void cache_entry_destroy (void *arg) { struct cache_entry *hp = arg; if (hp) { if (hp->o) json_object_put (hp->o); if (hp->waitlist) wait_queue_destroy (hp->waitlist); free (hp); } }
/** * @brief Destroy an event object. * * Event's resources are freed and it may no longer be * used until event_init() is called again. Any threads * still waiting on the event will be resumed. * * @param e Event object to initialize */ void event_destroy(event_t *e) { enter_critical_section(); #if EVENT_CHECK ASSERT(e->magic == EVENT_MAGIC); #endif e->magic = 0; e->signalled = false; e->flags = 0; wait_queue_destroy(&e->wait, true); exit_critical_section(); }
/** * @brief Destroy a mutex_t * * This function frees any resources that were allocated * in mutex_init(). The mutex_t object itself is not freed. */ void mutex_destroy(mutex_t *m) { enter_critical_section(); #if MUTEX_CHECK ASSERT(m->magic == MUTEX_MAGIC); m->magic = 0; if (m->holder != 0 && current_thread != m->holder) panic("mutex_destroy: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n", current_thread, current_thread->name, m, m->holder, m->holder->name); #endif m->count = 0; wait_queue_destroy(&m->wait, true); exit_critical_section(); }
void test_wakeup(int all) { Tid ret; long ii; static Tid child[NTHREADS]; unintr_printf("starting wakeup test\n"); done = 0; queue = wait_queue_create(); assert(queue); /* initial thread sleep and wake up tests */ ret = thread_sleep(NULL); assert(ret == THREAD_INVALID); unintr_printf("initial thread returns from sleep(NULL)\n"); ret = thread_sleep(queue); assert(ret == THREAD_NONE); unintr_printf("initial thread returns from sleep(NONE)\n"); ret = thread_wakeup(NULL, 0); assert(ret == 0); ret = thread_wakeup(queue, 1); assert(ret == 0); /* create all threads */ for (ii = 0; ii < NTHREADS; ii++) { child[ii] = thread_create((void (*)(void *))test_wakeup_thread, (void *)ii); assert(thread_ret_ok(child[ii])); } while (__sync_fetch_and_add(&done, 0) < NTHREADS) { /* spin for 5 ms */ spin(5000); /* this requires that thread_wakeup is working correctly */ ret = thread_wakeup(queue, all); assert(ret >= 0); assert(all ? ret <= NTHREADS : ret <= 1); } wait_queue_destroy(queue); unintr_printf("wakeup test done\n"); }
void test_wakeup(int all) { Tid ret; long ii; static Tid child[NTHREADS]; unintr_printf("starting wakeup test\n"); done = 0; nr_sleeping = 0; queue = wait_queue_create(); assert(queue); /* initial thread sleep and wake up tests */ ret = thread_sleep(NULL); assert(ret == THREAD_INVALID); unintr_printf("initial thread returns from sleep(NULL)\n"); ret = thread_sleep(queue); assert(ret == THREAD_NONE); unintr_printf("initial thread returns from sleep(NONE)\n"); ret = thread_wakeup(NULL, 0); assert(ret == 0); ret = thread_wakeup(queue, 1); assert(ret == 0); /* create all threads */ for (ii = 0; ii < NTHREADS; ii++) { child[ii] = thread_create((void (*)(void *))test_wakeup_thread, (void *)ii); assert(thread_ret_ok(child[ii])); } out: while (__sync_fetch_and_add(&done, 0) < NTHREADS) { if (all) { /* wait until all threads have slept */ if (__sync_fetch_and_add(&nr_sleeping, 0) < NTHREADS) { goto out; } /* we will wake up all threads in the thread_wakeup * call below so set nr_sleeping to 0 */ nr_sleeping = 0; } else { /* wait until at least one thread has slept */ if (__sync_fetch_and_add(&nr_sleeping, 0) < 1) { goto out; } /* wake up one thread in the wakeup call below */ __sync_fetch_and_add(&nr_sleeping, -1); } /* spin for 5 ms. this allows testing that the sleeping thread * sleeps for at least 5 ms. */ spin(5000); /* tests thread_wakeup */ assert(interrupts_enabled()); ret = thread_wakeup(queue, all); assert(interrupts_enabled()); assert(ret >= 0); assert(all ? ret == NTHREADS : ret == 1); } /* we expect nr_sleeping is 0 at this point */ assert(nr_sleeping == 0); assert(interrupts_enabled()); wait_queue_destroy(queue); unintr_printf("wakeup test done\n"); }
void cv_destroy(struct cv *cv) { assert(cv != NULL); wait_queue_destroy(cv->queue); free(cv); }
void lock_destroy(struct lock *lock) { assert(lock != NULL); wait_queue_destroy(lock->queue); free(lock); }
int main (int argc, char *argv[]) { waitqueue_t *q; waitqueue_t *q2; wait_t *w; flux_msg_t *msg; int count = 0; int i; plan (NO_PLAN); q = wait_queue_create (); q2 = wait_queue_create (); ok (q && q2, "wait_queue_create works"); ok (wait_queue_length (q) == 0 && wait_queue_length (q2) == 0, "wait_queue_length on brandnew waitqueue_t returns zero"); msg = flux_msg_create (FLUX_MSGTYPE_REQUEST); ok (msg != NULL, "flux_msg_create works"); w = wait_create (NULL, NULL, msg, msghand, &count); ok (w != NULL, "wait_create works"); flux_msg_destroy (msg); wait_addqueue (q, w); wait_addqueue (q2, w); ok (wait_queue_length (q) == 1 && wait_queue_length (q2) == 1, "wait_addqueue can add wait_t to a two queues"); wait_runqueue (q); ok (wait_queue_length (q) == 0 && wait_queue_length (q2) == 1, "wait_runqueue dequeued wait_t from first queue"); wait_runqueue (q2); ok (wait_queue_length (q) == 0 && wait_queue_length (q2) == 0, "wait_runqueue dequeued wait_t from second queue"); ok (count == 1, "wait_runqueue ran the wait_t once"); for (i = 0; i < 20; i++) { char *s = xasprintf ("%d", i); msg = flux_msg_create (FLUX_MSGTYPE_REQUEST); if (!msg) break; if (flux_msg_enable_route (msg) < 0 || flux_msg_push_route (msg, s) < 0) break; w = wait_create (NULL, NULL, msg, msghand, &count); if (!w) break; wait_addqueue (q, w); free (s); } ok (wait_queue_length (q) == 20, "wait_addqueue 20x works"); wait_destroy_match (q, msgcmp, NULL); ok (wait_queue_length (q) == 17, "wait_destroy_match on sender works"); wait_destroy_match (q, msgcmp2, NULL); ok (wait_queue_length (q) == 0, "all-match wait_destroy_match works"); wait_queue_destroy (q); wait_queue_destroy (q2); done_testing (); return (0); }