lab 7(管路)

3454 ワード

かんろ
monitr構造
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
", 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
", 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
", 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
", cvp, cvp->count, cvp->owner->next_count); }

 
有効な実行順序
実行cond_waitのプロセス
mutexの取得->mutexの解放->条件待ちに入る->実行->nextにブロックされたプロセスの起動
実行cond_Signalのプロセス
->mutexの取得->待機条件を起動するプロセス->nextで待機
->mutexの解放