watchdog::~watchdog(void) { atomic_exchange32(&m_do_exit, 1); osd_event_set(m_event); osd_thread_wait_free(m_thread); osd_event_free(m_event); }
void osd_work_queue_free(osd_work_queue *queue) { // if we have threads, clean them up if (queue->thread != NULL) { int threadnum; // stop the timer for "waittime" on the main thread if (queue->flags & WORK_QUEUE_FLAG_MULTI) { end_timing(queue->thread[queue->threads].waittime); } // signal all the threads to exit atomic_exchange32(&queue->exiting, TRUE); for (threadnum = 0; threadnum < queue->threads; threadnum++) { work_thread_info *thread = &queue->thread[threadnum]; if (thread->wakeevent != NULL) osd_event_set(thread->wakeevent); } // wait for all the threads to go away for (threadnum = 0; threadnum < queue->threads; threadnum++) { work_thread_info *thread = &queue->thread[threadnum]; // block on the thread going away, then close the handle if (thread->handle != NULL) { osd_thread_wait_free(thread->handle); } // clean up the wake event if (thread->wakeevent != NULL) osd_event_free(thread->wakeevent); } #if KEEP_STATISTICS int allocthreadnum; if (queue->flags & WORK_QUEUE_FLAG_MULTI) allocthreadnum = queue->threads + 1; else allocthreadnum = queue->threads; // output per-thread statistics for (threadnum = 0; threadnum < allocthreadnum; threadnum++) { work_thread_info *thread = &queue->thread[threadnum]; osd_ticks_t total = thread->runtime + thread->waittime + thread->spintime; printf("Thread %d: items=%9d run=%5.2f%% (%5.2f%%) spin=%5.2f%% wait/other=%5.2f%% total=%9d\n", threadnum, thread->itemsdone, (double)thread->runtime * 100.0 / (double)total, (double)thread->actruntime * 100.0 / (double)total, (double)thread->spintime * 100.0 / (double)total, (double)thread->waittime * 100.0 / (double)total, (UINT32) total); } #endif } // free the list if (queue->thread != NULL) osd_free(queue->thread); // free all the events if (queue->doneevent != NULL) osd_event_free(queue->doneevent); // free all items in the free list while (queue->free != NULL) { osd_work_item *item = (osd_work_item *)queue->free; queue->free = item->next; if (item->event != NULL) osd_event_free(item->event); osd_free(item); } // free all items in the active list while (queue->list != NULL) { osd_work_item *item = (osd_work_item *)queue->list; queue->list = item->next; if (item->event != NULL) osd_event_free(item->event); osd_free(item); } #if KEEP_STATISTICS printf("Items queued = %9d\n", queue->itemsqueued); printf("SetEvent calls = %9d\n", queue->setevents); printf("Extra items = %9d\n", queue->extraitems); printf("Spin loops = %9d\n", queue->spinloops); #endif osd_scalable_lock_free(queue->lock); // free the queue itself osd_free(queue); }