ARGOBOTS  dce6e727ffc4ca5b3ffc04cb9517c6689be51ec5
abtd_futex.h
Go to the documentation of this file.
1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
2 /*
3  * See COPYRIGHT in top-level directory.
4  */
5 
6 #ifndef ABTD_FUTEX_H_INCLUDED
7 #define ABTD_FUTEX_H_INCLUDED
8 
9 #ifndef ABT_CONFIG_ACTIVE_WAIT_POLICY
10 
11 /* ABTD_futex_multiple supports a wait-broadcast pattern. ABTD_futex_multiple
12  * allows multiple waiters. */
13 typedef struct ABTD_futex_multiple ABTD_futex_multiple;
14 
15 /* Initialize ABTD_futex_multiple. */
16 static inline void ABTD_futex_multiple_init(ABTD_futex_multiple *p_futex);
17 
18 /* This routine unlocks p_lock and makes the underlying Pthread block on
19  * p_futex. Broadcast can wake up this waiter. Spurious wakeup does not
20  * happen. */
21 void ABTD_futex_wait_and_unlock(ABTD_futex_multiple *p_futex,
22  ABTD_spinlock *p_lock);
23 
24 /* This routine unlocks p_lock and makes the underlying Pthread block on
25  * p_futex. Broadcast can wake up this waiter. By nature, spurious wakeup
26  * might happen, so the caller needs to check the current time if necessary. */
27 void ABTD_futex_timedwait_and_unlock(ABTD_futex_multiple *p_futex,
28  ABTD_spinlock *p_lock,
29  double wait_time_sec);
30 
31 /* This routine wakes up waiters that are waiting on p_futex. This function
32  * must be called when a lock (p_lock above) is taken. */
33 void ABTD_futex_broadcast(ABTD_futex_multiple *p_futex);
34 
35 /* ABTD_futex_single supports a suspend-resume pattern. ABTD_futex_single
36  * allows only a single waiter. */
37 typedef struct ABTD_futex_single ABTD_futex_single;
38 
39 /* Initialize ABTD_futex_single. */
40 static inline void ABTD_futex_single_init(ABTD_futex_single *p_futex);
41 
42 /* This routine suspends the underlying Pthread. Only one thread can suspend
43  * on a single p_futex. This suspended thread must be woken up by
44  * ABTD_futex_resume(). Spurious wakeup does not happen.
45  *
46  * p_futex must be new; it may not have been used after initialization. */
47 void ABTD_futex_suspend(ABTD_futex_single *p_futex);
48 
49 /* This routine wakes up a Pthread suspended by ABTD_futex_suspend(). This
50  * routine blocks if no Pthread is waiting on p_futex. */
51 void ABTD_futex_resume(ABTD_futex_single *p_futex);
52 
53 #ifdef ABT_CONFIG_USE_LINUX_FUTEX
54 
55 struct ABTD_futex_multiple {
56  ABTD_atomic_int val;
57 };
58 
59 static inline void ABTD_futex_multiple_init(ABTD_futex_multiple *p_futex)
60 {
61  ABTD_atomic_relaxed_store_int(&p_futex->val, 0);
62 }
63 
64 struct ABTD_futex_single {
65  ABTD_atomic_int val;
66 };
67 
68 static inline void ABTD_futex_single_init(ABTD_futex_single *p_futex)
69 {
70  ABTD_atomic_relaxed_store_int(&p_futex->val, 0);
71 }
72 
73 #else /* ABT_CONFIG_USE_LINUX_FUTEX */
74 
75 struct ABTD_futex_multiple {
76  void *p_next; /* pthread_sync */
77 };
78 
79 static inline void ABTD_futex_multiple_init(ABTD_futex_multiple *p_futex)
80 {
81  p_futex->p_next = NULL;
82 }
83 
84 struct ABTD_futex_single {
85  ABTD_atomic_ptr p_sync_obj;
86 };
87 
88 static inline void ABTD_futex_single_init(ABTD_futex_single *p_futex)
89 {
90  ABTD_atomic_relaxed_store_ptr(&p_futex->p_sync_obj, NULL);
91 }
92 
93 #endif /* !ABT_CONFIG_USE_LINUX_FUTEX */
94 
95 #endif /* !ABT_CONFIG_ACTIVE_WAIT_POLICY */
96 
97 #endif /* ABTD_FUTEX_H_INCLUDED */