Line data Source code
1 : /* SPDX-License-Identifier: LGPL-2.1+ */ 2 : #pragma once 3 : 4 : #include <stdbool.h> 5 : #include <stdint.h> 6 : #include <sys/types.h> 7 : 8 : #include "macro.h" 9 : 10 : /* See source file for an API description. */ 11 : 12 : typedef struct Barrier Barrier; 13 : 14 : enum { 15 : BARRIER_SINGLE = 1LL, 16 : BARRIER_ABORTION = INT64_MAX, 17 : 18 : /* bias values to store state; keep @WE < @THEY < @I */ 19 : BARRIER_BIAS = INT64_MIN, 20 : BARRIER_WE_ABORTED = BARRIER_BIAS + 1LL, 21 : BARRIER_THEY_ABORTED = BARRIER_BIAS + 2LL, 22 : BARRIER_I_ABORTED = BARRIER_BIAS + 3LL, 23 : }; 24 : 25 : enum { 26 : BARRIER_PARENT, 27 : BARRIER_CHILD, 28 : }; 29 : 30 : struct Barrier { 31 : int me; 32 : int them; 33 : int pipe[2]; 34 : int64_t barriers; 35 : }; 36 : 37 : #define BARRIER_NULL {-1, -1, {-1, -1}, 0} 38 : 39 : int barrier_create(Barrier *obj); 40 : void barrier_destroy(Barrier *b); 41 : 42 0 : DEFINE_TRIVIAL_CLEANUP_FUNC(Barrier*, barrier_destroy); 43 : 44 : void barrier_set_role(Barrier *b, unsigned role); 45 : 46 : bool barrier_place(Barrier *b); 47 : bool barrier_abort(Barrier *b); 48 : 49 : bool barrier_wait_next(Barrier *b); 50 : bool barrier_wait_abortion(Barrier *b); 51 : bool barrier_sync_next(Barrier *b); 52 : bool barrier_sync(Barrier *b); 53 : 54 0 : static inline bool barrier_i_aborted(Barrier *b) { 55 0 : return IN_SET(b->barriers, BARRIER_I_ABORTED, BARRIER_WE_ABORTED); 56 : } 57 : 58 0 : static inline bool barrier_they_aborted(Barrier *b) { 59 0 : return IN_SET(b->barriers, BARRIER_THEY_ABORTED, BARRIER_WE_ABORTED); 60 : } 61 : 62 : static inline bool barrier_we_aborted(Barrier *b) { 63 : return b->barriers == BARRIER_WE_ABORTED; 64 : } 65 : 66 0 : static inline bool barrier_is_aborted(Barrier *b) { 67 0 : return IN_SET(b->barriers, 68 : BARRIER_I_ABORTED, BARRIER_THEY_ABORTED, BARRIER_WE_ABORTED); 69 : } 70 : 71 0 : static inline bool barrier_place_and_sync(Barrier *b) { 72 0 : (void) barrier_place(b); 73 0 : return barrier_sync(b); 74 : }