Add post-and-poke synchronization to parlib
[akaros.git] / user / parlib / include / poke.h
1 /* Copyright (c) 2012 The Regents of the University of California
2  * Barret Rhoden <brho@cs.berkeley.edu>
3  * See LICENSE for details.
4  *
5  * Post work and poke synchronization.  This is a wait-free way to make sure
6  * some code is run, usually by the calling core, but potentially by any core.
7  * Under contention, everyone just posts work, and one core will carry out the
8  * work.  Callers post work (the meaning of which is particular to their
9  * subsystem), then call this function.  The function is not run concurrently
10  * with itself.
11  *
12  * As far as uthreads, vcores, and preemption go, poking is safe in uthread
13  * context and if preemptions occur.  However, a uthread running the poke
14  * function that gets preempted could delay the execution of the poke
15  * indefinitely.  In general, post-and-poke does not provide any guarantee about
16  * *when* the poke finally occurs.  If delays of this sort are a problem, then
17  * run poke() from vcore context.
18  *
19  * Adapted from the kernel's implementation. */
20
21 #ifndef PARLIB_POKE_H
22 #define PARLIB_POKE_H
23
24 #include <ros/atomic.h>
25
26 __BEGIN_DECLS
27
28 struct poke_tracker {
29         atomic_t                        need_to_run;
30         atomic_t                        run_in_progress;
31         void                            (*func)(void *);
32 };
33
34 void poke(struct poke_tracker *tracker, void *arg);
35
36 static inline void poke_init(struct poke_tracker *tracker, void (*func)(void*))
37 {
38         tracker->need_to_run = 0;
39         tracker->run_in_progress = 0;
40         tracker->func = func;
41 }
42
43 #define POKE_INITIALIZER(f) {.func = f}
44
45 __END_DECLS
46
47 #endif /* PARLIB_POKE_H */