void semInit() { union semun arg; int semkey = getSemKey(); unsigned short initial_values[] = { 0, 0, 0 }; struct sembuf signal_shm = SEMOP(OP_SIGNAL, SHM_MUTEX); arg.array = initial_values; do { sem.id = semget(semkey, SEM_NUM, IPC_CREAT | IPC_EXCL | 0666); if (sem.id != -1) { /* Só entra aqui o que conseguiu criar os semáforos. */ printf("[INFO] Semáforos inicializados com chave 0x%x\n", semkey); semctl(sem.id, 0, SETALL, arg); semop(sem.id, &signal_shm, 1); break; } else sem.id = semget(semkey, SEM_NUM, 0666); } while ((sem.id == -1 && errno == ENOENT) || !waitFirstOp()); sem.nops = 0; }
int main(int argc, char** argv) { printf("bus %s started\n", argv[1]); fflush(stdout); int semid, shmid; struct Common* shared; semid = semget(getSemKey(), NUM_SEMS, 0777); shmid = shmget(getSemKey(), 0, 0); shared = (struct Common *)shmat(shmid, 0, 0); semwait(semid, SEM_GATE_EMPTY); printf("Bus %s has arrived\n", argv[1]); fflush(stdout); semsignal(semid, SEM_BUS_BOARDABLE); semwait(semid, SEM_MUTEX); time_t sleep_time = shared->departure_time - time(NULL); semsignal(semid, SEM_MUTEX); printf("Bus %s Sleeping until departure\n", argv[1]); fflush(stdout); sleep(sleep_time); semwait(semid, SEM_MUTEX); printf("Bus %s: last call for boarding\n", argv[1]); fflush(stdout); while(1) { semwait(semid, SEM_CAN_BOARD); if(shared->tickets_sold == shared->boarded) { semsignal(semid, SEM_CAN_BOARD); break; } semsignal(semid, SEM_CAN_BOARD); // wait another second to give customer // threads a chance to finish boarding sleep(1); } semwait(semid, SEM_BUS_BOARDABLE); // release passengers to the gate that were waiting for the next bus printf("Bus %s releasing next bus queue\n", argv[1]); fflush(stdout); int i; for(i=0; i<shared->next_bus_tickets; i++) { semsignal(semid, SEM_NEXT_BUS_QUEUE); } // reset the ticket variables for the next bus printf("Bus %s preparing shared variables for next bus\n", argv[1]); fflush(stdout); // if there were customers waiting for the next, next bus or beyond // release some of them for(i=0; i<shared->tickets_sold; i++) { semsignal(semid, SEM_MAX_CUSTOMERS); } shared->tickets_sold = shared->next_bus_tickets; shared->next_bus_tickets = 0; shared->departure_time += BUS_PERIOD; shared->boarded = 0; semsignal(semid, SEM_MUTEX); semsignal(semid, SEM_GATE_EMPTY); printf("Bus %s is departing\n", argv[1]); fflush(stdout); return 0; }