void CPU::synchronize_smp() { if(SMP::Threaded == true) { if(smp.clock < 0) co_switch(smp.thread); } else { while(smp.clock < 0) smp.enter(); } }
void CPU::synchronize_ppu() { if(PPU::Threaded == true) { if(ppu.clock < 0) co_switch(ppu.thread); } else { while(ppu.clock < 0) ppu.enter(); } }
static void update_variables(void) { struct retro_variable var = { .key = "Hatari_resolution", }; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value) { char *pch; char str[100]; snprintf(str, sizeof(str), "%s", var.value); pch = strtok(str, "x"); if (pch) retrow = strtoul(pch, NULL, 0); pch = strtok(NULL, "x"); if (pch) retroh = strtoul(pch, NULL, 0); fprintf(stderr, "[libretro-test]: Got size: %u x %u.\n", retrow, retroh); CROP_WIDTH =retrow; CROP_HEIGHT= (retroh-80); VIRTUAL_WIDTH = retrow; texture_init(); //reset_screen(); } } static void retro_wrap_emulator() { pre_main(RPATH); pauseg=-1; environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, 0); // Were done here co_switch(mainThread); // Dead emulator, but libco says not to return while(true) { LOGI("Running a dead emulator."); co_switch(mainThread); } }
bool Handle_CMD(eMessage msg) { if(msg == eMessage_ResumeAfterBRK) { //careful! dont switch back to co_emu, we were in another cothread probably when the BRK happened. //i'm not sure its completely safe to be returning to co_emu below in the normal CMD handler, either... co_switch(co_emu_suspended); return true; } if(msg<=eMessage_CMD_FIRST || msg>=eMessage_CMD_LAST) return false; s_EmulationControl.command = msg; s_EmulationControl.exitReason = eEmulationExitReason_NotSet; co_switch(co_emu); return true; }
static void retro_wrap_emulator() { mmain(1,RPATH); pauseg=-1; environ_cb(RETRO_ENVIRONMENT_SHUTDOWN, 0); // Were done here co_switch(mainThread); // Dead emulator, but libco says not to return while(true) { LOGI("Running a dead emulator."); co_switch(mainThread); } }
static work(async_worker_t *const worker) { worker->main = co_active(); for(;;) { uv_sem_wait(&worker->sem); if(!worker->work) break; co_switch(worker->work); uv_async_send(work->async); } }
void retro_unload_game(void) { if(pauseg==0) { pauseg=-1; co_switch(emuThread); } LOGI("Retro unload_game\n"); }
void gui_poll_events(){ //NO SURE FIND BETTER WAY TO COME BACK IN MAIN THREAD IN HATARI GUI Ktime = GetTicks(); if(Ktime - LastFPSTime >= 1000/50){ frame++; LastFPSTime = Ktime; co_switch(mainThread); } }
void retro_run (void) { retro_poll_mame_input(); if (draw_this_frame) video_cb(videoBuffer,rtwi, rthe, topw << PITCH); else video_cb(NULL,rtwi, rthe, topw << PITCH); co_switch(emuThread); }
//NO SURE FIND BETTER WAY TO COME BACK IN MAIN THREAD IN HATARI GUI void gui_poll_events(void) { Ktime = GetTicks(); if(Ktime - LastFPSTime >= 1000/50) { frame++; LastFPSTime = Ktime; co_switch(mainThread); } }
int retro_return(int just_flipping) { if (stop) return 0; vbo_disable(); flip_only = just_flipping; co_switch(main_thread); return 0; }
int main() { printf("cothread parameterized function example\n\n"); thread[0] = co_active(); thread[1] = co_create(65536, co_entrypoint); thread[2] = co_create(65536, co_entrypoint); //use specialized co_switch(cothread_t, int, int) for initial co_switch call co_switch(thread[1], 1, 2); co_switch(thread[2], 4, 8); //after first call, entry point arguments have been initialized, standard //co_switch(cothread_t) can be used from now on co_switch(thread[2]); co_switch(thread[1]); printf("\ndone\n"); #if defined(_MSC_VER) || defined(__DJGPP__) getch(); #endif return 0; }
void CPU::add_clocks(unsigned clocks) { system.clocks_executed += clocks; if(system.sgb()) scheduler.exit(Scheduler::ExitReason::StepEvent); status.clock += clocks; if(status.clock >= 4 * 1024 * 1024) { status.clock -= 4 * 1024 * 1024; cartridge.mbc3.second(); } //4MHz / N(hz) - 1 = mask if((status.clock & 15) == 0) timer_262144hz(); if((status.clock & 63) == 0) timer_65536hz(); if((status.clock & 255) == 0) timer_16384hz(); if((status.clock & 511) == 0) timer_8192hz(); if((status.clock & 1023) == 0) timer_4096hz(); lcd.clock -= clocks * lcd.frequency; if(lcd.clock <= 0) co_switch(scheduler.active_thread = lcd.thread); apu.clock -= clocks * apu.frequency; if(apu.clock <= 0) co_switch(scheduler.active_thread = apu.thread); }
int async_spawn(size_t const stack, void (*const func)(void *), void *const arg) { cothread_t const fiber = co_create(stack, async_start); if(!fiber) return UV_ENOMEM; arg_func = func; arg_arg = arg; // Similar to async_wakeup but the new thread is not created yet async_t *const original = async_main; async_main = async_active(); co_switch(fiber); async_main = original; return 0; }
void retro_run (void) { bool updated = false; if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE_UPDATE, &updated) && updated) check_variables(); retro_poll_mame_input(); if (draw_this_frame) video_cb(videoBuffer,rtwi, rthe, topw << LOG_PIXEL_BYTES); else video_cb(NULL,rtwi, rthe, topw << LOG_PIXEL_BYTES); co_switch(emuThread); }
int retro_return(bool just_flipping) { if (!stop) { state_job_done = savestates_job_nothing; flip_only = just_flipping; vbo_draw(); co_switch(main_thread); return state_job_done; } return 0; }
bool retro_load_game(const struct retro_game_info *info) { environ_cb(RETRO_ENVIRONMENT_SET_INPUT_DESCRIPTORS, input_descriptors); const char *full_path; (void)info; full_path = info->path; strcpy(RPATH,full_path); co_switch(emuThread); return true; }
static void nx_protect_switch_wrapper(co_monitor_t *cmon) { co_archdep_monitor_t archdep = cmon->archdep; unsigned long long pts_save; asm("cli"); pts_save = (*archdep->fixed_pte) & CO_ARCH_PAGE_NX; *archdep->fixed_pte &= ~CO_ARCH_PAGE_NX; co_switch(); *archdep->fixed_pte |= pts_save; /* interrupts are re-enabled by the caller */ }
bool retro_load_game(const struct retro_game_info *info) { check_variables(); #ifdef M16B memset(videoBuffer,0,1024*1024*2); #else memset(videoBuffer,0,1024*1024*2*2); #endif char basename[128]; extract_basename(basename, info->path, sizeof(basename)); extract_directory(g_rom_dir, info->path, sizeof(g_rom_dir)); strcpy(RPATH,info->path); co_switch(emuThread); return 1; }
void co_host_switch_wrapper(co_monitor_t *cmon) { if (co_get_cr4() & CO_ARCH_X86_CR4_VMXE) { /* * An other virtualization is running in VMX mode. * coLinux does not cooperate with it. * Abort the guest, but don't crash the host for now. */ co_passage_page->operation = CO_OPERATION_TERMINATE; co_passage_page->params[0] = CO_TERMINATE_VMXE; return; } co_switch(); }
//NO SURE FIND BETTER WAY TO COME BACK IN MAIN THREAD IN HATARI GUI void gui_poll_events(void) { Ktime = GetTicks(); if(Ktime - LastFPSTime >= 1000/50) { slowdown=0; frame++; LastFPSTime = Ktime; #ifndef NO_LIBCO co_switch(mainThread); #else //FIXME nolibco Gui endless loop -> no retro_run() call retro_run_gui(); #endif } }
static int squvco_open(sqlite3_vfs *const vfs, char const *const path, sqlite3_file *const file, int const sqflags, int *const outFlags) { int uvflags = 0; if(!path) return SQLITE_IOERR; if(sqflags & SQLITE_OPEN_EXCLUSIVE) uvflags |= O_EXCL; if(sqflags & SQLITE_OPEN_CREATE) uvflags |= O_CREAT; if(sqflags & SQLITE_OPEN_READWRITE) uvflags |= O_RDWR; if(sqflags & SQLITE_OPEN_READONLY) uvflags |= O_RDONLY; uv_fs_t req = { .data = co_active() }; uv_fs_open(vfs->pAppData->loop, &req, path, uvflags, 0600, fs_cb); co_switch(vfs->pAppData->yield); int const result = req.result; uv_fs_req_cleanup(&req); if(result < 0) return SQLITE_CANTOPEN; file->methods = &io_methods; file->file = result; file->thread = vfs->pAppData; file->lockLevel = SQLITE_LOCK_NONE; return SQLITE_OK; }
static inline void thread_params_set(struct mk_thread *th, int type, struct mk_vhost_handler *handler, struct mk_http_session *session, struct mk_http_request *request, int n_params, struct mk_list *params) { /* Callback parameters in order */ libco_param.type = type; libco_param.handler = handler; libco_param.session = session; libco_param.request = request; libco_param.n_params = n_params; libco_param.params = params; libco_param.th = th; co_switch(th->callee); }
void async_mutex_lock(async_mutex_t *const mutex) { assert(mutex && "Mutex must not be null"); cothread_t const thread = co_active(); if(!mutex->active.thread) { mutex->active = thread; } else if(thread == mutex->active.thread) { mutex->depth++; } else { assert(mutex->tail && "Mutex has no tail"); assert(mutex->tail->thread && "Mutex tail has no thread"); list_entry us = { .thread = thread, .next = NULL, }; mutex->tail->next = &us; mutex->tail = &us; co_switch(yield); assert(thread == mutex->active.thread && "Mutex wrong thread obtained lock"); // TODO } }
int main( void ) { int i, n; printf( "Thread test\n" ); print_libco_opts(); threads [0] = co_active(); threads [1] = co_create( stack_size, entry ); assert( threads [1] ); for ( n = 0; n < iter; n++ ) { /* if ( !(n & (n - 1)) ) printf( "%d\n", n );*/ for ( i = 1; i < max_threads; i++ ) if ( threads [i] ) co_switch( threads [i] ); } { unsigned all = 0; for ( i = 0; i < 16; i++ ) all ^= shared [i]; if ( all != final_data ) { printf( "0x%08X\n", all ); printf( "Incorrect CRC\n" ); return EXIT_FAILURE; } } printf( "Passed\n\n" ); return 0; }
void CPU::synchronize_controllers() { if(input.port1->clock < 0) co_switch(input.port1->thread); if(input.port2->clock < 0) co_switch(input.port2->thread); }
void CPU::synchronize_coprocessors() { for(unsigned i = 0; i < coprocessors.size(); i++) { Processor &chip = *coprocessors[i]; if(chip.clock < 0) co_switch(chip.thread); } }
void mini_osd_interface::update(bool skip_redraw) { //const render_primitive_list *primlist; UINT8 *surfptr; if(pauseg==-1){ machine().schedule_exit(); return; } if (FirstTimeUpdate == 1) skip_redraw = 0; //force redraw to make sure the video texture is created if (!skip_redraw) { draw_this_frame = true; // get the minimum width/height for the current layout int minwidth, minheight; if(videoapproach1_enable==false){ our_target->compute_minimum_size(minwidth, minheight); } else{ minwidth=1024;minheight=768; } if (FirstTimeUpdate == 1) { FirstTimeUpdate++; write_log("game screen w=%i h=%i rowPixels=%i\n", minwidth, minheight,minwidth ); rtwi=minwidth; rthe=minheight; topw=minwidth; int gamRot=0; orient = (machine().system().flags & ORIENTATION_MASK); vertical = (machine().system().flags & ORIENTATION_SWAP_XY); gamRot = (ROT270 == orient) ? 1 : gamRot; gamRot = (ROT180 == orient) ? 2 : gamRot; gamRot = (ROT90 == orient) ? 3 : gamRot; //prep_retro_rotation(gamRot); } if (minwidth != rtwi || minheight != rthe || minwidth != topw ){ write_log("Res change: old(%d,%d) new(%d,%d) %d\n",rtwi,rthe,minwidth,minheight,topw); rtwi=minwidth; rthe=minheight; topw=minwidth; } if(videoapproach1_enable){ rtwi=topw=1024; rthe=768; } // make that the size of our target our_target->set_bounds(rtwi,rthe); // get the list of primitives for the target at the current size render_primitive_list &primlist = our_target->get_primitives(); // lock them, and then render them primlist.acquire_lock(); surfptr = (UINT8 *) videoBuffer; // draw a series of primitives using a software rasterizer for (const render_primitive *prim = primlist.first(); prim != NULL; prim = prim->next()) { switch (prim->type) { case render_primitive::LINE: draw_line(*prim, (PIXEL_TYPE*)surfptr, minwidth, minheight, minwidth); break; case render_primitive::QUAD: if (!prim->texture.base) draw_rect(*prim, (PIXEL_TYPE*)surfptr, minwidth, minheight, minwidth); else setup_and_draw_textured_quad(*prim, (PIXEL_TYPE*)surfptr, minwidth, minheight, minwidth); break; default: throw emu_fatalerror("Unexpected render_primitive type"); } } primlist.release_lock(); } else draw_this_frame = false; if(ui_ipt_pushchar!=-1){ ui_input_push_char_event(machine(), our_target, (unicode_char)ui_ipt_pushchar); ui_ipt_pushchar=-1; } co_switch(mainThread); }
void Cpu::syncGear2Gear() { if (!sys->emulateG2G()) return; if(*clockG2G < 0) { co_switch(gear2gear.getThreadHandle()); } }
void Board::tick() { cartridge.clock += 12; if(cartridge.clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread); }