void childProcess( Process* proc ) { closeUnusedPipes( proc ); // STARTED proc -> started += 1; incLamportTime(); Message startedMsg; fillMessage( &startedMsg, proc, STARTED ); makeIPCLog( startedMsg.s_payload ); send_multicast( proc, &startedMsg ); // Receive STARTED while( proc -> started != proc -> total ) { defaultCSExtendedCycle( proc ); } sprintf( LogBuf, log_received_all_started_fmt, get_lamport_time(), proc -> localId ); makeIPCLog( LogBuf ); // Payload int totalIterations = proc -> localId * 5; for( int i = 1; i <= totalIterations; i ++ ) { sprintf( LogBuf, log_loop_operation_fmt, proc -> localId, i, totalIterations ); if( proc -> isMutex ) request_cs( proc ); print( LogBuf ); if( proc -> isMutex ) release_cs( proc ); } // DONE proc -> done += 1; incLamportTime(); Message doneMsg; fillMessage( &doneMsg, proc, DONE ); makeIPCLog( doneMsg.s_payload ); send_multicast( proc, &doneMsg ); // Receive DONE while( proc -> done != proc -> total ) { defaultCSExtendedCycle( proc ); } sprintf( LogBuf, log_received_all_done_fmt, get_lamport_time(), proc -> localId ); makeIPCLog( LogBuf ); closeTheOtherPipes( proc ); }
int release_cs( const void* self ) { const Process* proc = self; pop( proc -> list ); // CS_RELEASE incLamportTime(); Message releaseMsg; fillMessage( &releaseMsg, proc, CS_RELEASE ); send_multicast( ( void* ) proc, &releaseMsg ); return 0; }
int request_cs( const void* self ) { Process* proc = ( Process* ) self; // CS_REQUEST incLamportTime(); Message requestMsg; fillMessage( &requestMsg, proc, CS_REQUEST ); send_multicast( ( void* ) proc, &requestMsg ); Request request = { get_lamport_time(), proc -> localId }; insert( proc -> list, request ); proc -> replied = 1; while( proc -> replied != proc -> total || !isFirst( proc -> list, proc -> localId ) ) { defaultCSExtendedCycle( proc ); } return 0; }
int request_cs(const void * self) { const cs_t* csdata = self; if(csdata->rick->state == EMPTY_STATE) { Message msg; timestamp_t tm = get_lamport_time(); msg.s_header.s_type = CS_REQUEST; msg.s_header.s_payload_len = 0; msg.s_header.s_local_time = tm; send_multicast(csdata->data, &msg); csdata->rick->state = WAIT_STATE; csdata->rick->requestTime = tm; return 1; } else return 2; }
int ACE_TMAIN (int, ACE_TCHAR *[]) { ACE_INET_Addr nop; send_multicast (nop); 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; }