void power_off(void) { /* Shut down SDL event loop */ SDL_Event event; memset(&event, 0, sizeof(SDL_Event)); event.type = SDL_USEREVENT; SDL_PushEvent(&event); #ifdef HAVE_SDL_THREADS /* since sim_thread_shutdown() grabs the mutex we need to let it free, * otherwise SDL_WaitThread will deadlock */ struct thread_entry* t = sim_thread_unlock(); #endif /* wait for event thread to finish */ SDL_WaitThread(evt_thread, NULL); #ifdef HAVE_SDL_THREADS /* lock again before entering the scheduler */ sim_thread_lock(t); /* sim_thread_shutdown() will cause sim_do_exit() to be called via longjmp, * but only if we let the sdl thread scheduler exit the other threads */ while(1) yield(); #else sim_do_exit(); #endif }
void system_reboot(void) { #ifdef HAVE_SDL_THREADS sim_thread_exception_wait(); #else sim_do_exit(); #endif }
/* Initialize SDL threading */ void init_threads(void) { struct thread_entry *thread; int n; memset(cores, 0, sizeof(cores)); memset(threads, 0, sizeof(threads)); m = SDL_CreateMutex(); if (SDL_LockMutex(m) == -1) { fprintf(stderr, "Couldn't lock mutex\n"); return; } /* Initialize all IDs */ for (n = 0; n < MAXTHREADS; n++) threads[n].id = THREAD_ID_INIT(n); /* Slot 0 is reserved for the main thread - initialize it here and then create the SDL thread - it is possible to have a quick, early shutdown try to access the structure. */ thread = &threads[0]; thread->stack = (uintptr_t *)" "; thread->stack_size = 8; thread->name = "main"; thread->state = STATE_RUNNING; thread->context.s = SDL_CreateSemaphore(0); thread->context.t = NULL; /* NULL for the implicit main thread */ cores[CURRENT_CORE].running = thread; if (thread->context.s == NULL) { fprintf(stderr, "Failed to create main semaphore\n"); return; } /* Tell all threads jump back to their start routines, unlock and exit gracefully - we'll check each one in turn for it's status. Threads _could_ terminate via remove_thread or multiple threads could exit on each unlock but that is safe. */ /* Setup jump for exit */ if (setjmp(thread_jmpbufs[0]) == 0) { THREAD_SDL_DEBUGF("Main thread: %p\n", thread); return; } SDL_UnlockMutex(m); /* Set to 'COMMAND_DONE' when other rockbox threads have exited. */ while (threads_status < THREADS_EXIT_COMMAND_DONE) SDL_Delay(10); SDL_DestroyMutex(m); /* We're the main thead - perform exit - doesn't return. */ sim_do_exit(); }