« 自前のセマフォは案外たいへん(2) | トップページ | 自前のセマフォは案外たいへん(おまけ) »

2018年7月15日 (日)

自前のセマフォは案外たいへん(3)

セマフォ自作の実況第3段です。第2段

mtx_lock() 内で実行している mtx_append() は下記のようになっています。これはセマフォの待ち行列に入る関数です。

int mtx_append(queue_t *que, process_id id)
{
    if (que->id[que->last] != 0) return -1;        /* (5-1) */

    que->id[que->last++] = id;            /* (5-2) */
    if (que->last == que->size){          /* (5-3) */
        que->last = 0;
    }
    retun 0;
} /* end of mtx_append() */

que->last はプロセス ID が挿入される配列内の位置です。 que->id[que->last] != 0 は、その位置に既にスレッドが入っている、即ち、セマフォの待ち行列は満席であることを意味しています(5-1)。この場合、簡単のため、エラーで返ることにしました。 que->id[que->last] が空席の場合、この位置にプロセス ID を挿入した後で que->last はインクリメントされます(5-2)。つまり、 que->last はポスト・インクリメントの動作をします。待ち行列はリングバッファを構成しています(5-3)。

セマフォの開放は mtx_unlock() で行います。

void mtx_unlock(queue_t *que)
{
    process_id    id_next;

    spinlock(&(que->lock));            /* (6-1) */
    que->id[que->first] = 0;           /* (6-2) */
    if (++(que->first) == que->size)    /* (6-3) */
        que->first = 0;
    id_next = que->id[que->first];
    spinunlock(&(que->lock));
    if (id_next != 0){
        _os_send(id_next, que->signal);        /* (6-4) */
    }
} /* end of mtx_unlock() */

セマフォを開放するということは、セマフォを待っているスレッドにセマフォの権限を与えるということです(もちろん、待っているスレッドが有ればの話し)。現在セマフォを獲得しているスレッドは待ち行列の que->first 番に入っているので、そこのプロセス ID を 0 にして他のスレッドが使用可能にします(6-2)。セマフォに対して次に権利のあるスレッドは待ち行列の que->first + 1 番で待っています(6-3)。そのプロセス ID id_next0 だと待っているスレッドは無いことを意味します。 0 でなければ、そのスレッドにシグナルを送って順番を知らせます(6-4)。

自前セマフォの作成は以上です。次回(おまけ)に続きます。

« 自前のセマフォは案外たいへん(2) | トップページ | 自前のセマフォは案外たいへん(おまけ) »

プログラミング」カテゴリの記事

コメント

コメントを書く

(ウェブ上には掲載しません)

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/584699/66941154

この記事へのトラックバック一覧です: 自前のセマフォは案外たいへん(3):

« 自前のセマフォは案外たいへん(2) | トップページ | 自前のセマフォは案外たいへん(おまけ) »