Lines Matching +full:- +full:set
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
8 * - FREE -> SET (qemu_event_set)
9 * - BUSY -> SET (qemu_event_set)
10 * - SET -> FREE (qemu_event_reset)
11 * - FREE -> BUSY (qemu_event_wait)
14 * BUSY -> SET and FREE -> BUSY, respectively.
16 * Without futex, BUSY -> SET and FREE -> BUSY never happen. Instead, the waking
17 * operation follows FREE -> SET and the blocking operation will happen in
18 * qemu_event_wait() if the event is not SET.
20 * SET->BUSY does not happen (it can be observed from the outside but
21 * it really is SET->FREE->BUSY).
23 * busy->free provably cannot happen; to enforce it, the set->free transition
24 * is done with an OR, which becomes a no-op if the event has concurrently
30 #define EV_BUSY -1
35 pthread_mutex_init(&ev->lock, NULL); in qemu_event_init()
36 pthread_cond_init(&ev->cond, NULL); in qemu_event_init()
39 ev->value = (init ? EV_SET : EV_FREE); in qemu_event_init()
40 ev->initialized = true; in qemu_event_init()
45 assert(ev->initialized); in qemu_event_destroy()
46 ev->initialized = false; in qemu_event_destroy()
48 pthread_mutex_destroy(&ev->lock); in qemu_event_destroy()
49 pthread_cond_destroy(&ev->cond); in qemu_event_destroy()
55 assert(ev->initialized); in qemu_event_set()
62 * ev->value we need a full memory barrier here. in qemu_event_set()
65 if (qatomic_read(&ev->value) != EV_SET) { in qemu_event_set()
66 int old = qatomic_xchg(&ev->value, EV_SET); in qemu_event_set()
76 pthread_mutex_lock(&ev->lock); in qemu_event_set()
78 qatomic_store_release(&ev->value, EV_SET); in qemu_event_set()
79 pthread_cond_broadcast(&ev->cond); in qemu_event_set()
80 pthread_mutex_unlock(&ev->lock); in qemu_event_set()
86 assert(ev->initialized); in qemu_event_reset()
91 * do nothing. Otherwise change EV_SET->EV_FREE. in qemu_event_reset()
93 qatomic_or(&ev->value, EV_FREE); in qemu_event_reset()
102 * If futexes are not available, there are no EV_FREE->EV_BUSY in qemu_event_reset()
113 * ev->value = EV_SET -----> load ev->value in qemu_event_reset()
114 * ev->value = old value | EV_FREE in qemu_event_reset()
120 qatomic_set(&ev->value, qatomic_load_acquire(&ev->value) | EV_FREE); in qemu_event_reset()
126 assert(ev->initialized); in qemu_event_wait()
132 * not go down the slow path, so this load-acquire is needed that in qemu_event_wait()
135 unsigned value = qatomic_load_acquire(&ev->value); in qemu_event_wait()
144 * busy->free transition. After the CAS, the event will be either in qemu_event_wait()
145 * set or busy. in qemu_event_wait()
152 if (qatomic_cmpxchg(&ev->value, EV_FREE, EV_BUSY) == EV_SET) { in qemu_event_wait()
158 * This is the final check for a concurrent set, so it does need in qemu_event_wait()
165 pthread_mutex_lock(&ev->lock); in qemu_event_wait()
166 while (qatomic_read(&ev->value) != EV_SET) { in qemu_event_wait()
167 pthread_cond_wait(&ev->cond, &ev->lock); in qemu_event_wait()
169 pthread_mutex_unlock(&ev->lock); in qemu_event_wait()