/* * callout.c * * Callout.c implements callout.h. * * The initial implementation is structured for simplicity. For your assignment, * you should revise the internal data structures so that they are more time * efficient. There should be one queue per event type, and all of the queues * should be placed into a single global table. * * Also, in this implementation the callout_id_t is implemented as the address * of the callout structure. This is ok, but somewhat dangerous. You should * include machinery to isolate this implementation from malicious callers. An easy * way to do this is to introduce a level of indirection with a table of handles. * Each entry in the table corresponds to an internal callout_event_t, and the * callout_id_t which is returned is simple an index into the table. * * * HISTORY * 30-Mar-98 Brian Bershad (bershad) at the University of Washington * Created. * */ #include #include "callout.h" int done = FALSE; /* * Simple structure for maintaining callout data. For your assignment, you should * replace this structure with an array of queues */ typedef struct callout_event_data { int type; callout_event_func_t f; callout_event_closure_t cl; struct callout_event_data *next; int ncalls; } *callout_event_t; callout_event_t callout_list; callout_id_t callout_register(int type, callout_event_func_t f, callout_event_closure_t c) { callout_event_t ce = (callout_event_t)malloc(sizeof(struct callout_event_data)); if (ce) { ce->f = f; ce->cl = c; ce->type = type; ce->ncalls = 0; ce->next = callout_list; callout_list = ce; } return (callout_id_t)ce; } int callout_unregister(callout_id_t h, callout_event_closure_t *c) { printf("UNIMPLEMENTD. callout unregister called\n"); } int callout_getstats(callout_id_t h, int *numcalls) { callout_event_t ce = (callout_event_t)h; *numcalls = ce->ncalls; return TRUE; } void callout_map(callout_map_func_t mapf, callout_map_closure_t cl) { printf("UNIMPLEMENTD. callout map\n"); } void callout_boot(callout_genevent_func_t g) { int e; callout_event_t ce; /* * This code here clearly needs to change so that we can more effectively * perform the dispatch. */ while (!done) { e = (*g)(); for (ce = callout_list; ce; ce = ce->next) { if (ce->type == e) { ce->ncalls++; (*(ce->f))(e, ce, ce->cl); } } } } void callout_shutdown() { done = TRUE; }