/******************************************************************************
Ricart and Agrawala's Resource Allocation algorithm
Description: $LYDIANROOT/Html/res_all_RA.html
Parameter:
- PARAM[0]: the number of processes allowed to enter the critical section
before the simulation ends.
- PARAM[1]: amount of time each process spends in the critical section
=> use TIMER1 to generate the corresponding event.
Network topology: complete graph.
*****************************************************************************/
#define MAX(A,B) ((A) > (B) ? (A) : (B))
typedef struct {
int clock; //local clock
int req_clock; //timestamp attached on its request messages
LIST ack_l; //the list of ACK being expected by me
LIST wait_l; //the list of sender waiting for ACK from me
} REGISTERS;
REGISTERS *REG;
int counter;
reg_alloc() {
REG = (REGISTERS*)malloc(processes*sizeof(REGISTERS));
}
init() {
int i;
for( i=0; i<processes; i++) {
REG[i].clock = 0;
REG[i].req_clock = 0;
init_list( REG[i].ack_l);
init_list( REG[i].wait_l);
}
}
start() {//Send requests to its all neighbours
int i;
MESSAGE *mess;
if( PCB[me].adjacents == 0) {
new_state = EATING;
//enter critical section
start_timer( TIMER1, PARAM[1]);
}
REG[me].clock ++;
REG[me].req_clock = REG[me].clock;
for( i=0; i<PCB[me].adjacents; i++) { //i: port
insert_list( i, REG[me].ack_l);
mess = create_message();
mess->kind = REQ;
mess->value[0] = REG[me].clock;
send_to( mess, i);
}
new_state = HUNGRY;
}
sleeping_req() {
MESSAGE *mess;
REG[me].clock = MAX( REG[me].clock, CURMESS->value[0]) + 1;
mess = create_message();
mess->kind = ACK;
send_to( mess, CURMESS->port);
}
hungry_req() {
MESSAGE *mess;
REG[me].clock = MAX( REG[me].clock, CURMESS->value[0]) + 1;
if( ( CURMESS->value[0] < REG[me].req_clock) ||
( (CURMESS->value[0] == REG[me].req_clock) && (CURMESS->from < me))) {
mess = create_message();
mess->kind = ACK;
send_to( mess, CURMESS->port);
}
else
insert_list( CURMESS->port, REG[me].wait_l);
}
eating_req() {
REG[me].clock = MAX( REG[me].clock, CURMESS->value[0]) + 1;
insert_list( CURMESS->port, REG[me].wait_l);
}
hungry_ack() {
delete_list( CURMESS->port, REG[me].ack_l);
if( empty_list( REG[me].ack_l) == TRUE) {
new_state = EATING;
//enter critical section
start_timer( TIMER1, PARAM[1]);
}
}
eating_timeout() {
int i;
MESSAGE *mess;
for( i=0; i<PCB[me].adjacents; i++)
if( in_list( i, REG[me].wait_l) == TRUE) {
delete_list( i, REG[me].wait_l);
mess = create_message();
mess->kind = ACK;
send_to( mess, i);
}
counter++;
if( counter < PARAM[0])
init_event( me);
else {
new_state = SLEEPING;
simul_end();
return;
}
}