Exemplo n.º 1
0
void
PC_Put(PC *pc, int color)
{
  Lock_Acquire(&pc->lock);
  assert(color <= pc->maxColor);
  while(pc->capacity == pc->used){
    pc->waitingP++;
    Cond_Wait(&pc->spaceAvail, &pc->lock);
    pc->waitingP--;
  }
  pc->used++;
  addItem(color, &(pc->list));
  assert(((Item *)List_Last(&(pc->list)))->color == color);
  if(pc->used == 1){
    /*
     * Went from empty to non-empty. Signal
     */
    if(pc->maxColor == 0){
      Cond_Signal(&pc->stuffAvail, &pc->lock);
    }
    else{
      Cond_Broadcast(&pc->stuffAvail, &pc->lock);
    }
  }
  assert(((Item *)List_Last(&(pc->list)))->color == color);
  Lock_Release(&pc->lock);
}
Exemplo n.º 2
0
int P(int sid)
{
	struct Semaphore* sema = (&s_semaphoreList)->head;
	struct Mutex* mutex;
	struct Condition* cond;

	//find sem by sid
	while (sema != 0)
	{
		if (sema->sid == sid)
		{
			mutex = &(sema->mutex); // important
			cond = &(sema->cond);

			Enable_Interrupts();
			Mutex_Lock(mutex);
			while(sema->count <= 0)
			{
				Cond_Wait(cond, mutex);
				//Print("WAKE UP!");
			}
			sema->count--;
			Mutex_Unlock(mutex);
			Disable_Interrupts();
			
			return 0;
		}
		sema = Get_Next_In_Semaphore_List(sema);
	}
	
	return -1;
}
Exemplo n.º 3
0
/*
   PROGRAM:  Philosopher
   A program that simulates a philosopher participating in a dining philosophers'
   symposium. Each philosopher will join the symposium, alternating between
   thinking, going hungry and eating a bite, for a number of bites. After he
   has eaten the last bite, he leaves.
*/
int Philosopher(int argl, void* args)
{
    int i,j;
    int bites;			/* Number of bites (mpoykies) */

    assert(argl == sizeof(int[2]));
    i = ((int*)args)[0];
    bites = ((int*)args)[1];

    Mutex_Lock(&mx);		/* Philosopher arrives in thinking state */
    state[i] = THINKING;
    print_state("     %d has arrived\n",i);
    Mutex_Unlock(&mx);

    for(j=0; j<bites; j++) {

        think(i);			/* THINK */

        Mutex_Lock(&mx);		/* GO HUNGRY */
        state[i] = HUNGRY;
        trytoeat(i);		/* This may not succeed */
        while(state[i]==HUNGRY) {
            print_state("     %d waits hungry\n",i);
            Cond_Wait(&mx, &(hungry[i])); /* If hungry we sleep. trytoeat(i) will wake us. */
        }
        assert(state[i]==EATING);
        Mutex_Unlock(&mx);

        eat(i);			/* EAT */

        Mutex_Lock(&mx);
        state[i] = THINKING;	/* We are done eating, think again */
        print_state("     %d is thinking\n",i);
        trytoeat(LEFT(i));		/* Check if our left and right can eat NOW. */
        trytoeat(RIGHT(i));
        Mutex_Unlock(&mx);
    }
    Mutex_Lock(&mx);
    state[i] = NOTHERE;		/* We are done (eaten all the bites) */
    print_state("     %d is leaving\n",i);
    Mutex_Unlock(&mx);

    return i;
}
Exemplo n.º 4
0
int
PC_Get(PC *pc, int color)
{
  Lock_Acquire(&pc->lock);
  assert(color <= pc->maxColor);
  while(List_IsEmpty(&(pc->list)) 
        || (((Item *)List_First(&(pc->list)))->color != color)){
    pc->waitingC++;
    Cond_Wait(&pc->stuffAvail, &pc->lock);
    pc->waitingC--;
  }
  removeItem(color, &(pc->list));
  pc->used--;
  Cond_Signal(&pc->spaceAvail, &pc->lock);
  /* 
   * We just took top item off -- another getter may be
   * able to proceed
   */
  Cond_Broadcast(&pc->stuffAvail, &pc->lock);
  Lock_Release(&pc->lock);
  return color;
}
Exemplo n.º 5
0
/*
 * Get buffer for given block, and mark it in use.
 * Must be called with cache mutex held.
 */
static int Get_Buffer(struct FS_Buffer_Cache *cache, ulong_t fsBlockNum,
                      struct FS_Buffer **pBuf) {
    struct FS_Buffer *buf, *lru = 0;
    int rc;

    Debug("Request block %lu\n", fsBlockNum);

    KASSERT(IS_HELD(&cache->lock));

    /*
     * Look for existing buffer.
     * As a side-effect, finds the least recently used
     * buffer that is not in use (if any).
     */
    buf = Get_Front_Of_FS_Buffer_List(&cache->bufferList);
    while (buf != 0) {
        if (buf->fsBlockNum == fsBlockNum) {
            /* If buffer is in use, wait until it is available. */
            while (buf->flags & FS_BUFFER_INUSE) {
                Debug("Waiting for block %lu\n", fsBlockNum);
                Cond_Wait(&cache->cond, &cache->lock);
            }
            goto done;
        }

        /* If buffer isn't in use, it's a candidate for LRU. */
        if (!(buf->flags & FS_BUFFER_INUSE))
            lru = buf;

        buf = Get_Next_In_FS_Buffer_List(buf);
    }

    /*
     * If number of allocated buffers does not exceed the
     * limit, allocate a new one.
     */
    if (cache->numCached < FS_BUFFER_CACHE_MAX_BLOCKS) {
        buf = (struct FS_Buffer *)Malloc(sizeof(*buf));
        if (buf != 0) {
            buf->data = Alloc_Page();
            if (buf->data == 0)
                Free(buf);
            else {
                /* Successful creation */
                buf->fsBlockNum = fsBlockNum;
                buf->flags = 0;
                Add_To_Front_Of_FS_Buffer_List(&cache->bufferList, buf);
                ++cache->numCached;
                goto readAndAcquire;
            }
        }
    }

    /*
     * If there is no LRU buffer, then we have exceeded
     * the number of available buffers.
     */
    if (lru == 0)
        return ENOMEM;

    KASSERT(!noEvict);

    /* Make sure the LRU buffer is clean. */
    if ((rc = Sync_Buffer(cache, lru)) != 0)
        return rc;

    /* LRU buffer is clean, so we can steal it. */
    buf = lru;
    buf->flags = 0;
    buf->fsBlockNum = fsBlockNum;       /* bugfix by neil. */

    Move_To_Front(cache, buf);

  readAndAcquire:
    /*
     * The buffer selected should be clean (no uncommitted data),
     * and should have been moved to the front of the buffer list
     * (to show it has just been referenced).
     */
    KASSERT(!(buf->flags & FS_BUFFER_DIRTY));
    KASSERT(Get_Front_Of_FS_Buffer_List(&cache->bufferList) == buf);

    /* Read block data into buffer. */
    if ((rc = Do_Buffer_IO(cache, buf, Block_Read)) != 0)
        return rc;

  done:
    /* Buffer is now in use. */
    buf->flags |= FS_BUFFER_INUSE;

    /* Success! */
    Debug("Acquired block %lu\n", fsBlockNum);
    *pBuf = buf;
    return 0;
}