예제 #1
0
파일: cpu.cpp 프로젝트: IcooN/OpenEmu
void CPU::synchronize_smp() {
  if(SMP::Threaded == true) {
    if(smp.clock < 0) co_switch(smp.thread);
  } else {
    while(smp.clock < 0) smp.enter();
  }
}
예제 #2
0
파일: cpu.cpp 프로젝트: IcooN/OpenEmu
void CPU::synchronize_ppu() {
  if(PPU::Threaded == true) {
    if(ppu.clock < 0) co_switch(ppu.thread);
  } else {
    while(ppu.clock < 0) ppu.enter();
  }
}
예제 #3
0
파일: libretro.c 프로젝트: helgeblod/hatari
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);
   }
}
예제 #4
0
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;
}
예제 #5
0
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);
	}
}
예제 #7
0
void retro_unload_game(void)
{
	if(pauseg==0)
   	{
		pauseg=-1;				
      		co_switch(emuThread);
	}

	LOGI("Retro unload_game\n");	
}
예제 #8
0
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);
 	}
}
예제 #9
0
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);
}
예제 #10
0
//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;
}
예제 #12
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;
}
예제 #13
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);
}
예제 #14
0
파일: async.c 프로젝트: Ryezhang/stronglink
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;
}
예제 #15
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);
}
예제 #16
0
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;
}
예제 #17
0
파일: libretro.c 프로젝트: helgeblod/hatari
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;
}
예제 #18
0
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 */
}
예제 #19
0
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;
}
예제 #20
0
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();
}
예제 #21
0
//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;
}
예제 #23
0
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
	}
}
예제 #25
0
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;
}
예제 #26
0
파일: cpu.cpp 프로젝트: HDBSD/bizhawk
void CPU::synchronize_controllers() {
  if(input.port1->clock < 0) co_switch(input.port1->thread);
  if(input.port2->clock < 0) co_switch(input.port2->thread);
}
예제 #27
0
파일: cpu.cpp 프로젝트: HDBSD/bizhawk
void CPU::synchronize_coprocessors() {
  for(unsigned i = 0; i < coprocessors.size(); i++) {
    Processor &chip = *coprocessors[i];
    if(chip.clock < 0) co_switch(chip.thread);
  }
}
예제 #28
0
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);
}  
예제 #29
0
void Cpu::syncGear2Gear() {
    if (!sys->emulateG2G()) return;
    if(*clockG2G < 0) {
        co_switch(gear2gear.getThreadHandle());
    }
}
예제 #30
0
void Board::tick() {
  cartridge.clock += 12;
  if(cartridge.clock >= 0 && scheduler.sync != Scheduler::SynchronizeMode::All) co_switch(cpu.thread);
}