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_mcsp.h"
8
zm_mcsp_init(zm_mcsp_t * L)9 int zm_mcsp_init(zm_mcsp_t *L) {
10 zm_mcs_init(&L->high_p);
11 L->go_straight = 0;
12 L->low_p_acq = 0;
13 zm_ticket_init(&L->filter);
14 zm_mcs_init(&L->low_p);
15 return 0;
16 }
17
zm_mcsp_acquire(zm_mcsp_t * L)18 int zm_mcsp_acquire(zm_mcsp_t *L) {
19 zm_mcs_acquire(L->high_p);
20 if (!L->go_straight) {
21 zm_ticket_acquire(&L->filter);
22 L->go_straight = 1;
23 }
24 return 0;
25 }
26
zm_mcsp_tryacq(zm_mcsp_t * L,int * success)27 int zm_mcsp_tryacq(zm_mcsp_t *L, int *success) {
28 zm_mcs_tryacq(L->high_p, success);
29 if (success) {
30 if (!L->go_straight) {
31 zm_ticket_tryacq(&L->filter, success);
32 if (success)
33 L->go_straight = 1;
34 else
35 zm_mcs_release(L->high_p);
36 }
37 }
38 return 0;
39 }
40
zm_mcsp_acquire_low(zm_mcsp_t * L)41 int zm_mcsp_acquire_low(zm_mcsp_t *L) {
42 zm_mcs_acquire(L->low_p);
43 zm_ticket_acquire(&L->filter);
44 L->low_p_acq = 1;
45 return 0;
46 }
47
zm_mcsp_tryacq_low(zm_mcsp_t * L,int * success)48 int zm_mcsp_tryacq_low(zm_mcsp_t *L, int *success) {
49 zm_mcs_tryacq(L->low_p, success);
50 if (success) {
51 zm_ticket_tryacq(&L->filter, success);
52 if (success)
53 L->low_p_acq = 1;
54 else
55 zm_mcs_release(L->low_p);
56 }
57 return 0;
58 }
59
zm_mcsp_release(zm_mcsp_t * L)60 int zm_mcsp_release(zm_mcsp_t *L) {
61 if (!L->low_p_acq) {
62 if (zm_mcs_nowaiters(L->high_p)) {
63 L->go_straight = 0;
64 zm_ticket_release(&L->filter);
65 }
66 zm_mcs_release(L->high_p);
67 } else {
68 L->low_p_acq = 0;
69 zm_ticket_release(&L->filter);
70 zm_mcs_release(L->low_p);
71 }
72 return 0;
73 }
74
zm_mcsp_acquire_c(zm_mcsp_t * L,zm_mcs_qnode_t * I)75 int zm_mcsp_acquire_c(zm_mcsp_t *L, zm_mcs_qnode_t* I) {
76 zm_mcs_acquire_c(L->high_p, I);
77 if (!L->go_straight) {
78 zm_ticket_acquire(&L->filter);
79 L->go_straight = 1;
80 }
81 return 0;
82 }
83
zm_mcsp_acquire_low_c(zm_mcsp_t * L,zm_mcs_qnode_t * I)84 int zm_mcsp_acquire_low_c(zm_mcsp_t *L, zm_mcs_qnode_t* I) {
85 zm_mcs_acquire_c(L->low_p, I);
86 zm_ticket_acquire(&L->filter);
87 L->low_p_acq = 1;
88 return 0;
89 }
90
zm_mcsp_release_c(zm_mcsp_t * L,zm_mcs_qnode_t * I)91 int zm_mcsp_release_c(zm_mcsp_t *L, zm_mcs_qnode_t *I) {
92 if (!L->low_p_acq) {
93 if (zm_mcs_nowaiters_c(L->high_p, I)) {
94 L->go_straight = 0;
95 zm_ticket_release(&L->filter);
96 }
97 zm_mcs_release_c(L->high_p, I);
98 } else {
99 L->low_p_acq = 0;
100 zm_ticket_release(&L->filter);
101 zm_mcs_release_c(L->low_p, I);
102 }
103 return 0;
104 }
105
zm_mcsp_destroy(zm_mcsp_t * L)106 int zm_mcsp_destroy(zm_mcsp_t *L) {
107 zm_mcs_destroy(&L->high_p);
108 zm_ticket_destroy(&L->filter);
109 zm_mcs_destroy(&L->low_p);
110 return 0;
111 }
112