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 osd_work_queue_free(osd_work_queue *queue) { /** * Wait until the work queue is empty. We use a special timeout value, * that we know means 'wait forever'. **/ osd_work_queue_wait(queue, 0); /** * Destroy the queue **/ osd_free(queue); /** * Now decrement the queue count, and if it has gone to zero, destroy the * work threads as there are no more work queues that need to be serviced **/ pthread_mutex_lock(&g_mutex); if (--g_queues_count == 0) { work_queue_destroy_threads_locked(); } pthread_mutex_unlock(&g_mutex); }
int osd_work_item_wait(osd_work_item *item, osd_ticks_t timeout) { /** * Just wait on the queue that this item belongs to. This is done because * MAME actually doesn't really use this method and this is the simplest * way to implement it. Providing for an implementation that can wait for * this specific item to be finished is more heavyweight and hurts the * performance of the rest of the work queue implementation. **/ return osd_work_queue_wait(item->queue, timeout); }
static void sdlwindow_sync(void) { if (multithreading_enabled) { // Fallback while (!osd_work_queue_wait(work_queue, osd_ticks_per_second()*10)) { mame_printf_warning("sdlwindow_sync: Sleeping...\n"); osd_sleep(100000); } } }
void laserdisc_device::device_stop() { // make sure all async operations have completed if (m_disc != nullptr) osd_work_queue_wait(m_work_queue, osd_ticks_per_second() * 10); // free any textures and palettes if (m_videotex != nullptr) machine().render().texture_free(m_videotex); if (m_videopalette != nullptr) m_videopalette->deref(); if (m_overtex != nullptr) machine().render().texture_free(m_overtex); }
void laserdisc_device::process_track_data() { // wait for the async operation to complete if (m_readresult == CHDERR_OPERATION_PENDING) osd_work_queue_wait(m_work_queue, osd_ticks_per_second() * 10); assert(m_readresult != CHDERR_OPERATION_PENDING); // remove the video if we had an error if (m_readresult != CHDERR_NONE) m_avhuff_config.video.reset(); // count the field as read if we are successful if (m_avhuff_config.video.valid()) { m_frame[m_videoindex].m_numfields++; player_overlay(m_avhuff_config.video); } // pass the audio to the callback if (!m_audio_callback.isnull()) m_audio_callback(*this, m_samplerate, m_audiocursamples, m_avhuff_config.audio[0], m_avhuff_config.audio[1]); // shift audio data if we read it into the beginning of the buffer if (m_audiocursamples != 0 && m_audiobufin != 0) for (int chnum = 0; chnum < 2; chnum++) if (m_avhuff_config.audio[chnum] == &m_audiobuffer[chnum][0]) { // move data to the end int samplesleft = m_audiobufsize - m_audiobufin; samplesleft = MIN(samplesleft, m_audiocursamples); memmove(&m_audiobuffer[chnum][m_audiobufin], &m_audiobuffer[chnum][0], samplesleft * 2); // shift data at the beginning if (samplesleft < m_audiocursamples) memmove(&m_audiobuffer[chnum][0], &m_audiobuffer[chnum][samplesleft], (m_audiocursamples - samplesleft) * 2); } // update the input buffer pointer m_audiobufin = (m_audiobufin + m_audiocursamples) % m_audiobufsize; }
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"); }
void poly_wait(poly_manager *poly, const char *debug_reason) { osd_ticks_t time; /* remember the start time if we're logging */ if (LOG_WAITS) time = get_profile_ticks(); /* wait for all pending work items to complete */ if (poly->queue != NULL) osd_work_queue_wait(poly->queue, osd_ticks_per_second() * 100); /* if we don't have a queue, just run the whole list now */ else { int unitnum; for (unitnum = 0; unitnum < poly->unit_next; unitnum++) poly_item_callback(poly->unit[unitnum], 0); } /* log any long waits */ if (LOG_WAITS) { time = get_profile_ticks() - time; if (time > LOG_WAIT_THRESHOLD) logerror("Poly:Waited %d cycles for %s\n", (int)time, debug_reason); } /* reset the state */ poly->polygon_next = poly->unit_next = 0; memset(poly->unit_bucket, 0xff, sizeof(poly->unit_bucket)); /* we need to preserve the last extra data that was supplied */ if (poly->extra_next > 1) memcpy(poly->extra[0], poly->extra[poly->extra_next - 1], poly->extra_size); poly->extra_next = 1; }