int release_cs(const void * self) { const cs_t* csdata = self; if(csdata->rick->state == EXEC_STATE) { timestamp_t tm = get_lamport_time(); for(int i=0; i<csdata->data->processes; i++) { if(csdata->rick->waitProcess[i] == 1) { Message msg; msg.s_header.s_type = CS_REPLY; msg.s_header.s_payload_len = 0; msg.s_header.s_local_time = tm; send(csdata->data, i, &msg); csdata->rick->waitProcess[i] = 0; } } csdata->rick->state = EMPTY_STATE; return 1; } else return 2; }
int main(int argc, char *argv[]) { int pid; dataIO_t data; int start_msgs, done_msgs; FILE *fd_pipes, *fd_events; if(argc < 2) usage(); int c; opterr=0; int mutexfl = 0; const char* short_options = "p:"; const struct option long_options[] = { {"mutexl", 0, &mutexfl, 1}, {NULL,0,NULL,0} }; while(1){ c = getopt_long(argc, argv, short_options, long_options, NULL); if (c == -1) break; switch (c) { case 0: break; case 'p': data.processes = atoi(optarg)+1; break; case '?': default: usage(); } } data.lid = 0; if ((fd_pipes = fopen(pipes_log, "w")) == NULL) { fprintf(stderr, "Error opening the file %s\n", pipes_log); exit(1); } for(int i = 0; i < data.processes; i++) { for(int j = 0; j < data.processes; j++) { if(j==i) { data.pipes[i][j].rdwr[0] = -1; data.pipes[i][j].rdwr[1] = -1; } else { if(pipe(data.pipes[i][j].rdwr) < 0) { fprintf(stderr, "Error creating the pipe\n"); exit(1); } int mode; mode = fcntl(data.pipes[i][j].rdwr[0], F_GETFL); fcntl(data.pipes[i][j].rdwr[0], F_SETFL, mode | O_NONBLOCK); mode = fcntl(data.pipes[i][j].rdwr[1], F_GETFL); fcntl(data.pipes[i][j].rdwr[1], F_SETFL, mode | O_NONBLOCK); fprintf(fd_pipes, "The pipe %d ===> %d was created\n", j, i); } } } fclose(fd_pipes); Message msg, resMsg; msg.s_header.s_magic = MESSAGE_MAGIC; msg.s_header.s_local_time = 0; if ((fd_events = fopen(events_log, "a")) == NULL) { fprintf(stderr, "Error opening the file %s\n", events_log); exit(1); } for(int i = 1; i < data.processes; i++) { pid = fork(); if(pid < 0) { fprintf(stderr, "Error creating the child\n"); exit(1); } else if (pid == 0) { doChild(&data, fd_events, i, 0, mutexfl); exit(0); } } closeUnusedPipes(&data); timestamp_t tm = get_lamport_time(); start_msgs = data.processes - 1; done_msgs = data.processes - 1; while(start_msgs) { if(receive_any(&data, &resMsg) > -1) { if(resMsg.s_header.s_type == STARTED) { start_msgs--; lamportStamp = max(lamportStamp, resMsg.s_header.s_local_time); tm = get_lamport_time(); } if(resMsg.s_header.s_type == DONE) { done_msgs--; lamportStamp = max(lamportStamp, resMsg.s_header.s_local_time); tm = get_lamport_time(); } } } fprintf(fd_events, log_received_all_started_fmt, tm, data.lid); fflush(fd_events); printf(log_received_all_started_fmt, tm, data.lid); while(done_msgs) { if(receive_any(&data, &resMsg) > -1) { if(resMsg.s_header.s_type == DONE){ done_msgs--; lamportStamp = max(lamportStamp, resMsg.s_header.s_local_time); tm = get_lamport_time(); } } } fprintf(fd_events, log_received_all_done_fmt, tm, data.lid); fflush(fd_events); printf(log_received_all_done_fmt, tm, data.lid); fclose(fd_events); for(int i = 0; i < data.processes; i++) { wait(&i); } return 0; }
void doChild(void *parentData, FILE *fd_events, int lid, int initBalance, int mutexfl) { Message msg, resMsg; dataIO_t* data = parentData; rick_t rkdata = { EMPTY_STATE, 0, {0} }; cs_t csdata = { data, &rkdata }; int start_msgs = data->processes - 2; int done_msgs = data->processes - 2; timestamp_t tm = lamportStamp; data->lid = lid; closeUnusedPipes(data); balance_t childBalance = initBalance; fprintf(fd_events, log_started_fmt, tm, data->lid, getpid(), getppid(), childBalance); fflush(fd_events); printf(log_started_fmt, tm, data->lid, getpid(), getppid(),childBalance); tm = get_lamport_time(); msg.s_header.s_type = STARTED; msg.s_header.s_magic = MESSAGE_MAGIC; sprintf(msg.s_payload, log_started_fmt, tm, data->lid, getpid(), getppid(), childBalance); msg.s_header.s_payload_len = strlen(msg.s_payload); msg.s_header.s_local_time = tm; send_multicast(data, &msg); while(start_msgs) { if(receive_any(data, &resMsg) > -1) { if(resMsg.s_header.s_type == STARTED) start_msgs--; if(resMsg.s_header.s_type == DONE) done_msgs--; } } fprintf(fd_events, log_received_all_started_fmt, tm, data->lid); fflush(fd_events); printf(log_received_all_started_fmt, tm, data->lid); int replyCounter = 0; int printIterator = 0; int printMax = data->lid * 5; while(done_msgs || printIterator < printMax) { int rPid = receive_any(data, &resMsg); if(rPid > -1) { if(resMsg.s_header.s_type == DONE) { lamportStamp = max(lamportStamp, resMsg.s_header.s_local_time); tm = get_lamport_time(); done_msgs--; } if(resMsg.s_header.s_type == CS_REQUEST) { lamportStamp = max(lamportStamp, resMsg.s_header.s_local_time); tm = get_lamport_time(); if(csdata.rick->state == EMPTY_STATE || (csdata.rick->state == WAIT_STATE && (csdata.rick->requestTime >= resMsg.s_header.s_local_time && rPid < data->lid))) { tm = get_lamport_time(); msg.s_header.s_type = CS_REPLY; msg.s_header.s_payload_len = 0; msg.s_header.s_local_time = tm; send(data, rPid, &msg); } else { csdata.rick->waitProcess[rPid] = 1; } } if(resMsg.s_header.s_type == CS_REPLY) { lamportStamp = max(lamportStamp, resMsg.s_header.s_local_time); tm = get_lamport_time(); replyCounter ++; } } if(mutexfl == 1){ if(printIterator < printMax) request_cs(&csdata); if(replyCounter == data->processes - 2) { csdata.rick->state = EXEC_STATE; char str[MAX_PAYLOAD_LEN]; sprintf(str, log_loop_operation_fmt, data->lid, printIterator+1, printMax); print(str); printIterator++; release_cs(&csdata); replyCounter = 0; } } else { if(printIterator < printMax) { char str[MAX_PAYLOAD_LEN]; sprintf(str, log_loop_operation_fmt, data->lid, printIterator+1, printMax); print(str); printIterator++; } } if(printIterator == printMax) { fprintf(fd_events, log_done_fmt, tm, data->lid, childBalance); fflush(fd_events); printf(log_done_fmt, tm, data->lid, childBalance); msg.s_header.s_type = DONE; sprintf(msg.s_payload, log_done_fmt, tm, data->lid, childBalance); msg.s_header.s_payload_len = strlen(msg.s_payload); send_multicast(data, &msg); printIterator ++; } } fprintf(fd_events, log_received_all_done_fmt, tm, data->lid); fflush(fd_events); printf(log_received_all_done_fmt, tm, data->lid); fclose(fd_events); exit(0); }
int request_cs(const void *self){ IO *inout = (IO*)self; process processDst, processSrc; // update localTime lamport_before_send(); // fill the CS_REQUEST message Message *msg = (Message*)malloc(sizeof(Message)); Message *msgReceive = (Message*)malloc(sizeof(Message)); msg -> s_header.s_magic = MESSAGE_MAGIC; msg -> s_header.s_payload_len = 0; msg -> s_header.s_type = CS_REQUEST; msg -> s_header.s_local_time = get_lamport_time(); processDst.local_time = get_lamport_time(); processDst.id = inout -> id; // send CS_REQUEST message to other processes send_multicast(inout, msg); int receiveCount = 0; int doneCount = 0; while(1){ if (inout -> numOfChildren == 1) break; int src; //fprintf(stderr, "11111111111111111111111111\n"); while ((src = receive_any(inout, msgReceive)) < 0) usleep(1000); //fprintf(stderr, "22222222222222222222222222\n"); // update localTime lamport_after_receive(&msgReceive -> s_header); switch(msgReceive -> s_header.s_type){ // wait for all CS_REPLY case CS_REPLY: if (receiveCount + 1 < inout -> numOfChildren) receiveCount++; break; // compare if CS_REQUEST case CS_REQUEST: processSrc.local_time = msgReceive -> s_header.s_local_time; processSrc.id = src; if (compare(&processDst, &processSrc) == 1) DR[src - 1] = 1; // wait if CS_REQUEST not first else { //printf("I HERE, count:%d\n", src); lamport_before_send(); msg -> s_header.s_type = CS_REPLY; msg -> s_header.s_local_time = get_lamport_time(); //fprintf(stderr, "sending CS_REPLY proc %d mess_type %d\n", inout->id, CS_REPLY); send(inout, src, msg); } break; case DONE: doneCount++; break; } // block process if receive all CS_REPLY if (receiveCount + 1 == inout -> numOfChildren) break; } return doneCount; }
int main(int argc, char *argv[]){ // create an IO structure IO *inout = (IO*)malloc(sizeof(IO)); // number of child processes from command line to numOfChildren variable int opt; while ( (opt = getopt(argc,argv,"p:")) != -1){ switch (opt){ case 'p': inout -> numOfChildren = atoi(optarg); break; default: free(inout); return -1; } } inout -> id = PARENT_ID; // create or open logs for writing FILE *pipesLog = fopen(pipes_log, "w+"); FILE *eventsLog = fopen(events_log, "w+"); // create pipes and fill the inout.pipes for (int i = 0; i < inout -> numOfChildren + 1; i++){ for (int j = 0; j < inout -> numOfChildren + 1; j++){ if (i != j){ Pipe *pipeMem = (Pipe*)malloc(sizeof(Pipe)); int pipefd[2]; pipe(pipefd); fcntl(pipefd[0], F_SETFL, O_NONBLOCK); fcntl(pipefd[1], F_SETFL, O_NONBLOCK); pipeMem -> in = pipefd[0]; pipeMem -> out = pipefd[1]; inout -> pipes[i][j] = pipeMem; fprintf(pipesLog, log_opened_fmt, pipefd[0], pipefd[1]); fflush(pipesLog); printf(log_opened_fmt, pipefd[0], pipefd[1]); } } } Message *msgReceive = (Message*)malloc(sizeof(Message)); BalanceHistory *balanceHistory = (BalanceHistory*)malloc(sizeof(BalanceHistory)); AllHistory *allHistory = (AllHistory*)malloc(sizeof(AllHistory)); // create children for (int id = 1; id < inout -> numOfChildren + 1; id++){ switch(fork()){ case -1: perror("fork"); exit(EXIT_FAILURE); case 0: lamport_process_init(); fprintf(eventsLog, log_started_fmt, get_lamport_time(), id, getpid(), getppid(), atoi(argv[optind+id-1])); fflush(eventsLog); printf(log_started_fmt, get_lamport_time(), id, getpid(), getppid(), atoi(argv[optind+id-1])); timestamp_t after; balanceHistory -> s_id = id; balanceHistory -> s_history_len = 1; balanceHistory -> s_history[0].s_balance = atoi(argv[optind+id-1]); balanceHistory -> s_history[0].s_time = get_lamport_time(); balanceHistory -> s_history[0].s_balance_pending_in = 0; inout -> id = id; // close unused pipes for (int i = 0; i < inout -> numOfChildren + 1; i++){ for (int j = 0; j < inout -> numOfChildren + 1; j++){ if (i != j){ if (i != inout -> id && j != inout -> id){ close(inout -> pipes[i][j] -> in); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); close(inout -> pipes[i][j] -> out); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); } if (i == inout -> id){ close(inout -> pipes[i][j] -> in); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); } if (j == inout -> id){ close(inout -> pipes[i][j] -> out); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); } } } } // update localTime lamport_before_send(); // fill the STARTED message Message *msg = (Message*)malloc(sizeof(Message)); sprintf(msg -> s_payload, log_started_fmt, get_lamport_time(), id, getpid(), getppid(), balanceHistory -> s_history[balanceHistory -> s_history_len].s_balance); msg -> s_header.s_magic = MESSAGE_MAGIC; msg -> s_header.s_payload_len = strlen(msg -> s_payload)+1; msg -> s_header.s_type = STARTED; msg -> s_header.s_local_time = get_lamport_time(); // send STARTED message to other processes send_multicast(inout, msg); // receive STARTED message from other processes for (int i = 1; i < inout -> numOfChildren + 1; i++){ if (i != inout -> id){ do{ while (receive(inout, i, msgReceive) == -1) usleep(1000); // update localTime lamport_after_receive(&msgReceive -> s_header); } while (msgReceive -> s_header.s_type != STARTED); } } // logs fprintf(eventsLog, log_received_all_started_fmt, get_lamport_time(), inout -> id); fflush(eventsLog); printf(log_received_all_started_fmt, get_lamport_time(), inout -> id); // useful work while(1){ int src = receive_any(inout, msgReceive); // update localTime lamport_after_receive(&msgReceive -> s_header); if (msgReceive -> s_header.s_type==STOP) break; printf("%d RECEIVE FROM %d TYPE %d\n", inout ->id, src, msgReceive -> s_header.s_type); TransferOrder *transferOrder; switch(msgReceive -> s_header.s_type){ case TRANSFER: transferOrder = (TransferOrder*)msgReceive -> s_payload; if (src == 0){ after = get_lamport_time()+1; for (int i = balanceHistory -> s_history_len; i <= after; i++){ balanceHistory -> s_history[i] = balanceHistory -> s_history[i-1]; balanceHistory -> s_history[i].s_time = balanceHistory -> s_history[i-1].s_time+1; balanceHistory -> s_history[i].s_balance_pending_in = 0; balanceHistory -> s_history_len ++; } balanceHistory -> s_history[after].s_balance -= transferOrder -> s_amount; balanceHistory -> s_history[after].s_balance_pending_in = transferOrder -> s_amount; // update localTime lamport_before_send(); msgReceive -> s_header.s_local_time = get_lamport_time(); send(inout, transferOrder -> s_dst, msgReceive); fprintf(eventsLog, log_transfer_out_fmt, get_lamport_time(), inout -> id, transferOrder -> s_amount, transferOrder -> s_dst); fflush(eventsLog); printf(log_transfer_out_fmt, get_lamport_time(), inout -> id, transferOrder -> s_amount, transferOrder -> s_dst); } if (src > 0){ after = get_lamport_time(); for (int i = balanceHistory -> s_history_len; i<=after; i++){ balanceHistory -> s_history[i] = balanceHistory -> s_history[i-1]; balanceHistory -> s_history[i].s_time=balanceHistory -> s_history[i-1].s_time+1; balanceHistory -> s_history[i].s_balance_pending_in = 0; balanceHistory -> s_history_len ++; } balanceHistory -> s_history[after].s_balance += transferOrder -> s_amount; balanceHistory -> s_history[after].s_balance_pending_in = 0; // update localTime lamport_before_send(); msg -> s_header.s_magic = MESSAGE_MAGIC; msg -> s_header.s_payload_len = 0; msg -> s_header.s_type = ACK; msg -> s_header.s_local_time = get_lamport_time(); send(inout, PARENT_ID, msg); fprintf(eventsLog, log_transfer_in_fmt, get_lamport_time(), inout -> id, transferOrder -> s_amount, transferOrder -> s_dst); fflush(eventsLog); printf(log_transfer_in_fmt, get_lamport_time(), inout -> id, transferOrder -> s_amount, transferOrder -> s_src); } } } // update localTime lamport_before_send(); // fill the DONE message sprintf(msg -> s_payload, log_done_fmt, get_lamport_time(), inout -> id, balanceHistory -> s_history[balanceHistory -> s_history_len-1].s_balance); msg -> s_header.s_magic = MESSAGE_MAGIC; msg -> s_header.s_payload_len = strlen(msg -> s_payload)+1; msg -> s_header.s_type = DONE; msg -> s_header.s_local_time = get_lamport_time(); // send DONE message to other processes send_multicast(inout, msg); // receive DONE message from other processes for (int i = 1; i < inout -> numOfChildren + 1; i++){ if (i != inout -> id){ do{ while (receive(inout, i, msgReceive) == -1) usleep(1000); // update localTime lamport_after_receive(&msgReceive -> s_header); } while (msgReceive -> s_header.s_type != DONE); } } // logs fprintf(eventsLog, log_received_all_done_fmt, get_lamport_time(), inout -> id); fflush(eventsLog); printf(log_received_all_done_fmt, get_lamport_time(), inout -> id); // update localTime lamport_before_send(); // fill the BALANCE_HISTORY message msg -> s_header.s_magic = MESSAGE_MAGIC; msg -> s_header.s_payload_len = sizeof(BalanceHistory); msg -> s_header.s_type = BALANCE_HISTORY; msg -> s_header.s_local_time = get_lamport_time(); if (msg -> s_header.s_local_time > after){ for (int i = balanceHistory -> s_history_len; i<=msg -> s_header.s_local_time; i++){ balanceHistory -> s_history[i] = balanceHistory -> s_history[i-1]; balanceHistory -> s_history[i].s_time=balanceHistory -> s_history[i-1].s_time+1; balanceHistory -> s_history[i].s_balance_pending_in = 0; balanceHistory -> s_history_len ++; } } memcpy(msg -> s_payload, balanceHistory, msg -> s_header.s_payload_len); // send the BALANCE_HISTORY to each child send(inout, PARENT_ID, msg); // close all other pipes for (int i = 0; i < inout -> numOfChildren + 1; i++){ for (int j = 0; j < inout -> numOfChildren + 1; j++){ if (i != j){ if (i == inout -> id){ close(inout -> pipes[i][j] -> out); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); } if (j == inout -> id){ close(inout -> pipes[i][j] -> in); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); } } } } for (int i = 0; i < inout -> numOfChildren + 1; i++){ for (int j = 0; j < inout -> numOfChildren + 1; j++){ if (i != j) free(inout -> pipes[i][j]); } } free(msg); fprintf(eventsLog, log_done_fmt, get_lamport_time(), inout -> id, balanceHistory -> s_history[balanceHistory -> s_history_len-1].s_balance); fflush(eventsLog); printf(log_done_fmt, get_lamport_time(), inout -> id, balanceHistory ->s_history[balanceHistory -> s_history_len-1].s_balance); return 0; default: break; } } for (int i = 0; i < inout -> numOfChildren + 1; i++){ for (int j = 0; j < inout -> numOfChildren + 1; j++){ if (i != j){ if (i != PARENT_ID && j != PARENT_ID){ close(inout -> pipes[i][j] -> in); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); close(inout -> pipes[i][j] -> out); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); } if (i == PARENT_ID){ close(inout -> pipes[i][j] -> in); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); } if (j == PARENT_ID){ close(inout -> pipes[i][j] -> out); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); } } } } for (int i = 1; i < inout -> numOfChildren + 1; i++){ if (i != inout -> id){ do{ while (receive(inout, i, msgReceive) == -1) usleep(1000); // update localTime lamport_after_receive(&msgReceive -> s_header); } while (msgReceive -> s_header.s_type != STARTED); } } fprintf(eventsLog, log_received_all_started_fmt, get_lamport_time(), inout -> id); fflush(eventsLog); printf(log_received_all_started_fmt, get_lamport_time(), inout -> id); // for pa2 bank_robbery(inout, inout -> numOfChildren); Message *msg = (Message*)malloc(sizeof(Message)); // update localTime lamport_before_send(); // fill the STOP message msg -> s_header.s_magic = MESSAGE_MAGIC; msg -> s_header.s_payload_len = 0; msg -> s_header.s_type = STOP; msg -> s_header.s_local_time = get_lamport_time(); // send the STOP to each child send_multicast(inout, msg); // receive all DONE messages for (int i = 1; i < inout -> numOfChildren + 1; i++){ do{ while (receive(inout, i, msgReceive) == -1) usleep(1000); // update localTime lamport_after_receive(&msgReceive -> s_header); } while (msgReceive -> s_header.s_type != DONE); } //logs fprintf(eventsLog, log_received_all_done_fmt, get_lamport_time(), inout -> id); fflush(eventsLog); printf(log_received_all_done_fmt, get_lamport_time(), inout -> id); // receive all BALANCE_HISTORY messages and fill AllHistory allHistory -> s_history_len = inout -> numOfChildren; for (int i = 1; i < inout -> numOfChildren + 1; i++){ do{ while (receive(inout, i, msgReceive) == -1) usleep(1000); // update localTime lamport_after_receive(&msgReceive -> s_header); } while (msgReceive -> s_header.s_type != BALANCE_HISTORY); memcpy(&allHistory -> s_history[i-1], msgReceive -> s_payload, sizeof(BalanceHistory)); } for (int i = 0; i < inout -> numOfChildren + 1; i++){ for (int j = 0; j < inout -> numOfChildren + 1; j++){ if (i != j){ if (i == PARENT_ID){ close(inout -> pipes[i][j] -> out); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> out, inout -> id); } if (j == PARENT_ID){ close(inout -> pipes[i][j] -> in); fprintf(pipesLog, log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); fflush(pipesLog); printf(log_closed_fmt, inout -> pipes[i][j] -> in, inout -> id); } } } } for (int i = 0; i < inout -> numOfChildren; i++) wait(NULL); for (int i = 0; i< inout -> numOfChildren; i++){ for (int j = 0; j<=allHistory -> s_history[i].s_history_len; j++){ printf("N: %d process: %d balance: %d time: %d\n", j, allHistory -> s_history[i].s_id, allHistory -> s_history[i].s_history[j].s_balance, allHistory -> s_history[i].s_history[j].s_time); } } print_history(allHistory); free(inout); free(msg); free(msgReceive); free(balanceHistory); free(allHistory); fclose(pipesLog); fclose(eventsLog); return 0; }
int request_cs(const void * self) { if (done_count == 0) { inc_lamport_time(); return 0; } Message * msg = (Message *) calloc(1, sizeof(Message)); memset(msg, 0, sizeof(Message)); inc_lamport_time(); init_message(msg, NULL, CS_REQUEST); queue_push(my_local_id, get_lamport_time()); for (local_id id_from = 1; id_from <= num_proc; id_from++) { if (id_from != my_local_id) { send(NULL, id_from, msg); } } local_id from; int count_reply = num_proc - 2; while (1) { memset(msg, 0, sizeof(Message)); receive_any(&from, msg); // printf("%d: type message %d\n", my_local_id, msg->s_header.s_type); switch (msg->s_header.s_type) { case CS_REPLY: { count_reply--; // printf("%d: reply head - %d\n", my_local_id, get_head()); if (count_reply <= 0 && get_head() == my_local_id) { return 0; } break; } case CS_REQUEST: { // printf("%d: request\n", my_local_id); queue_push(from, msg->s_header.s_local_time); memset(msg, 0, sizeof(Message)); inc_lamport_time(); init_message(msg, NULL, CS_REPLY); send(NULL, from, msg); break; } case CS_RELEASE: { // printf("%d: release\n", my_local_id); next_proc(); if (get_head() == my_local_id) { return 0; } break; } case DONE: { done_count--; if (done_count <= 0) { return 0; } break; } default: fprintf(stderr, "unknown type message: %d\n", msg->s_header.s_type); } } free(msg); return 0; }