void agent_fun(void *aux){ int i=0; while(i<5){ sema_down(&agent); long num=random_ulong()%3; if (tobaco_match==num) { sema_up(&smoker1); }else if(match_paper==num){ sema_up(&smoker2); }else if(paper_tobaco){ sema_up(&smoker3); } i++; } }
void do_grad(int* studentsInRoom, sema gradAllowedMutex, int* gradsEaten, sema roomTypeMutex, enum studentType* currentStudentType) { while (1) { sema_down(gradAllowedMutex); sema_down(roomTypeMutex); if (*currentStudentType != ugrad && *studentsInRoom < 2) { (*studentsInRoom) += 1; *currentStudentType = grad; sema_up(roomTypeMutex); (*gradsEaten) += 1; // 6 grads have eaten, lock out more grads until ugrads get a turn if (*gradsEaten == NUM_GRADS) { sema_down(gradAllowedMutex); } printf("grad eating...\n"); sleep(randint()); printf(" grad done\n"); sema_down(roomTypeMutex); (*studentsInRoom) -= 1; if (*studentsInRoom == 0) { *currentStudentType = empty; } sema_up(roomTypeMutex); } else { sema_up(roomTypeMutex); } } }
void ArriveBridge(int direc,int prio) { sema_down(&mutex); if(prio == 1)total_urgent_waiting++; while(true) { if((bridge_direction == direc || bridge.value == 3) && (total_urgent_waiting == 0 || prio == 1)) { sema_down(&bridge); bridge_direction = direc; if(prio == 1)total_urgent_waiting--; //sema_down(&inform); printf("%s %d %s %d\n","MOVING ON Origin =",direc,"Priority =",prio); //sema_up(&inform); sema_up(&mutex); break; } else { //sema_down(&inform); printf("%s %d %s %d\n","CAN NOT PROCEED Origin =",direc,"Priority =",prio); //sema_up(&inform); } sema_up(&mutex); thread_yield(); sema_down(&mutex); } }
void smoker1_fun(void *aux){ while(1){ sema_down(&smoker1); printf("I AM SMOKER 1\n"); sema_up(&agent); } }
void sys_exit (int status) { struct thread *t = thread_current(); int fd; t->exit_code = status; t->end = true; for (fd=0; fd < t->fd_num; fd++){ // close all open fd if (t->fd_list[fd] != NULL){ file_close(t->fd_list[fd]); t->fd_list[fd] = 0; } } printf("%s: exit(%d)\n", t->process_name, status); sema_up (&t->wait_this); //unblock parent sema_down (&t->kill_this); //kill_this will up when parent get exit_code succefully file_allow_write (t->open_file); file_close (t->open_file); thread_exit(); }
void test_priority_sema (void) { int i; /* This test does not work with the MLFQS. */ ASSERT (!thread_mlfqs); sema_init (&sema, 0); thread_set_priority (PRI_MIN); for (i = 0; i < 10; i++) { int priority = PRI_DEFAULT - (i + 3) % 10 - 1; char name[16]; snprintf (name, sizeof name, "priority %d", priority); thread_create (name, priority, priority_sema_thread, NULL); } for (i = 0; i < 10; i++) { sema_up (&sema); msg ("Back in main thread."); } }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); enum intr_level old_state = intr_disable(); // Remove all donors that hold this lock if (!list_empty(&thread_current()->donorList)) { struct list_elem *e, *tmp; for (e = list_begin(&thread_current()->donorList); e != list_end(&thread_current()->donorList); e = tmp) { struct thread *t = list_entry(e, struct thread, donorElem); tmp = list_next(e); if (t->tLock == lock) list_remove(e); } } intr_set_level(old_state); lock->holder = NULL; sema_up (&lock->semaphore); //intr_set_level(old_state); }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); enum intr_level old_level = intr_disable (); lock->holder = NULL; /* If we're using the priority scheduler, loop through all threads that were waiting on this lock and notify them to remove their priority donations. */ if (!thread_mlfqs) { struct list_elem *e; for (e = list_begin (&lock->semaphore.waiters); e != list_end (&lock->semaphore.waiters); e = list_next (e)) { struct thread *t = list_entry (e, struct thread, elem); thread_recall_donation (t); } /* Recompute my effective priority, since I may have just lost some donations. */ thread_calculate_priority (thread_current ()); } lock->holder = NULL; /* NOTE : It's possible that we will be preempted by sema_up. */ sema_up (&lock->semaphore); intr_set_level (old_level); }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { bool yield = false; ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); enum intr_level old_level = intr_disable (); if (!thread_mlfqs && thread_current ()->is_a_donee) { thread_reverse_priority_donation (lock); yield = true; } lock->holder = NULL; sema_up (&lock->semaphore); intr_set_level (old_level); if (yield) thread_yield (); }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { int64_t start = timer_ticks (); ASSERT (intr_get_level () == INTR_ON); enum intr_level old_level; struct wait_sema current_thread; sema_init (¤t_thread.sleep_sema,0); sema_down (&sema_calc_tick); current_thread.wakeup_tick = start+ticks; sema_up (&sema_calc_tick); old_level = intr_disable(); list_insert_ordered (&wait_sema_list,¤t_thread.elem,wakeup_order,NULL); intr_set_level (old_level); sema_down (¤t_thread.sleep_sema); /*Old Code*/ // while (timer_elapsed (start) < ticks) // thread_yield (); }
void syscall_exit(int status){ /* Terminates the current user program, returning status to the kernel. * * If the process's parent waits for it, this is the status that * will be returnd. * * Conventionally, a status of 0 indicates success and nonzero values * indicate errors. (ref:man29-30) */ struct thread *t = thread_current (); char *wanted, *last; wanted = strtok_r(t->name, " ", &last); printf("%s: exit(%d)\n", wanted, status); // XXX : Delete All unremoved FPs. struct list_elem *e; for (e = list_begin(&(t->FDs)); e != list_end(&(t->FDs)); /* XXX inside. */){ struct fd_list *now = list_entry(e, struct fd_list, elem); e = list_next(e); // printf("%s(%d) NOW FD_list %d\n", __func__, __LINE__, now->fd); close_fd_list(now); } // XXX : Delete Child from Parent. struct thread *parent = t->parent; // XXX : Wait until parent waiting child. while(!( (t->parent->status == THREAD_BLOCKED) && (t->parent->waiting_tid == t->tid) )){ thread_yield(); } // SEARCH It; for (e = list_begin(&(parent->childs)); e != list_end(&(parent->childs)); /* */){ //printf("list anything out: %p\n", (void *)e); struct child_list *now = list_entry(e, struct child_list, elem); e = list_next(e); if(now->tid == t->tid) // Unlink Child from Parent; if(&(now->elem)){ //free(list_remove(e)); list_remove(&(now->elem)); free(now); break; } } // XXX : Store return status to parent. t->parent->waited_child_return_value = status; // XXX : Wakeup Parent. //printf("[%s/%s]SEMAUP? %d\n", t->parent->name, t->name, t->parent->sema.value); sema_up(&(t->parent->sema)); //printf("[%s/%s]SEMAUP! %d\n", t->parent->name, t->name, t->parent->sema.value); // XXX thread_exit(); return ; }
void syscall_exit(int value) { struct exit_struct *ec = thread_current()->exit_controler; printf("%s: exit(%d)\n", thread_name(), value); ec->value = value; sema_up(&ec->parent); thread_exit(); }
void thread_cleanup_and_exit (int status) { printf ("%s: exit(%d)\n", thread_name (), status); /* close all open file descriptors */ struct thread *t = thread_current (); struct list_elem *e; /* close all the files opened and free spaces allocated for the file list */ while (!list_empty (&t->file_list)) { e = list_pop_back (&t->file_list); struct file_elem *f_elem = list_entry (e, struct file_elem, elem); file_close (f_elem->file); free (f_elem); } /* free waited_children_list and children_list */ while (!list_empty (&t->children_list)) { e = list_pop_back (&t->children_list); struct child_elem *c_elem = list_entry (e, struct child_elem, elem); // free children from the global exit_list free_thread_from_exit_list (c_elem->pid); free (c_elem); } while (!list_empty (&t->waited_children_list)) { e = list_pop_back (&t->waited_children_list); struct wait_child_elem *w_elem = list_entry (e, struct wait_child_elem, elem); free (w_elem); } add_thread_to_exited_list (t->tid, status); /* allow file write to executable */ if (t->exec_file) { file_allow_write (t->exec_file); file_close (t->exec_file); } /* release all the locks that have not already been released */ while (!list_empty (&t->acquired_locks)) { struct list_elem *e = list_front (&t->acquired_locks); struct lock *l = list_entry (e, struct lock, elem); lock_release (l); } /* wake parent up if its waiting on it */ struct thread *parent = get_thread (thread_current ()->parent_id); if (parent) { sema_up (&parent->waiting_on_child_exit_sema); } thread_exit (); }
/*! Thread function used by sema_self_test(). */ static void sema_test_helper(void *sema_) { struct semaphore *sema = sema_; int i; for (i = 0; i < 10; i++) { sema_down(&sema[0]); sema_up(&sema[1]); } }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); lock->holder = NULL; sema_up (&lock->semaphore); }
void sysexit(int status) { // Print Process Termination Message // File Name char* name = thread_current()->name; char* token, *save_ptr; token = strtok_r(name, " ", &save_ptr); putbuf (token, strlen(token)); char* str1 = ": exit("; putbuf (str1, strlen(str1)); // ExitStatus char strstatus[32]; snprintf(strstatus, 32, "%d", status); putbuf (strstatus, strlen(strstatus)); char* str2 = ")\n"; putbuf (str2, strlen(str2)); // EXIT Child Processes if(thread_current()->numchild > 0) { struct list_elem * e; while (!list_empty(&thread_current()->child_list)) { e = list_pop_front(&thread_current()->child_list); struct childproc * childitem = list_entry (e, struct childproc, elem); if(!exit_remove(childitem->childid)) { list_push_back(&ignore_list, &childitem->elem); } else { free(childitem); } } } // Save exit status struct exitstatus * es = (struct exitstatus *) malloc(sizeof(struct exitstatus)); if(es != NULL && !ignore_remove(thread_current()->tid)) { es->avail = true; es->status = status; es->childid = thread_current()->tid; list_push_back(&exit_list, &es->elem); struct list_elem * e; for (e = list_begin (&waitproc_list); e != list_end (&waitproc_list); e = list_next (e)) { struct waitproc * item = list_entry (e, struct waitproc, elem); sema_up(&item->sema); } }
/*! Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release(struct lock *lock) { ASSERT(lock != NULL); ASSERT(lock_held_by_current_thread(lock)); lock->holder = NULL; lock->donated_priority = PRI_MIN; list_remove(&lock->elem); sema_up(&lock->semaphore); thread_yield(); }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); lock->holder = NULL; sema_up (&lock->semaphore); /* May yield if the newly unblocked thread is of higher priority than the current thread. */ }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); //list_find_delete(&thread_current()->lock_list,lock); //giveup_priority(); lock->holder = NULL; sema_up (&lock->semaphore); //check_priority(); }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); list_remove(&(lock->hold_elem)); lock_recall_priority(); lock->holder = NULL; sema_up (&lock->semaphore); }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); enum intr_level old_level = intr_disable (); thread_remove_donations(lock->holder, lock); lock->holder = NULL; sema_up (&lock->semaphore); intr_set_level (old_level); }
void exit_handler (int status) { printf("%s: exit(%d)\n", &thread_current ()->name, status); lock_acquire(&ref_count_lock); struct p_data* parent = thread_current()->parent_data; if (parent != NULL) { parent->exit_status = status; parent->child_thread = NULL; sema_up(&parent->sema); parent->ref_count--; if (parent->cwd != NULL) { dir_close(parent->cwd); } if (parent->ref_count == 0) { thread_current()->parent_data = NULL; free(parent); } } if (thread_current()->cwd != NULL) { dir_close(thread_current()->cwd); } /* iterate through children and remove this as their parent*/ struct list_elem* e; struct list *childs = &thread_current()->child_processes; for (e = list_begin(childs); e != list_end(childs); e = list_next(e)) { struct p_data* child = list_entry(e, struct p_data, elem); child->ref_count --; list_remove(e); if (child->ref_count == 0) { struct thread *t = child->child_thread; if (t != NULL) { t->parent_data = NULL; } free(child); } } struct list *files = &thread_current()->files; for (e = list_begin(files); e != list_end(files); e = list_begin(files)) { close_handler(list_entry(e, struct file_struct, elem)->fd); } struct file_struct *executable = thread_current()->executable; if (executable != NULL) { file_allow_write(executable->sys_file); file_close(executable->sys_file); thread_current()->executable = NULL; free(executable); } lock_release(&ref_count_lock); thread_exit(); }
void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); struct list_elem *cur_given= list_head(&thread_current()->donation_givenlist)->next; delete_donations_givenlist(cur_given,lock); delete_donations_takenlist(lock); lock->holder = NULL; sema_up (&lock->semaphore); }//end of release function
static void h_thread_func (void *ls_) { struct lock_and_sema *ls = ls_; lock_acquire (&ls->lock); msg ("Thread H acquired lock."); sema_up (&ls->sema); lock_release (&ls->lock); msg ("Thread H finished."); }
/* Releases LOCK, which must be owned by the current thread. An interrupt handler cannot acquire a lock, so it does not make sense to try to release a lock within an interrupt handler. */ void lock_release (struct lock *lock) { ASSERT (lock != NULL); ASSERT (lock_held_by_current_thread (lock)); //enum intr_level old_level= intr_disable(); lock->holder = NULL; //list_find_delete(&thread_current()->lock_list,lock); //intr_set_level(old_level); sema_up (&lock->semaphore); //giveup_priority(); }
static void vtrr_thread_func (void *aux) { long long *ticks = (long long *) aux; msg("thread working"); while (!exit_test) (*ticks)++; sema_up(&exit_sem); }
/* Up or "V" operation on a semaphore. Increments SEMA's value and wakes up all threads waiting for SEMA, if any. This function may be called from an interrupt handler. */ void sema_broadcast (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); old_level = intr_disable (); while (!list_empty (&sema->waiters)) sema_up (sema); intr_set_level (old_level); }
/* Timer interrupt handler. * To receive the scheduled interrupt, the software must have previously enabled the corresponding * IRQ line using the BCM2835 interrupt controller. */ static void timer_irq_handler(struct interrupts_stack_frame *stack_frame) { // printf("\nKernel - Timer Interrupt Handler."); sema_up(&sleep_sema); // The System Timer compare has to be reseted after the timer interrupt. timer_reset_timer_compare(IRQ_1); thread_tick(stack_frame); //timer_msleep(1000000); timer_msleep(300000); // The System Timer compare register has to be set up with the new time after the timer interrupt. timer_set_interval(IRQ_1, TIMER_PERIODIC_INTERVAL); }
/*! Self-test for semaphores that makes control "ping-pong" between a pair of threads. Insert calls to printf() to see what's going on. */ void sema_self_test(void) { struct semaphore sema[2]; int i; printf("Testing semaphores..."); sema_init(&sema[0], 0); sema_init(&sema[1], 0); thread_create("sema-test", PRI_DEFAULT, sema_test_helper, &sema); for (i = 0; i < 10; i++) { sema_up(&sema[0]); sema_down(&sema[1]); } printf ("done.\n"); }
void do_ugrad(int* studentsInRoom, sema gradAllowedMutex, int* gradsEaten, sema roomTypeMutex, enum studentType* currentStudentType) { while (1) { sema_down(roomTypeMutex); if (*currentStudentType != grad && *studentsInRoom < 2) { (*studentsInRoom) += 1; *currentStudentType = ugrad; sema_up(roomTypeMutex); printf("ugrad eating...\n"); sleep(randint()); printf(" ugrad done\n"); sema_down(roomTypeMutex); (*studentsInRoom) -= 1; if (*studentsInRoom == 0) { *currentStudentType = empty; } *gradsEaten = 0; sema_up(gradAllowedMutex); sema_up(roomTypeMutex); } else { sema_up(roomTypeMutex); } } }