int main(int argc, char *argv[]) { int i; if(argc != 2) { printf(2, "You must pass the number of soldiers\n"); exit(); } n = atoi(argv[1]); if(n < 1) { printf(2, "Number of soldiers must be positive\n"); exit(); } uthread_init(); for(i = 0; i < n; ++i) { binary_semaphore_init(&soldier_ready[i], 0); binary_semaphore_init(&soldier_waiting[i], 0); binary_semaphore_init(&soldier_prepared[i], 0); binary_semaphore_init(&soldier_update[i], 0); } for(i = 0; i < n; ++i) { uthread_create(run_soldier, (void*)i); } for(;;) { for(i = 0; i < n; ++i) { binary_semaphore_down(&soldier_ready[i]); } print_cells(); if(all_firing()) { exit(); } for(i = 0; i < n; ++i) { binary_semaphore_up(&soldier_waiting[i]); } for(i = 0; i < n; ++i) { binary_semaphore_down(&soldier_prepared[i]); } for(i = 0; i < n; ++i) { binary_semaphore_up(&soldier_update[i]); } } }
void up() { binary_semaphore_down(&departure); counter--; if(counter > 0) { binary_semaphore_up(&departure); } else { binary_semaphore_up(&printing); } }
void down() { binary_semaphore_down(&arrival); counter++; if(counter < soldiersAmount) { binary_semaphore_up(&arrival); } else { binary_semaphore_up(&departure); } }
//bartender simulation void* bartender(){ void* ret_val = 0; int tid = thread_getId(); double amount =0; double buf_size =0; for(;;){ struct Action* bartender_action = get_action(); if(bartender_action->action_type == DRINK_ORDER){ struct Cup* current_cup = get_clean_cup(); //need to write to file intsead of screen TODO printf(1,"Bartender %d is making drink with cup %d\n",tid,current_cup->id); serve_drink(current_cup); } else if(bartender_action->action_type == RETURN_CUP){ struct Cup* current_cup = bartender_action->cup; return_cup(current_cup); //need to write to file intsead of screen TODO printf(1,"Bartender %d returned cup %d\n",tid,current_cup->id); amount = DBB->full->value; buf_size = DBB->buffer_size; if(amount/buf_size >= 0.6){ printf(1,"Go Clean Boy %d\n"); binary_semaphore_up(cup_boy_lock); } if(bartender_action->action_type == GO_HOME){ free(bartender_action); thread_exit(ret_val); } } free(bartender_action); } return 0; }
void foo(void* sem) { int k; binary_semaphore_down((struct binary_semaphore*)sem); for (k=0; k<20; k++) { printf (1, "foo: tid: %d\n", uthread_self()); } binary_semaphore_up((struct binary_semaphore*)sem); }
void leave_bar() { semaphore_up(bouncer); left_counter++; if(entered_counter >= S && left_counter == entered_counter){ printf(1, "\n@@@@\n"); binary_semaphore_up(lk); semaphore_up(exit_lk); } }
void printArray() { int i=1; for(;i<=soldiersAmount;i++) { printf(1,"%c ",Symbols[currentState[state%2][i]]); } printf(1,"\n"); state++; binary_semaphore_up(&arrival); }
void run_soldier(void* data) { int i = (int)data; int next; // Set initial state: if (i == 0) { // The general cells[i] = R; } else { // Regular soldiers cells[i] = Q; } binary_semaphore_up(&soldier_ready[i]); while(cells[i] != F) { binary_semaphore_down(&soldier_waiting[i]); // Calculate the next state: next = next_state(i); // Sanity checking: if(next == X) { printf(2, "Error, invalid state transition!\n"); exit(); } binary_semaphore_up(&soldier_prepared[i]); binary_semaphore_down(&soldier_update[i]); cells[i] = next; binary_semaphore_up(&soldier_ready[i]); } }
int binary_semaphore_up(int s_id) { acquire(&list_lock); if(!is_legal_id(s_id) || !is_semaphore_init(s_id)) return -1; struct binary_semaphore *s = &bsemaphores[s_id]; acquire(&s->lock); void *p=0; if(deque(&s->waiting, &p)<0){ // no waiting procs //cprintf("[unlk %d %d]", proc->pid, s_id); s->value=1; release(&s->lock); release(&list_lock); return 0; } if(((struct proc*) p)->tid == proc->tid){ s->value=1; //cprintf("[self %d %d]", proc->pid, s_id); release(&s->lock); release(&list_lock); return binary_semaphore_up(s_id); } //release(&s->lock); s->value=0; //cprintf("[wake %d %d]", ((struct proc*) p)->pid, s_id); wakeup((struct proc*) p); release(&s->lock); release(&list_lock); return 0; }
int main(int argc, char** argv) { //variables int A; // number of slots to Actions that can be received int B; // number of bartenders int C; // number of cups int S; // number of students int M; // maximum number of students that can be at the bar at once int fconf; int conf_size; struct stat bufstat; fconf = open("con.conf",O_RDONLY); fstat(fconf,&bufstat); conf_size = bufstat.size; char bufconf[conf_size]; read(fconf,bufconf,conf_size); int inputs_parsed[5]; //{Aval, Bval, Cval, Sval, Mval} parse_buffer(bufconf, inputs_parsed); A = inputs_parsed[0]; B = inputs_parsed[1]; C = inputs_parsed[2]; S = inputs_parsed[3]; M = inputs_parsed[4]; printf(1,"A: %d B: %d C: %d S: %d M: %d\n",A,B,C,S,M); void* students_stacks[S]; void* bartenders_stacks[B]; void* cup_boy_stack; int i; int student_tids[S]; //int bartender_tids[B]; finished_shift = 0; // cup_boy changes it to 1 if all students left the bar and sends Action => GO_HOME to bartenders file_to_write = open("out.txt",(O_CREATE | O_WRONLY)); // if(file_to_write == -1){ printf(1,"There was an error opening out.txt\n"); exit(); } //Databases bouncer = semaphore_create(M); //this is the bouncer to the Beinstein ABB = BB_create(A); //this is a BB for student actions: drink, ans for a dring DrinkBB = BB_create(A); //this is a BB holding the drinks that are ready to be drinking CBB = BB_create(C); //this is a BB hold clean cups DBB = BB_create(C); //this is a BB hold dirty cups cup_boy_lock = binary_semaphore_create(0); // initial cup_boy with 0 so he goes to sleep imidietly on first call to down general_mutex = binary_semaphore_create(1); //initialize C clean cups struct Cup* cup_array[C]; for(i = 0; i < C; i++){ cup_array[i] = malloc(sizeof(struct Cup)); //TODO free cups //memset(cup_array[i],0,sizeof(void*)*STACK_SIZE); cup_array[i]->id = i; add_clean_cup(cup_array[i]); } //initialize cup_boy cup_boy_stack = (void*)malloc(sizeof(void*)*STACK_SIZE); memset(cup_boy_stack,0,sizeof(void*)*STACK_SIZE); if(thread_create((void*)cup_boy,cup_boy_stack,sizeof(void*)*STACK_SIZE) < 0){ printf(2,"Failed to create cupboy thread. Exiting...\n"); exit(); } //initialize B bartenders for(i = 0; i < B; i++){ bartenders_stacks[i] = (void*)malloc(sizeof(void*)*STACK_SIZE); memset(bartenders_stacks[i],0,sizeof(void*)*STACK_SIZE); thread_create((void*)bartender,bartenders_stacks[i],sizeof(void*)*STACK_SIZE);//TODO test //bartender_tids[i] = } //initialize S students for(i = 0; i < S; i++){//TODO test for fail students_stacks[i] = malloc(sizeof(void*)*STACK_SIZE); memset(students_stacks[i],0,sizeof(void*)*STACK_SIZE); student_tids[i] = thread_create((void*)student,students_stacks[i],sizeof(void*)*STACK_SIZE); } join_peoples(student_tids,S); //join students finished_shift = 1; //join_peoples(bartender_tids,B); //join bartenders sleep(2); // delay so exit will not come before threads finished TODO (need better soloution) if(finished_shift){ binary_semaphore_up(cup_boy_lock); } if(close(file_to_write) == -1){ printf(1,"There was an error closing out.txt\n"); exit(); } //free cup_boy_stack free(cup_boy_stack); //after all students have finished need to exit all bartenders and cup boy, and free all memory allocation //free cups for(i = 0; i < C; i++){ free(cup_array[i]); } //free bartenders_stacks for(i = 0; i < B; i++){ free(bartenders_stacks[i]); } //free students_stacks for(i = 0; i < S; i++){ free(students_stacks[i]); } semaphore_free(bouncer); BB_free(ABB); BB_free(DrinkBB); BB_free(CBB); BB_free(DBB); exit(); return 0; }