/* 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 (); }
/* Down or "P" operation on a semaphore. Waits for SEMA's value * to become positive and then atomically decrements it. * * This function may sleep, so it must not be called within an * interrupt handler. This function may be called with * interrupts disabled, but if it sleeps then the next scheduled * thread will probably turn interrupts back on. */ void sema_down(struct semaphore *sema) { enum intr_level old_level; ASSERT(sema != NULL); ASSERT(!intr_context()); old_level = intr_disable (); while(sema -> value == 0) { /* * 注释掉原有代码 * list_push_back(&sema->waiters, &thread_current ()->elem); */ /* 按照降序插入 */ list_insert_ordered( &sema -> waiters, &thread_current() -> elem, (list_less_func *) &priority_cmp_max_to_low, NULL ); /* 阻塞当前线程 */ thread_block(); } sema -> value--; intr_set_level(old_level); }
/* 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); /* Modified by Bin */ /* while (timer_elapsed (start) < ticks) thread_yield ();*/ int64_t wakeup_ticks = start + ticks; enum intr_level old_level; old_level = intr_disable (); struct thread *cur = thread_current (); cur->wakeup_ticks = wakeup_ticks; list_insert_ordered (&waiting_list, &cur->waiting_elem, less_ticks, &wakeup_ticks); thread_block (); intr_set_level (old_level); }
/* Down or "P" operation on a semaphore. Waits for SEMA's value * to become positive and then atomically decrements it. * * This function may sleep, so it must not be called within an * interrupt handler. This function may be called with * interrupts disabled, but if it sleeps then the next scheduled * thread will probably turn interrupts back on. */ void sema_down(struct semaphore *sema) { enum intr_level old_level; ASSERT(sema != NULL); ASSERT(!intr_context()); old_level = intr_disable(); while (sema -> value == 0) { /* * 注释掉原有的代码 * list_push_back(&sema -> waiters, &thread_current() -> elem); * thread_block(); */ if (!thread_mlfqs) { donate_priority(); } list_insert_ordered( &sema -> waiters, &thread_current() -> elem, (list_less_func *) &cmp_priority, NULL ); thread_block(); } sema -> value--; intr_set_level(old_level); }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { ASSERT (intr_get_level () == INTR_ON);//interrupts must be on, otherwise kernel panic struct thread * t = thread_current(); t->endTime = timer_ticks() + ticks; enum intr_level old_level = intr_disable(); //disables interrupts and saves previous interrupt state in old_level //add to sleep list //list_push_back( &sleepingThreads, &t->elem); list_insert_ordered( &sleepingThreads, &t->elem, SLEEPING_THREAD_LESS_THAN, NULL); thread_block(); //sets thread to wait state intr_set_level(old_level); //resets interrupt status to original settings }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { //printf("SLEEP WAS CALLED!\n"); int64_t start = timer_ticks (); if(ticks < 0) ticks = start; struct thread *t = thread_current(); t->awakeTime = (start + ticks); //printf("setting awaketime to ", t->awakeTime); // printf("set wake at %d \n" , t->awakeTime); ASSERT (intr_get_level () == INTR_ON); enum intr_level curState = intr_disable(); list_insert_ordered(getWaitList(), &t->waitelem,COMPAREFUNC,NULL); //printf("print something----------------------------------------------------------"); //add t to a list of sleeping threads in order... thread_block(); // put thread to sleep intr_set_level(curState); //while (timer_elapsed (start) < ticks) // 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); #if 0 /* pj1 */ while (timer_elapsed (start) < ticks) thread_yield (); #endif #if 1 /* pj1 */ if (ticks <= 0) return; /* add current thread to sleep thread list in order, * and set its wake up time. Then schedule a new thread. */ struct thread *cur = thread_current(); enum intr_level old_level; lock_acquire(&sleep_list_lock); old_level = intr_disable(); cur->wake_up_ticks = start + ticks; list_insert_ordered(&sleep_list, &cur->elem, (list_less_func *)cmp_thread_wake_ticks, NULL); lock_release(&sleep_list_lock); thread_block(); intr_set_level(old_level); #endif }
int syscall_open(const char *file) { if(!is_valid_ptr(file)) syscall_exit(-1); // 0. Try to open it. struct file *fp = filesys_open(file); if (!fp) return -1; // 1. Get First Empty FD int fd = Get_First_Empty_FD(&(thread_current()->FDs)); if (fd == -1) // XXX Reached MAX_FD (* TEST: [multi-oom]) return -1; // 2. Make FD struct fd_list *new_fd = (struct fd_list *)calloc(1, sizeof(struct fd_list)); if(!new_fd) return -1; // 3. Assign That FD as got the first empty one. new_fd->fd = fd; new_fd->file = fp; // 4. Insert Ordered this FD at FDs List. list_insert_ordered( &(thread_current()->FDs), &(new_fd->elem), FD_List_Less_Func, NULL); return fd; }
/* Down or "P" operation on a semaphore. Waits for SEMA's value to become positive and then atomically decrements it. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but if it sleeps then the next scheduled thread will probably turn interrupts back on. */ void sema_down (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); ASSERT (!intr_context ()); old_level = intr_disable (); struct thread *currentThread = thread_current(); while (sema->value == 0) { if(!thread_mlfqs) { thread_donate_priority(); } //list_insert_priority_ordered (&sema->waiters, ¤tThread->elem, currentThread->priority); list_insert_ordered (&sema->waiters, ¤tThread->elem, (list_less_func *) &thread_cmp_priority, NULL); thread_block (); } sema->value--; intr_set_level (old_level); }
header_t* heap_alloc(size_t size) { header_t* h = free_list; header_t* best_fit = NULL; header_t* prev_best_fit = NULL; header_t* prev = NULL; HEAP_VALIDATE; // Also allocate mem for header: size += HEAP_HEADER_SIZE; // Find best candidate: while (h != NULL) { if (h->e.size >= size) { // h fulfils the request, but is it the best: if (best_fit != NULL) { if (h->e.size < best_fit->e.size) { prev_best_fit = prev; best_fit = h; } } else { prev_best_fit = prev; best_fit = h; } } prev = h; h = h->e.next; } if (best_fit != NULL) { // remove from free list: list_remove(&free_list, prev_best_fit, best_fit); size_t remaining_size = best_fit->e.size - size; size_t best_fit_size; if (remaining_size > HEAP_HEADER_SIZE) { // The best_fit is too large; split into two parts: header_t* remaining = offset_header(best_fit, size); init_element(remaining, remaining_size, HT_FREE); // Return to free list: list_insert_ordered(&free_list, remaining); // Adjust the size of best fit: best_fit_size = size; } else { // No split: best_fit_size = best_fit->e.size; } // else: Perfect fit init_element(best_fit, best_fit_size, HT_USED); } // else: Out of mem HEAP_VALIDATE; return best_fit; }
/* Acquires LOCK, sleeping until it becomes available if necessary. The lock must not already be held by the current thread. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but interrupts will be turned back on if we need to sleep. */ void lock_acquire (struct lock *lock) { ASSERT (lock != NULL); ASSERT (!intr_context ()); ASSERT (!lock_held_by_current_thread (lock)); //implementing donation //enum intr_level old_level; //old_level = intr_disable(); //PRE:1.HIGHEST PRIORITY THREADS TAKING THE CPU //2.CURRENT->THREAD WHICH HAVE HIGHEST PRIORITY //3.Thus the lock holder must be in the ready list //NEW if (thread_mlfqs) { //roozbeh //in case mlfqs, no need for donations sema_down (&lock->semaphore); lock->holder = thread_current (); } else { //non- mlfqs case, do donation //duc: struct thread *cur = thread_current(); struct thread *lock_holder = lock->holder; if (lock_holder != NULL) donate(lock, cur->priority, MAX_DEPTH); //stick lock to current thread cur->target_lock = lock; sema_down(&lock->semaphore); lock->holder = thread_current(); lock->max_priority = cur->priority; list_insert_ordered(&cur->lock_list, &lock->elem, higher_priority_lock, NULL); cur->target_lock = NULL; } //OLD /*if (lock_holder!=NULL && lock_holder->priority < cur->priority) { cur->donee_priority = lock_holder->priority; //insert into this lock's waiting queue according to it's priority //list_insert_ordered(&lock->semaphore.waiters, &cur->elem, higher_priority, NULL); //lock_holder->donation_times++; //>do we check donation_time initialized as 0? lock_holder->priority=cur->priority; //thread_block(); } sema_down (&lock->semaphore);//try to release the lock lock->holder = thread_current ();*/ //intr_set_level(old_level); }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. Sleep 'ticks' must be positive */ void timer_sleep (int64_t sleep_ticks) { if(sleep_ticks > 0) { thread_current()->awake_tick = timer_ticks() + sleep_ticks; list_insert_ordered(&sleep_list, &thread_current()->elem, (list_less_func *) &list_compare_time_to_sleep, NULL); enum intr_level previous_level = intr_disable(); thread_block(); intr_set_level(previous_level); } }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { struct thread *cur = thread_current (); ASSERT (intr_get_level () == INTR_ON); /* 2015.09.15. Add for avoid busy-waiting(s) */ cur->sleep_ticks = timer_ticks() + ticks; list_insert_ordered(&waiting_list, &cur->waitingelem, &is_small_sleep_ticks, NULL); enum intr_level old_level = intr_disable (); thread_block (); intr_set_level(old_level); /* 2015.09.15. Add for avoid busy-waiting(e) */ }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { struct thread *t = thread_current (); enum intr_level old_level = intr_get_level (); t->awake_time = timer_ticks() + ticks; ASSERT (old_level == INTR_ON); intr_disable (); list_insert_ordered (&sleep_list, &t->sleepelem, time_compare, NULL); thread_block (); intr_set_level (old_level); }
/* Free memory, coalescing free list if necessary. */ void mem_free(void *ptr) { struct list_elem* temp_elem_p; struct used_block* used_p; struct free_block* free_p; struct free_block* temp_free_p; size_t actual_length; #ifdef debug printf("FREE: %d\n",(int) ptr); #endif #ifdef verbose printf("Before: "); mem_dump_free_list(); #endif pthread_mutex_lock(&lock); used_p = (struct used_block*) (ptr - sizeof(struct used_block)); actual_length = used_p->length + sizeof(struct used_block); free_p = (struct free_block*) used_p; free_p->length = actual_length; list_insert_ordered(&free_list, &free_p->elem, mem_block_less, NULL); #ifdef debug printf("\tAdded free block: @%d len=%d\n", (int) free_p, free_p->length); #endif #ifdef verbose printf("After: "); mem_dump_free_list(); #endif temp_elem_p = list_prev(&free_p->elem); if (temp_elem_p != list_head(&free_list)) { temp_free_p = list_entry(temp_elem_p, struct free_block, elem); #ifdef verbose printf("Checking before @%d+%d == %d\n", (int) temp_free_p, temp_free_p->length, (int) free_p); #endif if (mem_block_is_adjacent(temp_free_p, free_p)) { #ifdef verbose printf("Merging before @%d+%d == %d\n", (int) temp_free_p, temp_free_p->length, (int) free_p); #endif mem_coalesce(temp_free_p, free_p); free_p = temp_free_p; } }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { enum intr_level old_level; ASSERT (intr_get_level () == INTR_ON); if(ticks <= 0) return; old_level = intr_disable(); struct thread *cur = thread_current(); cur->sleep_ticks = timer_ticks() + ticks; list_insert_ordered(&sleeping, &cur->elem,(list_less_func*)&thread_wake, NULL); thread_block(); intr_set_level(old_level); }
/* Down or "P" operation on a semaphore. Waits for SEMA's value to become positive and then atomically decrements it. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but if it sleeps then the next scheduled thread will probably turn interrupts back on. Returns false if the lock acquire results in a deadlock, and true otherwise. */ void sema_down (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); ASSERT (!intr_context ()); old_level = intr_disable (); while (sema->value == 0) { list_insert_ordered (&sema->waiters, &thread_current ()->elem, priority_less, NULL); thread_block (); } sema->value--; intr_set_level (old_level); }
/*yan*/ void sema_down (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); ASSERT (!intr_context ()); old_level = intr_disable(); //disable the interrupts while (sema->value==0) { //insert current thread into waiter list list_insert_ordered(&sema->waiters,&thread_current()->elem,higher_priority,NULL); thread_block(); } sema->value--; intr_set_level (old_level); }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { int64_t start = timer_ticks (); struct thread *cur = thread_current (); cur->wakeup_time = start + ticks; ASSERT (intr_get_level () == INTR_ON); intr_disable (); list_insert_ordered (&wait_list, &cur->wait_elem, compare_threads_by_wakeup_time, NULL); intr_enable (); // Lastly block ourselves sema_down(&cur->wait_sema); }
/* Atomically releases LOCK and waits for COND to be signaled by some other piece of code. After COND is signaled, LOCK is reacquired before returning. LOCK must be held before calling this function. The monitor implemented by this function is "Mesa" style, not "Hoare" style, that is, sending and receiving a signal are not an atomic operation. Thus, typically the caller must recheck the condition after the wait completes and, if necessary, wait again. A given condition variable is associated with only a single lock, but one lock may be associated with any number of condition variables. That is, there is a one-to-many mapping from locks to condition variables. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but interrupts will be turned back on if we need to sleep. */ void cond_wait (struct condition *cond, struct lock *lock) { struct semaphore_elem waiter; ASSERT (cond != NULL); ASSERT (lock != NULL); ASSERT (!intr_context ()); ASSERT (lock_held_by_current_thread (lock)); sema_init (&waiter.semaphore, 0); list_insert_ordered (&cond->waiters, &waiter.elem, comp_cond_pri_less, &thread_current ()->priority); lock_release (lock); sema_down (&waiter.semaphore); lock_acquire (lock); }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { int64_t start = timer_ticks (); struct thread *t = thread_current(); t->wakeup_time = start + ticks; ASSERT (intr_get_level () == INTR_ON); intr_disable(); list_insert_ordered(&wait_list,&(t->timer_list_elem),compare_threads_by_wakeup_time,NULL); intr_enable(); sema_down(&(t->sema)); }
/* 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); if(timer_elapsed (start) < ticks){ struct thread *cur = thread_current (); enum intr_level old_level; old_level = intr_disable (); cur->rem_ticks = start + ticks; list_insert_ordered(&blocked_pqueue, &(cur->blocked_elem), (list_less_func *) &bThread_comparable , NULL); thread_block(); intr_set_level (old_level); } }
void heap_free(header_t* h) { HEAP_VALIDATE; if (h == NULL) { consout("Element is NULL\n"); HEAP_EXIT; } if (!is_type(h, HT_USED) && !is_type(h, HT_PROTECTED)) { consout("Magic\n"); HEAP_EXIT; } set_type(h, HT_FREE); list_insert_ordered(&free_list, h); HEAP_VALIDATE; }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { ASSERT (intr_get_level () == INTR_ON); struct thread * t; enum intr_level old_state; old_state = intr_disable(); t = thread_current(); t -> sleep_ticks = timer_ticks() + ticks; list_insert_ordered(&wait_list, &t->elem, &cmp_sleep_ticks, NULL); thread_block(); intr_set_level(old_state); }
/* Down or "P" operation on a semaphore. Waits for SEMA's value to become positive and then atomically decrements it. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but if it sleeps then the next scheduled thread will probably turn interrupts back on. */ void sema_down (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); ASSERT (!intr_context ()); old_level = intr_disable (); while (sema->value == 0) { /* Keep the waiting list sorted, highest priority first. */ list_insert_ordered (&sema->waiters, &thread_current ()->elem, more_prio, NULL); thread_block (); } sema->value--; intr_set_level (old_level); }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep (int64_t ticks) { ASSERT (intr_get_level () == INTR_ON); if (ticks <= 0) { return; } // disable interrupt so you can make the thread go to sleep enum intr_level old_level = intr_disable (); // add the timer ticks into data member of thread to keep track of ticks thread_current()->ticks = timer_ticks() + ticks; // add the current thread into the sleep_list which is a queue for sleeping threads list_insert_ordered(&sleep_list, &thread_current()->elem, (list_less_func *) &cmp_ticks, NULL); // make the thread sleep thread_block(); intr_set_level(old_level); }
/* Sleeps for approximately TICKS timer ticks. Interrupts must be turned on. */ void timer_sleep(int64_t ticks) { ASSERT(intr_get_level() == INTR_ON); if(ticks <= 0) { return; } enum intr_level old_level = intr_disable(); thread_current()->wakeup_tick = ticks + timer_ticks(); list_insert_ordered(&sleeping_threads, &thread_current()->elem, (list_less_func *) &compare_wakeup_tick, NULL); thread_block(); intr_set_level(old_level); }
/* Acquires LOCK, sleeping until it becomes available if necessary. The lock must not already be held by the current thread. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but interrupts will be turned back on if we need to sleep. */ void lock_acquire (struct lock *lock) { ASSERT (lock != NULL); ASSERT (!intr_context ()); ASSERT (!lock_held_by_current_thread (lock)); /* Added for priority donation. */ if (lock->holder != NULL) { if (lock->highest_waiter == NULL) { lock->highest_waiter = thread_current (); lock->highest_waiter->waiting_for = lock->holder; } else if (lock->highest_waiter->priority < thread_current ()->priority) { list_remove (&lock->highest_waiter->waiting_elem); lock->highest_waiter->waiting_for = thread_current (); lock->highest_waiter = thread_current (); lock->highest_waiter->waiting_for = lock->holder; } if (lock->highest_waiter == thread_current ()) { list_insert_ordered (&lock->holder->waiting_threads, &lock->highest_waiter->waiting_elem, waiting_value_great, NULL); if (lock->holder->priority < &lock->highest_waiter->priority) { if (lock->holder->priority_orig < 0) lock->holder->priority_orig = lock->holder->priority; thread_donate_priority (lock->holder, lock->highest_waiter->priority); } } } sema_down (&lock->semaphore); lock->holder = thread_current (); /* Added for priority donation. */ lock->highest_waiter = !list_empty (&lock->semaphore.waiters) ? list_entry (list_begin (&lock->semaphore.waiters), struct thread, elem) : NULL; }
/* Down or "P" operation on a semaphore. Waits for SEMA's value to become positive and then atomically decrements it. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but if it sleeps then the next scheduled thread will probably turn interrupts back on. */ void sema_down (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); ASSERT (!intr_context ()); old_level = intr_disable (); while (sema->value == 0) { //list_push_back (&sema->waiters, &thread_current ()->elem); /* My Implementation */ list_insert_ordered(&sema->waiters, &thread_current ()->elem, compare_by_priority, NULL); /* == Implementaion */ thread_block (); } sema->value--; intr_set_level (old_level); }
/* Down or "P" operation on a semaphore. Waits for SEMA's value to become positive and then atomically decrements it. This function may sleep, so it must not be called within an interrupt handler. This function may be called with interrupts disabled, but if it sleeps then the next scheduled thread will probably turn interrupts back on. */ void sema_down (struct semaphore *sema) { enum intr_level old_level; ASSERT (sema != NULL); ASSERT (!intr_context ()); old_level = intr_disable (); while (sema->value == 0) { /* Insert into the correct location */ list_insert_ordered (&sema->waiters, &thread_current ()->elem, thread_priority_fifo, NULL); thread_current ()->in_list = &sema->waiters; thread_block (); } sema->value--; intr_set_level (old_level); }