Exemple #1
0
/* 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 (&current_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,&current_thread.elem,wakeup_order,NULL);
  intr_set_level (old_level);

  sema_down (&current_thread.sleep_sema); 	

/*Old Code*/
 // while (timer_elapsed (start) < ticks) 
 //   thread_yield ();
}
Exemple #2
0
/* 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);
}
Exemple #3
0
/* 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);
}
Exemple #4
0
/* 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);
}
Exemple #5
0
/* 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
}
Exemple #6
0
/* 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 ();
}
Exemple #7
0
/* 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;
}
Exemple #9
0
/* 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, &currentThread->elem, currentThread->priority);
  	list_insert_ordered (&sema->waiters, &currentThread->elem, (list_less_func *) &thread_cmp_priority, NULL);

    thread_block ();
  }
  
  sema->value--;
  intr_set_level (old_level);
}
Exemple #10
0
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;
}
Exemple #11
0
/* 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);
}
Exemple #12
0
/* 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);
  }
}
Exemple #13
0
/* 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) */
}
Exemple #14
0
/* 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);
}
Exemple #15
0
/* 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;
        }
    }
Exemple #16
0
/* 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);
}
Exemple #18
0
/*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);
}
Exemple #19
0
/* 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);
}
Exemple #20
0
/* 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);
}
Exemple #21
0
/* 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));
}
Exemple #22
0
/* 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);
  }

}
Exemple #23
0
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;
}
Exemple #24
0
/* 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);
}
Exemple #25
0
/* 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);
}
Exemple #26
0
/* 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);
}
Exemple #27
0
/* 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;
}
Exemple #29
0
/* 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);
}
Exemple #30
0
/* 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);
}