1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #include <stdlib.h>
7 #include "lock/zm_hmcs.h"
8 #include "lock/zm_hmpr.h"
9 #include "cond/zm_wskip.h"
10 
zm_hmpr_init(struct zm_hmpr * L)11 int zm_hmpr_init(struct zm_hmpr *L) {
12     int ret;
13     ret = zm_hmcs_init(&L->lock);
14     ret = zm_wskip_init(&L->waitq);
15     return ret;
16 }
17 
zm_hmpr_destroy(struct zm_hmpr * L)18 int zm_hmpr_destroy(struct zm_hmpr *L) {
19     int ret;
20     ret = zm_hmcs_destroy(&L->lock);
21     ret = zm_wskip_destroy(&L->waitq);
22     return ret;
23 }
24 
zm_hmpr_acquire(struct zm_hmpr * L,struct zm_hmpr_pnode * N)25 int zm_hmpr_acquire(struct zm_hmpr *L, struct zm_hmpr_pnode *N) {
26     int ret;
27     if (N->p == 0) {
28         ret = zm_hmcs_acquire(L->lock);
29         assert(ret == 0);
30         if (!L->go_straight) {
31             ret = zm_wskip_enq(L->waitq, &L->znode);
32             assert(ret == 0);
33             L->go_straight = 1;
34         }
35     } else {
36         ret = zm_wskip_wait(L->waitq, &N->qnode);
37         ret = zm_hmcs_acquire(L->lock);
38         L->low_p_acq = 1;
39     }
40     return ret;
41 }
42 
zm_hmpr_release(struct zm_hmpr * L,struct zm_hmpr_pnode * N)43 int zm_hmpr_release(struct zm_hmpr *L, struct zm_hmpr_pnode *N) {
44     int ret;
45     if (!L->low_p_acq) {
46         if (zm_hmcs_nowaiters(L->lock)) {
47             L->go_straight = 0;
48             ret = zm_wskip_wake(L->waitq, &L->znode);
49         }
50         zm_hmcs_release(L->lock);
51     } else {
52         L->low_p_acq = 0;
53         zm_hmcs_release(L->lock);
54         ret = zm_wskip_wake(L->waitq, N->qnode);
55     }
56     return ret;
57 }
58 
zm_hmpr_raise_prio(struct zm_hmpr_pnode * N)59 int zm_hmpr_raise_prio(struct zm_hmpr_pnode *N) {
60     if (N->p > 0) {
61         N->p--;
62         if ((N->p == 0) && (N->qnode != NULL))
63             return zm_wskip_skip(N->qnode);
64     }
65     return 0;
66 }
67