| /* Copyright (c) 2012 The Regents of the University of California |
| * Barret Rhoden <brho@cs.berkeley.edu> |
| * See LICENSE for details. |
| * |
| * Post work and poke synchronization. This is a wait-free way to make sure |
| * some code is run, usually by the calling core, but potentially by any core. |
| * Under contention, everyone just posts work, and one core will carry out the |
| * work. Callers post work (the meaning of which is particular to their |
| * subsystem), then call this function. The function is not run concurrently |
| * with itself. |
| * |
| * As far as uthreads, vcores, and preemption go, poking is safe in uthread |
| * context and if preemptions occur. However, a uthread running the poke |
| * function that gets preempted could delay the execution of the poke |
| * indefinitely. In general, post-and-poke does not provide any guarantee about |
| * *when* the poke finally occurs. If delays of this sort are a problem, then |
| * run poke() from vcore context. |
| * |
| * Adapted from the kernel's implementation. */ |
| |
| #pragma once |
| |
| #include <ros/atomic.h> |
| |
| __BEGIN_DECLS |
| |
| struct poke_tracker { |
| atomic_t need_to_run; |
| atomic_t run_in_progress; |
| void (*func)(void *); |
| }; |
| |
| void poke(struct poke_tracker *tracker, void *arg); |
| |
| static inline void poke_init(struct poke_tracker *tracker, void (*func)(void*)) |
| { |
| tracker->need_to_run = 0; |
| tracker->run_in_progress = 0; |
| tracker->func = func; |
| } |
| |
| #define POKE_INITIALIZER(f) {.func = f} |
| |
| __END_DECLS |