12,7 → 12,30 |
//===================================================================== |
|
#include "fsf_contract.h" |
#include "fsf_server.h" |
#include <kernel/descr.h> |
#include <kernel/func.h> |
#include <pistar.h> |
|
struct hash_entry { |
mutex_t mx; |
fsf_shared_obj_id_t id; |
}; |
|
|
#define MAX_HASH_ENTRY FSF_MAX_SHARED_OPERATION |
struct hash_entry htable[MAX_HASH_ENTRY]; |
|
|
/*----------------------------------------------------------------------*/ |
/* hash_fun() : address hash table */ |
/*----------------------------------------------------------------------*/ |
static int hash_fun(fsf_shared_obj_id_t *id) |
{ |
return (*id % MAX_HASH_ENTRY); |
} |
|
|
int fsf_initialize_contract |
(fsf_contract_parameters_t *contract) |
{ |
189,6 → 212,7 |
|
} |
|
/* OLD VERSION |
int fsf_set_contract_synchronization_parameters |
(fsf_contract_parameters_t *contract, |
fsf_preemption_level_t preemption_level, |
204,6 → 228,7 |
return 0; |
|
} |
*/ |
|
int |
fsf_get_contract_synchronization_parameters |
250,5 → 275,113 |
|
} |
|
// mutex lock function |
|
int fsf_lock_object(fsf_shared_operation_t *op) { |
int index, oldindex; |
|
index=hash_fun(&op->obj_id); |
|
if (htable[index].id!=op->obj_id) { |
oldindex=index; |
index = (index + 1) % MAX_HASH_ENTRY; |
// find |
for (;htable[index].id != op->obj_id, index!=oldindex; (index++) % MAX_HASH_ENTRY); |
if (index==oldindex) return -1; |
} |
|
// we need a special implementation for mutex_lock ... additional parameter |
|
return PISTAR_lock(FSF_get_shared_object_level(), &htable[index].mx,TIMESPEC2USEC(&op->wcet) ); |
|
} |
|
int fsf_unlock_object(fsf_shared_operation_t *op) { |
|
int index, oldindex; |
|
index=hash_fun(&op->obj_id); |
|
if (htable[index].id!=op->obj_id) { |
oldindex=index; |
index = (index + 1) % MAX_HASH_ENTRY; |
// find |
for (;htable[index].id != op->obj_id, index!=oldindex; (index++) % MAX_HASH_ENTRY); |
if (index==oldindex) return -1; |
} |
return mutex_unlock(&htable[index].mx); |
|
|
|
} |
|
void fsf_init_shared_object(fsf_shared_object_t *obj, |
fsf_shared_obj_id_t id) { |
int index; |
int oldindex; |
PISTAR_mutexattr_t a; |
|
PISTAR_mutexattr_default(a); |
|
obj->size=0; |
index=hash_fun(&id); |
if (htable[index].id>=0) { |
oldindex=index; |
index = (index + 1) % MAX_HASH_ENTRY; |
// collision detection |
for (;htable[index].id >=0, index!=oldindex; (index++) % MAX_HASH_ENTRY); |
// table is full |
if (index==oldindex) return; |
} |
mutex_init(&(htable[index]).mx, &a); |
obj->obj_id=id; |
|
} |
|
|
// Declare an operation |
// This function is used to declare that a shared object has |
// a synchronized operation on it. |
// It checks if another operation with the same id has already been |
// declared; if so, return false (-1). |
// The obj_id field of the operation is set equal to the shared object id. |
// the structure op is copied in the first free element in the array |
// shared_op pof the structure obj. If there are no more free element, |
// returns -1. |
// Returns 0 if the operation has been completed, -1 otherwise. |
|
int fsf_declare_shared_object_operation(fsf_shared_object_t *obj, |
fsf_shared_operation_t *op) { |
int i; |
for (i=0; i<obj->size; i++) { |
// fail if the operation already declared |
if (op->op_id==obj->shared_op[i].op_id) |
return -1; |
} |
|
// fail if the object is full |
if (obj->size>(FSF_MAX_SHARED_OPERATION-1)) |
return -1; |
|
obj->size++; |
obj->shared_op[i].op_id=op->op_id; |
obj->shared_op[i].wcet=op->wcet; |
obj->shared_op[i].obj_id=obj->obj_id; |
op->obj_id=obj->obj_id; |
|
return 0; |
|
|
} |
|
int fsf_set_contract_synchronization_parameters( |
fsf_contract_parameters_t *contract, |
const fsf_shared_operation_t *shared_ops, |
size_t op_num) |
{ |
if (shared_ops && op_num < FSF_MAX_SHARED_OPERATION) |
memcpy(&contract->shared_operations,shared_ops,op_num); |
else return -1; |
|
return 0; |
} |