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)11int 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)18int 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)25int 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)43int 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)59int 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