1#include <barrelfish/notificator.h> 2#include <barrelfish/dispatch.h> 3#include <barrelfish/dispatcher_arch.h> 4#include <barrelfish/waitset_chan.h> 5#include <include/waitset_chan_priv.h> 6 7/// Dequeue the element from the notificator queue 8// static void dequeue(struct notificator **queue, 9// struct notificator *element) 10// { 11// if (element->next == element) { 12// assert(element->prev == element); 13// assert(*queue == element); 14// *queue = NULL; 15// } else { 16// element->prev->next = element->next; 17// element->next->prev = element->prev; 18// if (*queue == element) { 19// *queue = element->next; 20// } 21// } 22// element->prev = element->next = NULL; 23// } 24 25/// Enqueue the element on the notificator queue 26static void enqueue(struct notificator **queue, 27 struct notificator *element) 28{ 29 if (*queue == NULL) { 30 *queue = element; 31 element->next = element->prev = element; 32 } else { 33 element->next = *queue; 34 element->prev = (*queue)->prev; 35 element->next->prev = element; 36 element->prev->next = element; 37 } 38} 39 40void notificator_init(struct notificator *notificator, void *object, 41 check_notification_fn_type can_read, check_notification_fn_type can_write) 42{ 43 notificator->prev = NULL; 44 notificator->next = NULL; 45 notificator->object = object; 46 notificator->can_read = can_read; 47 notificator->can_write = can_write; 48 49 waitset_chanstate_init(¬ificator->ready_to_read, CHANTYPE_OTHER); 50 notificator->ready_to_read.persistent = true; 51 waitset_chanstate_init(¬ificator->ready_to_write, CHANTYPE_OTHER); 52 notificator->ready_to_write.persistent = true; 53 54 dispatcher_handle_t handle = disp_disable(); 55 enqueue(&get_dispatcher_generic(handle)->notificators, notificator); 56 disp_enable(handle); 57} 58 59void check_notificators_disabled(dispatcher_handle_t handle) 60{ 61 struct dispatcher_generic *dp = get_dispatcher_generic(handle); 62 struct notificator *n; 63 64 if (!dp->notificators) 65 return; 66 n = dp->notificators; 67 do { 68 if (n->can_read(n->object)) { 69 if (waitset_chan_is_registered(&n->ready_to_read)) { 70 // debug_printf("triggering\n"); 71 errval_t err = waitset_chan_trigger_disabled(&n->ready_to_read, handle); 72 assert(err_is_ok(err)); // should not fail 73 } 74 } 75 if (n->can_write(n->object)) { 76 if (waitset_chan_is_registered(&n->ready_to_write)) { 77 // debug_printf("triggering\n"); 78 errval_t err = waitset_chan_trigger_disabled(&n->ready_to_write, handle); 79 assert(err_is_ok(err)); // should not fail 80 } 81 } 82 n = n->next; 83 } while (n != dp->notificators); 84} 85