void poly_free(poly_manager *poly) { #if KEEP_STATISTICS { int i, conflicts = 0, resolved = 0; for (i = 0; i < ARRAY_LENGTH(poly->conflicts); i++) { conflicts += poly->conflicts[i]; resolved += poly->resolved[i]; } printf("Total triangles = %d\n", poly->triangles); printf("Total quads = %d\n", poly->quads); if (poly->pixels > 1000000000) printf("Total pixels = %d%09d\n", (UINT32)(poly->pixels / 1000000000), (UINT32)(poly->pixels % 1000000000)); else printf("Total pixels = %d\n", (UINT32)poly->pixels); printf("Conflicts: %d resolved, %d total\n", resolved, conflicts); printf("Units: %5d used, %5d allocated, %5d waits, %4d bytes each, %7d total\n", poly->unit_max, poly->unit_count, poly->unit_waits, poly->unit_size, poly->unit_count * poly->unit_size); printf("Polygons: %5d used, %5d allocated, %5d waits, %4d bytes each, %7d total\n", poly->polygon_max, poly->polygon_count, poly->polygon_waits, poly->polygon_size, poly->polygon_count * poly->polygon_size); printf("Extra data: %5d used, %5d allocated, %5d waits, %4d bytes each, %7d total\n", poly->extra_max, poly->extra_count, poly->extra_waits, poly->extra_size, poly->extra_count * poly->extra_size); } #endif /* free the work queue */ if (poly->queue != NULL) osd_work_queue_free(poly->queue); }
static void sdlwindow_exit(running_machine &machine) { ASSERT_MAIN_THREAD(); mame_printf_verbose("Enter sdlwindow_exit\n"); // free all the windows while (sdl_window_list != NULL) { sdl_window_info *temp = sdl_window_list; sdl_window_list = temp->next; sdlwindow_video_window_destroy(machine, temp); } // if we're multithreaded, clean up the window thread if (multithreading_enabled) { sdlwindow_sync(); } // kill the drawers (*draw.exit)(); execute_async_wait(&sdlwindow_exit_wt, NULL); if (multithreading_enabled) { osd_work_queue_wait(work_queue, 1000000); osd_work_queue_free(work_queue); } mame_printf_verbose("Leave sdlwindow_exit\n"); }
void sdl_osd_interface::window_exit() { worker_param wp_dummy; ASSERT_MAIN_THREAD(); osd_printf_verbose("Enter sdlwindow_exit\n"); // free all the windows while (sdl_window_list != NULL) { sdl_window_info *temp = sdl_window_list; sdl_window_list = temp->m_next; temp->destroy(); // free the window itself global_free(temp); } // if we're multithreaded, clean up the window thread if (multithreading_enabled) { sdlwindow_sync(); } // kill the drawers (*draw.exit)(); execute_async_wait(&sdlwindow_exit_wt, wp_dummy); if (multithreading_enabled) { osd_work_queue_wait(work_queue, 1000000); osd_work_queue_free(work_queue); } osd_printf_verbose("Leave sdlwindow_exit\n"); }
osd_work_queue *osd_work_queue_alloc(int flags) { int threadnum; int numprocs = effective_num_processors(); osd_work_queue *queue; int osdthreadnum = 0; int allocthreadnum; char *osdworkqueuemaxthreads = osd_getenv(ENV_WORKQUEUEMAXTHREADS); // allocate a new queue queue = (osd_work_queue *)osd_malloc(sizeof(*queue)); if (queue == NULL) goto error; memset(queue, 0, sizeof(*queue)); // initialize basic queue members queue->tailptr = (osd_work_item **)&queue->list; queue->flags = flags; // allocate events for the queue queue->doneevent = osd_event_alloc(TRUE, TRUE); // manual reset, signalled if (queue->doneevent == NULL) goto error; // initialize the critical section queue->lock = osd_scalable_lock_alloc(); if (queue->lock == NULL) goto error; // determine how many threads to create... // on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else if (numprocs == 1) threadnum = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0; // on an n-CPU system, create n-1 threads for multi queues, and 1 thread for everything else else threadnum = (flags & WORK_QUEUE_FLAG_MULTI) ? (numprocs - 1) : 1; if (osdworkqueuemaxthreads != NULL && sscanf(osdworkqueuemaxthreads, "%d", &osdthreadnum) == 1 && threadnum > osdthreadnum) threadnum = osdthreadnum; // clamp to the maximum queue->threads = MIN(threadnum, WORK_MAX_THREADS); // allocate memory for thread array (+1 to count the calling thread if WORK_QUEUE_FLAG_MULTI) if (flags & WORK_QUEUE_FLAG_MULTI) allocthreadnum = queue->threads + 1; else allocthreadnum = queue->threads; #if KEEP_STATISTICS printf("osdprocs: %d effecprocs: %d threads: %d allocthreads: %d osdthreads: %d maxthreads: %d queuethreads: %d\n", osd_num_processors, numprocs, threadnum, allocthreadnum, osdthreadnum, WORK_MAX_THREADS, queue->threads); #endif queue->thread = (work_thread_info *)osd_malloc_array(allocthreadnum * sizeof(queue->thread[0])); if (queue->thread == NULL) goto error; memset(queue->thread, 0, allocthreadnum * sizeof(queue->thread[0])); // iterate over threads for (threadnum = 0; threadnum < queue->threads; threadnum++) { work_thread_info *thread = &queue->thread[threadnum]; // set a pointer back to the queue thread->queue = queue; // create the per-thread wake event thread->wakeevent = osd_event_alloc(FALSE, FALSE); // auto-reset, not signalled if (thread->wakeevent == NULL) goto error; // create the thread thread->handle = osd_thread_create(worker_thread_entry, thread); if (thread->handle == NULL) goto error; // set its priority: I/O threads get high priority because they are assumed to be // blocked most of the time; other threads just match the creator's priority if (flags & WORK_QUEUE_FLAG_IO) osd_thread_adjust_priority(thread->handle, 1); else osd_thread_adjust_priority(thread->handle, 0); } // start a timer going for "waittime" on the main thread if (flags & WORK_QUEUE_FLAG_MULTI) { begin_timing(queue->thread[queue->threads].waittime); } return queue; error: osd_work_queue_free(queue); return NULL; }
osd_work_queue *osd_work_queue_alloc(int flags) { int numprocs = effective_num_processors(); osd_work_queue *queue; int threadnum; // allocate a new queue queue = malloc(sizeof(*queue)); if (queue == NULL) goto error; memset(queue, 0, sizeof(*queue)); // initialize basic queue members queue->tailptr = (osd_work_item **)&queue->list; queue->flags = flags; // allocate events for the queue queue->doneevent = CreateEvent(NULL, TRUE, TRUE, NULL); // manual reset, signalled if (queue->doneevent == NULL) goto error; // initialize the critical section scalable_lock_init(&queue->lock); // determine how many threads to create... // on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else if (numprocs == 1) queue->threads = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0; // on an n-CPU system, create (n-1) threads for multi queues, and 1 thread for everything else else queue->threads = (flags & WORK_QUEUE_FLAG_MULTI) ? (numprocs - 1) : 1; // clamp to the maximum queue->threads = MIN(queue->threads, WORK_MAX_THREADS); // allocate memory for thread array (+1 to count the calling thread) queue->thread = malloc((queue->threads + 1) * sizeof(queue->thread[0])); if (queue->thread == NULL) goto error; memset(queue->thread, 0, (queue->threads + 1) * sizeof(queue->thread[0])); // iterate over threads for (threadnum = 0; threadnum < queue->threads; threadnum++) { work_thread_info *thread = &queue->thread[threadnum]; uintptr_t handle; // set a pointer back to the queue thread->queue = queue; // create the per-thread wake event thread->wakeevent = CreateEvent(NULL, FALSE, FALSE, NULL); // auto-reset, not signalled if (thread->wakeevent == NULL) goto error; // create the thread handle = _beginthreadex(NULL, 0, worker_thread_entry, thread, 0, NULL); thread->handle = (HANDLE)handle; if (thread->handle == NULL) goto error; // set its priority: I/O threads get high priority because they are assumed to be // blocked most of the time; other threads just match the creator's priority if (flags & WORK_QUEUE_FLAG_IO) SetThreadPriority(thread->handle, THREAD_PRIORITY_ABOVE_NORMAL); else SetThreadPriority(thread->handle, GetThreadPriority(GetCurrentThread())); } // start a timer going for "waittime" on the main thread begin_timing(queue->thread[queue->threads].waittime); return queue; error: osd_work_queue_free(queue); return NULL; }
osd_work_queue *osd_work_queue_alloc(int flags) { int numprocs = effective_num_processors(); osd_work_queue *queue; int threadnum; // allocate a new queue queue = (osd_work_queue *)osd_malloc(sizeof(*queue)); if (queue == NULL) goto error; memset(queue, 0, sizeof(*queue)); // initialize basic queue members queue->tailptr = (osd_work_item **)&queue->list; queue->flags = flags; // allocate events for the queue queue->doneevent = osd_event_alloc(TRUE, TRUE); // manual reset, signalled if (queue->doneevent == NULL) goto error; // initialize the critical section queue->lock = osd_scalable_lock_alloc(); if (queue->lock == NULL) goto error; // determine how many threads to create... // on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else if (numprocs == 1) queue->threads = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0; // on an n-CPU system, create (n-1) threads for multi queues, and 1 thread for everything else else queue->threads = (flags & WORK_QUEUE_FLAG_MULTI) ? (numprocs - 1) : 1; // clamp to the maximum queue->threads = MIN(queue->threads, WORK_MAX_THREADS); // allocate memory for thread array (+1 to count the calling thread) queue->thread = (work_thread_info *)osd_malloc_array((queue->threads + 1) * sizeof(queue->thread[0])); if (queue->thread == NULL) goto error; memset(queue->thread, 0, (queue->threads + 1) * sizeof(queue->thread[0])); // iterate over threads for (threadnum = 0; threadnum < queue->threads; threadnum++) { work_thread_info *thread = &queue->thread[threadnum]; // set a pointer back to the queue thread->queue = queue; // create the per-thread wake event thread->wakeevent = osd_event_alloc(FALSE, FALSE); // auto-reset, not signalled if (thread->wakeevent == NULL) goto error; // create the thread thread->handle = osd_thread_create(worker_thread_entry, thread); if (thread->handle == NULL) goto error; // set its priority: I/O threads get high priority because they are assumed to be // blocked most of the time; other threads just match the creator's priority if (flags & WORK_QUEUE_FLAG_IO) osd_thread_adjust_priority(thread->handle, 1); else osd_thread_adjust_priority(thread->handle, 0); // Bind main thread to cpu 0 osd_thread_cpu_affinity(NULL, effective_cpu_mask(0)); if (flags & WORK_QUEUE_FLAG_IO) osd_thread_cpu_affinity(thread->handle, effective_cpu_mask(1)); else osd_thread_cpu_affinity(thread->handle, effective_cpu_mask(2+threadnum) ); } // start a timer going for "waittime" on the main thread begin_timing(queue->thread[queue->threads].waittime); return queue; error: osd_work_queue_free(queue); return NULL; }
osd_work_queue *osd_work_queue_alloc(int flags) { int threadnum; int numprocs = effective_num_processors(); osd_work_queue *queue; int osdthreadnum = 0; int allocthreadnum; const char *osdworkqueuemaxthreads = osd_getenv(ENV_WORKQUEUEMAXTHREADS); // allocate a new queue queue = new osd_work_queue(); // initialize basic queue members queue->tailptr = (osd_work_item **)&queue->list; queue->flags = flags; // determine how many threads to create... // on a single-CPU system, create 1 thread for I/O queues, and 0 threads for everything else if (numprocs == 1) threadnum = (flags & WORK_QUEUE_FLAG_IO) ? 1 : 0; // on an n-CPU system, create n-1 threads for multi queues, and 1 thread for everything else else threadnum = (flags & WORK_QUEUE_FLAG_MULTI) ? (numprocs - 1) : 1; if (osdworkqueuemaxthreads != nullptr && sscanf(osdworkqueuemaxthreads, "%d", &osdthreadnum) == 1 && threadnum > osdthreadnum) threadnum = osdthreadnum; // clamp to the maximum queue->threads = MIN(threadnum, WORK_MAX_THREADS); // allocate memory for thread array (+1 to count the calling thread if WORK_QUEUE_FLAG_MULTI) if (flags & WORK_QUEUE_FLAG_MULTI) allocthreadnum = queue->threads + 1; else allocthreadnum = queue->threads; #if KEEP_STATISTICS printf("osdprocs: %d effecprocs: %d threads: %d allocthreads: %d osdthreads: %d maxthreads: %d queuethreads: %d\n", osd_num_processors, numprocs, threadnum, allocthreadnum, osdthreadnum, WORK_MAX_THREADS, queue->threads); #endif for (threadnum = 0; threadnum < allocthreadnum; threadnum++) queue->thread.push_back(new work_thread_info(threadnum, *queue)); // iterate over threads for (threadnum = 0; threadnum < queue->threads; threadnum++) { work_thread_info *thread = queue->thread[threadnum]; // create the thread thread->handle = new std::thread(worker_thread_entry, thread); if (thread->handle == nullptr) goto error; // set its priority: I/O threads get high priority because they are assumed to be // blocked most of the time; other threads just match the creator's priority if (flags & WORK_QUEUE_FLAG_IO) thread_adjust_priority(thread->handle, 1); else thread_adjust_priority(thread->handle, 0); } // start a timer going for "waittime" on the main thread if (flags & WORK_QUEUE_FLAG_MULTI) { begin_timing(queue->thread[queue->threads]->waittime); } return queue; error: osd_work_queue_free(queue); return nullptr; }
laserdisc_device::~laserdisc_device() { osd_work_queue_free(m_work_queue); }