lab7(管程)

管程 

moniter结构

mutex:初始值为1,用于对管程的互斥访问 

next:初始值为0,作为一个等待队列,用于阻塞已获得mutex的进程,next_count用于记录阻塞于next的进程数,类似于条件变量中的等待队列,唤醒等待进程的信号不可存储,即只可以唤醒事先进入等待队列的进程,而不能记录信号用来使后来的进程避免等待。

cv:条件变量,使需要等待某一条件出现的进程进入响应的等待队列,先等待后唤醒,使用semaphore来模拟,信号量初值为0

typedef struct condvar{
    semaphore_t sem;        // the sem semaphore  is used to down the waiting proc, and the signaling proc should up the waiting proc
    int count;              // the number of waiters on condvar
    monitor_t * owner;      // the owner(monitor) of this condvar
} condvar_t;

typedef struct monitor{
    semaphore_t mutex;      // the mutex lock for going into the routines in monitor, should be initialized to 1
    semaphore_t next;       // the next semaphore is used to down the signaling proc itself, and the other OR wakeuped waiting proc should wake up the sleeped signaling proc.
    int next_count;         // the number of of sleeped signaling proc
    condvar_t *cv;          // the condvars in monitor
} monitor_t;

 

 cond_signal

用于唤醒等待在某条件变量等待队列的进程。初始时先判断是否有进程等待,没有则不做操作,一次唤醒操作将丢失,有进程等待则唤醒。ucore使用的管程方案当唤醒某等待进程时,唤醒者阻塞自身,将使用管程的权利出让给被唤醒者。由于唤醒者在调用cond_signal之前必然已经获得了mutex,唤醒者在保持mutex的情况下等待在next的等待队列中,直到被唤醒者归还使用管程的权利,将唤醒者从next唤醒。

void
cond_signal (condvar_t *cvp) {
   //LAB7 EXERCISE1: YOUR CODE
    cprintf("cond_signal begin: cvp %x, cvp->count %d, cvp->owner->next_count %d\n", cvp, cvp->count, cvp->owner->next_count);
  /*
   *      cond_signal(cv) {
   *          if(cv.count>0) {
   *             mt.next_count ++;
   *             signal(cv.sem);
   *             wait(mt.next);
   *             mt.next_count--;
   *          }
   *       }
   */
    if(cvp->count>0) {
        cvp->owner->next_count ++;
        up(&(cvp->sem));
        down(&(cvp->owner->next));
        cvp->owner->next_count --;
    }
    cprintf("cond_signal end: cvp %x, cvp->count %d, cvp->owner->next_count %d\n", cvp, cvp->count, cvp->owner->next_count);
}

 

cond_wait 

用于等待某条件出现,被cond_signal唤醒。此处的if判断只能指向else,并释放mutex,然后进入等待,直到唤醒者进程获得mutex将其唤醒并阻塞于next。

void
cond_wait (condvar_t *cvp) {
    //LAB7 EXERCISE1: YOUR CODE
    cprintf("cond_wait begin:  cvp %x, cvp->count %d, cvp->owner->next_count %d\n", cvp, cvp->count, cvp->owner->next_count);
    cvp->count++;
    if ((cvp->owner)->next_count > 0)
        up(&((cvp->owner)->next));
    else
        up(&((cvp->owner)->mutex));
    down(&(cvp->sem));
    cvp->count--;


    /*
    *         cv.count ++;
    *         if(mt.next_count>0)
    *            signal(mt.next)
    *         else
    *            signal(mt.mutex);
    *         wait(cv.sem);
    *         cv.count --;
    */
    cprintf("cond_wait end:  cvp %x, cvp->count %d, cvp->owner->next_count %d\n", cvp, cvp->count, cvp->owner->next_count);
}

 


有效的执行顺序

执行cond_wait的进程

获得mutex -> 释放mutex -> 进入条件等待                                                                                    -> 执行 -> 唤醒阻塞于next的进程

执行cond_signal的进程

                                                                   -> 获得mutex -> 唤醒等待条件的进程 -> 等待于next

 -> 释放mutex

 

 

 

 

你可能感兴趣的:(ucore)