Exemple #1
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));

  if (!lock_try_acquire (lock)) /* Someone else holding the lock. */
  {
    sema_down (&lock->semaphore);
    lock->holder = thread_current ();
  }
}
Exemple #2
0
void lock_acquire(VMM_LOCK* lock)
{
    (void)lock;
    CPU_ID this_cpu_id = hw_cpu_id();

    if (! lock) {
        return; // error
    }
    while (FALSE == lock_try_acquire(lock)) {
        VMM_ASSERT_NOLOCK(lock->owner_cpu_id != this_cpu_id);
        hw_pause();
    }
    lock->owner_cpu_id = this_cpu_id;
}
Exemple #3
0
void interruptible_lock_acquire(VMM_LOCK* lock)
{
    (void)lock;
    CPU_ID this_cpu_id = hw_cpu_id();
    BOOLEAN ipc_processed = FALSE;

    if (!lock) {
        return; // error
    }
    while (FALSE == lock_try_acquire(lock)) {
        ipc_processed = ipc_process_one_ipc();
        if(FALSE == ipc_processed) {
            hw_pause();
        }
    }
    lock->owner_cpu_id = this_cpu_id;
}
Exemple #4
0
/* Randomly sellects a page to evict. */
struct frame *get_frame_for_eviction() {
	struct hash_iterator hi;
	struct hash_elem e;

  ASSERT(lock_held_by_current_thread(&ft_lock));

//	lock_acquire(&ft_lock);
	do {
		long index = random_ulong() % hash_size(&frame_table);
		hash_first(&hi, &frame_table);
		for(int i = 0; i < index; i++)
			hash_next(&hi);
	} while(!lock_try_acquire(&get_frame(hash_cur(&hi))->evicting));
	struct frame *f = get_frame(hash_cur(&hi));
	ASSERT(!f->page->deleting);
//	lock_release(&ft_lock);
	
  return f;
}
Exemple #5
0
static void clock_daemon(void *aux) {
//	printf("starting clock\n");
	struct frame *head, *tail;
	bool got_frame = false;
/*	while(true)
		thread_yield();*/
//	sema_down(&clockwaiting);
//	int i;
	while(1) {
//		printf("locking\n");
		lock_acquire(&clocklock);
//		printf("Checking list is empty\n");
		if(list_empty(&clocklist)) {
//			printf("Releasing lock\n");
			lock_release(&clocklock);
//			printf("Sleeping\n");
			timer_msleep(CLOCK_WAIT_MS);
//			thread_yield();
//			printf("Woke up\n");
			continue;
		}
//		printf("List is not empty\n");
		if(clockmodified) {
//			printf("clockmodified");
			head = tail = get_clock_frame(list_begin(&clocklist));
//			i = 0;
		}
//		printf("clock got lock\n");
		for(int i = 0; i < CLOCK_DIFF_COUNT; i++) {
//			printf("in for loop");
//			if(!clockmodified)
//				i = CLOCK_WAIT_COUNT;
//			printf("clock on frame %p: checking semaphore at %p\n", current, &current->evicting);
			/* Clear head's accessed bit. */
			if(lock_try_acquire(&head->evicting)) {
//				printf("\t\tgot head sema\n");
				pagedir_set_accessed(head->page->thread->pagedir, head->page->vaddr, false);//TODO check if it is being moved
				lock_release(&head->evicting);
			}
			/* If clock hands have reached proper angle, use tail hand. */
			if(!clockmodified/*i >= CLOCK_WAIT_COUNT*/) {
				/* Check if frame has been changed accessed since head passed. */
				if(lock_try_acquire(&tail->evicting)) {
					if(!pagedir_is_writeable/*accessed*/(tail->page->thread->pagedir, tail->page->vaddr)) {
						/* Wait for clock frame to be cleared then set it to tail. */
//						if(sema_try_down(&clockwaiting))
						lock_acquire(&clockcondlock);
						if(clockwaiters > 0 && clockrecieved) {
							printf("Found non accessed dir\n");
							clock_frame = tail;
							clockrecieved = false;
							got_frame = true;
							cond_signal(&clockwaiting, &clockcondlock);
						}
						lock_release(&clockcondlock);
//							sema_up(&clockready);
//						break;
						//						}
					}
					if(!got_frame) {
						lock_release(&tail->evicting);
					} else {
						got_frame = true;
					}
				}
				tail = get_next_clock_frame(tail);
			}
//			printf("getting next frame\n");
			head = get_next_clock_frame(head);
//			printf("sleeping\n");
		}
		clockmodified = false;
		lock_release(&clocklock);
		timer_msleep(CLOCK_WAIT_MS);
//		thread_yield();
	}
	PANIC("Frame eviction daemon quit!\n");
}
Exemple #6
0
/* Tries to allocate and lock a frame for PAGE.
   Returns the frame if successful, false on failure. */
static struct frame *
try_frame_alloc_and_lock (struct page *page) 
{
  size_t i;

  lock_acquire (&scan_lock);

  /* Find a free frame. */
  for (i = 0; i < frame_cnt; i++)
    {
      struct frame *f = &frames[i];
      if (!lock_try_acquire (&f->lock))
        continue;
      if (f->page == NULL) 
        {
          f->page = page;
          lock_release (&scan_lock);
          return f;
        } 
      lock_release (&f->lock);
    }

  /* No free frame.  Find a frame to evict. */
  for (i = 0; i < frame_cnt * 2; i++) 
    {
      /* Get a frame. */
      struct frame *f = &frames[hand];
      if (++hand >= frame_cnt)
        hand = 0;

      if (!lock_try_acquire (&f->lock))
        continue;

      if (f->page == NULL) 
        {
          f->page = page;
          lock_release (&scan_lock);
          return f;
        } 

      if (page_accessed_recently (f->page)) 
        {
          lock_release (&f->lock);
          continue;
        }
          
      lock_release (&scan_lock);
      
      /* Evict this frame. */
      if (!page_out (f->page))
        {
          lock_release (&f->lock);
          return NULL;
        }

      f->page = page;
      return f;
    }

  lock_release (&scan_lock);
  return NULL;
}