static int sdl_write_buffer_m(unsigned char* data, int len) { SDL_LockMutex(sound_mutex); #if 0 while(BUFFSIZE - buffered_bytes < len) SDL_CondWait(sound_cv, sound_mutex); if(buf_write_pos + len <= BUFFSIZE ) { memcpy(buffer + buf_write_pos, data, len); } else { int tail = BUFFSIZE - buf_write_pos; memcpy(buffer + buf_write_pos, data, tail); memcpy(buffer, data + tail, len - tail); } buf_write_pos = (buf_write_pos + len) % BUFFSIZE; buffered_bytes += len; #else for(int i = 0; i < len; i += 4) { while(buffered_bytes == BUFFSIZE) SDL_CondWait(sound_cv, sound_mutex); *(int*)((char*)(buffer + buf_write_pos)) = *(int*)((char*)(data + i)); //memcpy(buffer + buf_write_pos, data + i, 4); buf_write_pos = (buf_write_pos + 4) % BUFFSIZE; buffered_bytes += 4; } #endif SDL_CondSignal(sound_cv); SDL_UnlockMutex(sound_mutex); return len; }
bool task_wait(Task *task, void **result) { bool success = false; if(task == NULL) { return success; } void *_result = NULL; SDL_LockMutex(task->mutex); if(task->status == TASK_CANCELLED) { success = false; } else if(task->status == TASK_FINISHED) { success = true; _result = task->result; } else { SDL_CondWait(task->cond, task->mutex); _result = task->result; success = (task->status == TASK_FINISHED); } SDL_UnlockMutex(task->mutex); if(success && result != NULL) { *result = _result; } return success; }
/* =============== GLimp_RendererSleep =============== */ void *GLimp_RendererSleep() { void *data = nullptr; GLimp_SetCurrentContext( false ); SDL_LockMutex( smpMutex ); { smpData = nullptr; smpDataReady = false; // after this, the front end can exit GLimp_FrontEndSleep SDL_CondSignal( renderCompletedEvent ); while ( !smpDataReady ) { SDL_CondWait( renderCommandsEvent, smpMutex ); } data = ( void * ) smpData; } SDL_UnlockMutex( smpMutex ); GLimp_SetCurrentContext( true ); return data; }
bool ThreadPool::waitAll() { SDL_mutexP(mutex); while(usedThreads.size() > 0) { warnings << "ThreadPool: waiting for " << usedThreads.size() << " threads to finish:" << endl; for(std::set<ThreadPoolItem*>::iterator i = usedThreads.begin(); i != usedThreads.end(); ++i) { if((*i)->working && (*i)->finished) { warnings << " thread " << (*i)->name << " is ready but was not cleaned up" << endl; (*i)->working = false; SDL_CondSignal((*i)->readyForNewWork); } else if((*i)->working && !(*i)->finished) { warnings << " thread " << (*i)->name << " is still working" << endl; } else if(!(*i)->working && !(*i)->headless && (*i)->finished) { warnings << " thread " << (*i)->name << " is cleaning itself up right now" << endl; } else { warnings << " thread " << (*i)->name << " is in an invalid state" << endl; } } SDL_CondWait(threadStatusChanged, mutex); } SDL_mutexV(mutex); return true; }
static int SimulationThread(void *unused) { dAllocateODEDataForThread(dAllocateFlagCollisionData); if (SDL_SetThreadPriority(SDL_THREAD_PRIORITY_HIGH)) { //SDL_perror("SDL_SetThreadPriority"); } while (!Quit) { if (SDL_LockMutex(Mutex)) { SDL_perror("SDL_LockMutex"); break; } if (SDL_CondWait(Cond, Mutex)) { SDL_perror("SDL_CondWait"); break; } PushEvent(UPDATE); dSpaceCollide(Space, 0, &Near); dWorldStep(World, Step); dJointGroupEmpty(Group); SDL_UnlockMutex(Mutex); } dCleanupODEAllDataForThread(); return 0; }
void update_debugger(uint32 pc) // Update debugger state and display. // Should be called after each R4300 instruction // Checks for breakpoint hits on PC { int bpt; if(run==2) { bpt = check_breakpoints(pc); if( bpt==-1 ) { //previousPC = pc; return; } else { run = 0; switch_button_to_run(); if(BPT_CHECK_FLAG(g_Breakpoints[bpt], BPT_FLAG_LOG)) log_breakpoint(pc, BPT_FLAG_EXEC, 0); } } else if ( previousPC == pc ) { return; } if(run==0) { update_debugger_frontend( pc ); // Emulation thread is blocked until a button is clicked. SDL_mutexP(mutex); SDL_CondWait(debugger_done_cond, mutex); SDL_mutexV(mutex); } previousPC = pc; }
int DRThread::Thread(void* data) { DRThread* t = static_cast<DRThread*>(data); while(SDL_SemTryWait(t->semaphore)==SDL_MUTEX_TIMEDOUT) { if(t->exitCalled) return 0; // Lock work mutex t->lock(); int status = SDL_CondWait(t->condition, t->mutex); if(t->exitCalled) return 0; if( status == 0) { int ret = t->ThreadFunction(); t->unlock(); if(ret) { DREngineLog.writeToLog("error-code: %d", ret); LOG_ERROR("error in user defined thread, exit thread", -2); } } else { //unlock mutex and exit t->unlock(); LOG_ERROR("Fehler in Thread, exit", -1); } } return 0; }
void update_debugger(uint32 pc) // Update debugger state and display. // Should be called after each R4300 instruction // Checks for breakpoint hits on PC { int bpt; if(run!=0) {//check if we hit a breakpoint bpt = check_breakpoints(pc); if( bpt!=-1 ) { run = 0; if(BPT_CHECK_FLAG(g_Breakpoints[bpt], BPT_FLAG_LOG)) log_breakpoint(pc, BPT_FLAG_EXEC, 0); } } if(run!=2) { DebuggerCallback(DEBUG_UI_UPDATE, pc); /* call front-end to notify user interface to update */ } if(run==0) { // Emulation thread is blocked until a button is clicked. SDL_mutexP(mutex); SDL_CondWait(debugger_done_cond, mutex); SDL_mutexV(mutex); } previousPC = pc; }
/* Drawing runs on separate thread, so as soon as one image is drawn to the * screen, the next can be computed in the background. This way, typical * image changes won't need to wait for drawing computations, which can be * slow when generating large images using floating point. */ static int drawing_main(void *param) { int displayed_img; int draw_img = (flags & DRAW_LOGO) ? -1 : imageFuncList[imageFuncListIndex]; displayed_img = draw_img; while (1) { /* Draw next image to back buffer */ draw(draw_img); /* Tell main thread that image is drawn */ SDL_LockMutex(draw_mtx); drawdone = SDL_TRUE; SDL_CondSignal(drawdone_cond); /* Wait for next image */ while (!drawnext) { SDL_CondWait(drawnext_cond, draw_mtx); } drawnext = SDL_FALSE; SDL_UnlockMutex(draw_mtx); if (quit_draw) break; if (redraw_same) { draw_img = displayed_img; redraw_same = 0; } else { /* move to the next image */ draw_advance(); displayed_img = draw_img; draw_img = imageFuncList[imageFuncListIndex]; } } return 0; }
void FrameExporter::dumpThr() { SDL_mutexP(mutex); while(dumper_thread_state != FRAME_EXPORTER_EXIT) { dumper_thread_state = FRAME_EXPORTER_WAIT; while (dumper_thread_state == FRAME_EXPORTER_WAIT) { SDL_CondWait(cond, mutex); } if (dumper_thread_state == FRAME_EXPORTER_EXIT) break; if (pixels_shared_ptr != 0) { //invert image for(int y=0;y<display.height;y++) { for(int x=0;x<rowstride;x++) { pixels_out[x + y * rowstride] = pixels_shared_ptr[x + (display.height - y - 1) * rowstride]; } } dumpImpl(); } } dumper_thread_state = FRAME_EXPORTER_STOPPED; SDL_mutexV(mutex); }
/** * Dequeue * * @param p the PacketQueue * @param pkt the head AVPacket * @param block whether block the calling thread */ static int packet_queue_get(PacketQueue *q, AVPacket *pkt, int block) { AVPacketList *pkt1; int ret; SDL_LockMutex(q->mutex); for(;;) { if(quit) { ret = -1; break; } pkt1 = q->first_pkt; if (pkt1) { q->first_pkt = pkt1->next; if (!q->first_pkt) q->last_pkt = NULL; q->nb_packets--; q->size -= pkt1->pkt.size; *pkt = pkt1->pkt; av_free(pkt1); ret = 1; break; } else if (!block) { ret = 0; break; } else { SDL_CondWait(q->cond, q->mutex); } } SDL_UnlockMutex(q->mutex); return ret; }
void Event::wait(void) { SDL_LockMutex(mut); while(!triggered) SDL_CondWait(cond, mut); SDL_UnlockMutex(mut); }
static void audio_callback(void *userdata, Uint8 *stream, int len) { struct ao *ao = userdata; struct priv *priv = ao->priv; SDL_LockMutex(priv->buffer_mutex); #ifdef ESTIMATE_DELAY priv->callback_time1 = priv->callback_time0; priv->callback_time0 = mp_time_us(); #endif while (len > 0 && !priv->paused) { int got = av_fifo_size(priv->buffer); if (got > len) got = len; if (got > 0) { av_fifo_generic_read(priv->buffer, stream, got, NULL); len -= got; stream += got; } if (len > 0) SDL_CondWait(priv->underrun_cond, priv->buffer_mutex); } SDL_UnlockMutex(priv->buffer_mutex); }
bool Conditional::wait(Mutex* mutex, int timeout) { if (timeout < 0) return !SDL_CondWait(cond, mutex->mutex); else return (SDL_CondWaitTimeout(cond, mutex->mutex, timeout) == 0); }
void OPL_Delay(uint64_t us) { delay_data_t delay_data; if (driver == NULL) { return; } // Create a callback that will signal this thread after the // specified time. delay_data.finished = 0; delay_data.mutex = SDL_CreateMutex(); delay_data.cond = SDL_CreateCond(); OPL_SetCallback(us, DelayCallback, &delay_data); // Wait until the callback is invoked. SDL_LockMutex(delay_data.mutex); while (!delay_data.finished) { SDL_CondWait(delay_data.cond, delay_data.mutex); } SDL_UnlockMutex(delay_data.mutex); // Clean up. SDL_DestroyMutex(delay_data.mutex); SDL_DestroyCond(delay_data.cond); }
/* =============== GLimp_RendererSleep =============== */ void *GLimp_RendererSleep( void ) { void *data = NULL; GLimp_SetCurrentContext(NULL); SDL_LockMutex(smpMutex); { smpData = NULL; smpDataReady = qfalse; // after this, the front end can exit GLimp_FrontEndSleep SDL_CondSignal(renderCompletedEvent); while ( !smpDataReady ) SDL_CondWait(renderCommandsEvent, smpMutex); data = (void *)smpData; } SDL_UnlockMutex(smpMutex); GLimp_SetCurrentContext(opengl_context); return data; }
/** * @brief Frees the music. */ void music_al_free (void) { /* Stop music if needed. */ musicLock(); if (music_state != MUSIC_STATE_IDLE) { music_command = MUSIC_CMD_STOP; music_forced = 1; while (1) { SDL_CondWait( music_state_cond, music_state_lock ); if (music_state == MUSIC_STATE_IDLE) { music_forced = 0; break; } } } musicUnlock(); musicVorbisLock(); if (music_vorbis.rw != NULL) { ov_clear( &music_vorbis.stream ); music_vorbis.rw = NULL; /* somewhat officially ended */ } musicVorbisUnlock(); }
void sdl_thread() { for (;;) { // Wait for the emulation thread to signal that a frame has completed SDL_LockMutex(frame_lock); ready_to_draw_new_frame = true; while (!frame_available && !pending_sdl_thread_exit) SDL_CondWait(frame_available_cond, frame_lock); if (pending_sdl_thread_exit) { SDL_UnlockMutex(frame_lock); return; } frame_available = ready_to_draw_new_frame = false; SDL_UnlockMutex(frame_lock); // Process events and calculate controller input state (which might // need left+right/up+down elimination) process_events(); // Draw the new frame fail_if(SDL_UpdateTexture(screen_tex, 0, front_buffer, 256*sizeof(Uint32)), "failed to update screen texture: %s", SDL_GetError()); fail_if(SDL_RenderCopy(renderer, screen_tex, 0, 0), "failed to copy rendered frame to render target: %s", SDL_GetError()); SDL_RenderPresent(renderer); } }
/** * Get next item from the monitor * @return the next item */ void* SDL_IterMon_get_next(void* monitor) { SDL_IterMon_t* mon; void* next; mon = monitor; if (-1 == SDL_mutexP(mon->mutex)) assert(FALSE); /* wait for the iterator to be set */ while (!mon->iter) if (-1 == SDL_CondWait( mon->cond_can_get_iter, mon->mutex)) assert(FALSE); assert(mon->iter); if (mon->iter_has_next(mon->iter)) { next = mon->iter_get_next(mon->iter); assert(next); } else { mon->iter_done(mon->iter); mon->iter = NULL; SDL_SemPost(mon->sem_iterating); next = NULL; } if (-1 == SDL_mutexV(mon->mutex)) assert(FALSE); return next; }
// called by the runner to get a new job Job *AsyncJobQueue::GetJob() { SDL_LockMutex(m_queueLock); // loop until a new job is available Job *job = 0; while (!job) { // we're shutting down, so just get out of here if (m_shutdown) { SDL_UnlockMutex(m_queueLock); return 0; } if (!m_queue.size()) // no jobs, go to sleep until one arrives SDL_CondWait(m_queueWaitCond, m_queueLock); else { // got one, pop it and return it job = m_queue.front(); m_queue.pop_front(); } } SDL_UnlockMutex(m_queueLock); return job; }
static int _midi_queue_run(UNUSED void *xtop) { int i; #ifdef WIN32 __win32_pick_usleep(); SetPriorityClass(GetCurrentProcess(),HIGH_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL); /*SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_HIGHEST);*/ #endif SDL_mutexP(midi_play_mutex); for (;;) { SDL_CondWait(midi_play_cond, midi_play_mutex); for (i = 0; i < qlen; i++) { SDL_mutexP(midi_record_mutex); _midi_send_unlocked(qq[i].b, qq[i].used, 0, 1); SDL_mutexV(midi_record_mutex); SLEEP_FUNC(10000); /* 10msec */ qq[i].used = 0; } } return 0; /* never happens */ }
int PacketQueue_get(PacketQueue* pq, AVPacket* packet, bool block, _Atomic enum State const* const state) { SDL_LockMutex(pq->mutex); AVPacketList* pl; int result; while (true) { if (*state == STATE_QUIT) { result = -1; break; } pl = pq->first; if (pl) { pq->first = pl->next; if (!pq->first) pq->last = NULL; --pq->nPackets; pq->size -= pl->pkt.size; *packet = pl->pkt; av_free(pl); result = 1; break; } else if (!block) { result = 0; break; } else SDL_CondWait(pq->cond, pq->mutex); } SDL_UnlockMutex(pq->mutex); return result; }
void *queue_pop_blocking(queue_t *queue) { node_t *node; void *item; if (queue == 0) { return 0; } CHECK_AND_LOCK_MUTEX(queue->mutex); while (queue->front == queue->rear) { SDL_CondWait(queue->condition, queue->mutex); } node = queue->front->next; item = node->data; /* Check if removing the last node from the queue */ if (queue->front->next->next == 0) { queue->rear = queue->front; } else { queue->front->next = queue->front->next->next; } free(node); queue->nodes--; CHECK_AND_UNLOCK_MUTEX(queue->mutex); return item; }
int _Thread_CondWait(void *cond, void *mutex, const char *filename, int fileline) { #ifdef THREADDEBUG Sys_PrintfToTerminal("%p cond wait %s:%i\n" , cond, filename, fileline); #endif return SDL_CondWait((SDL_cond *)cond, (SDL_mutex *)mutex); }
AVPacket* THAVPacketQueue::pull(bool fBlock) { AVPacketList *pNode; AVPacket *pPacket; SDL_LockMutex(m_pMutex); pNode = m_pFirstPacket; if(pNode == nullptr && fBlock) { SDL_CondWait(m_pCond, m_pMutex); pNode = m_pFirstPacket; } if(pNode == nullptr) { pPacket = nullptr; } else { m_pFirstPacket = pNode->next; if(m_pFirstPacket == nullptr) { m_pLastPacket = nullptr; } iCount--; pPacket = (AVPacket*)av_malloc(sizeof(AVPacket)); *pPacket = pNode->pkt; av_free(pNode); } SDL_UnlockMutex(m_pMutex); return pPacket; }
void waiter_wait(WakeableWaiter *ww) { SDL_LockMutex(ww->lock); while (!ww->event) SDL_CondWait(ww->cond, ww->lock); ww->event = 0; SDL_UnlockMutex(ww->lock); }
def_dll int sdl_condition::wait(sdl_mutex* p) { if(p) { return SDL_CondWait(_condition,p->_mutex); } return -1; }
// This is the thread that handles all of our actual game logic updates: static int UpdateThread(void* data) { UpdateThreadData* rt_data = static_cast<UpdateThreadData*>(data); GameSynchronization& sync = *rt_data->sync; int prev_update_time; prev_update_time = CurrentWorldTime(*rt_data->input) - kMinUpdateTime; #ifdef __ANDROID__ JavaVM* jvm; JNIEnv* env = fplbase::AndroidGetJNIEnv(); env->GetJavaVM(&jvm); JNIEnv* update_env; JavaVMAttachArgs args; args.version = JNI_VERSION_1_6; // choose your JNI version args.name = "Zooshi Update"; args.group = nullptr; // you might want to assign the java thread to a ThreadGroup jvm->AttachCurrentThread(&update_env, &args); #endif // __ANDROID__ SDL_LockMutex(sync.updatethread_mutex_); while (!*(rt_data->game_exiting)) { SDL_CondWait(sync.start_update_cv_, sync.updatethread_mutex_); // ------------------------------------------- // Step 5b. (See comment at the start of Run() // Update everything. This is only called once everything has been // safely loaded up into openGL and the renderthread is working its way // through actually putting everything on the screen. // ------------------------------------------- SDL_LockMutex(sync.gameupdate_mutex_); const corgi::WorldTime world_time = CurrentWorldTime(*rt_data->input); const corgi::WorldTime delta_time = std::min(world_time - prev_update_time, kMaxUpdateTime); prev_update_time = world_time; SystraceAsyncBegin("UpdateGameState", kUpdateGameStateCode); rt_data->state_machine->AdvanceFrame(delta_time); SystraceAsyncEnd("UpdateGameState", kUpdateGameStateCode); SystraceAsyncBegin("UpdateRenderPrep", kUpdateRenderPrepCode); rt_data->state_machine->RenderPrep(rt_data->renderer); SystraceAsyncEnd("UpdateRenderPrep", kUpdateRenderPrepCode); rt_data->audio_engine->AdvanceFrame(delta_time / 1000.0f); *(rt_data->game_exiting) |= rt_data->state_machine->done(); SDL_UnlockMutex(sync.gameupdate_mutex_); } #ifdef __ANDROID__ jvm->DetachCurrentThread(); #endif // __ANDROID__ SDL_UnlockMutex(sync.updatethread_mutex_); return 0; }
void SyncPoint::Util::waitForUnlock() { SDL_LockMutex(mut); while (locked) SDL_CondWait(cond, mut); SDL_UnlockMutex(mut); }
/* =============== GLimp_FrontEndSleep =============== */ void GLimp_FrontEndSleep(void) { SDL_LockMutex(smpMutex); { while (smpData) SDL_CondWait(renderCompletedEvent, smpMutex); } SDL_UnlockMutex(smpMutex); }