示例#1
0
static void gx_devthread(void *a)
{
   unsigned i;

   while (!gx_stop_dev_thread)
   {
      slock_lock(gx_device_mutex);

      for (i = 0; i < GX_DEVICE_END; i++)
      {
         if (gx_devices[i].mounted)
         {
            if (!gx_devices[i].interface->isInserted())
            {
               char n[8];

               gx_devices[i].mounted = false;
               snprintf(n, sizeof(n), "%s:", gx_devices[i].name);
               fatUnmount(n);
            }
         }
         else if (gx_devices[i].interface->startup() && gx_devices[i].interface->isInserted())
            gx_devices[i].mounted = fatMountSimple(gx_devices[i].name, gx_devices[i].interface);
      }

      slock_unlock(gx_device_mutex);

      slock_lock(gx_device_cond_mutex);
      scond_wait_timeout(gx_device_cond, gx_device_cond_mutex, 1000000);
      slock_unlock(gx_device_cond_mutex);
   }
}
示例#2
0
/**
 * autosave_thread:
 * @data            : pointer to autosave object
 *
 * Callback function for (threaded) autosave.
 **/
static void autosave_thread(void *data)
{
   bool first_log = true;
   autosave_t *save = (autosave_t*)data;

   while (!save->quit)
   {
      bool differ;

      autosave_lock(save);
      differ = memcmp(save->buffer, save->retro_buffer,
            save->bufsize) != 0;
      if (differ)
         memcpy(save->buffer, save->retro_buffer, save->bufsize);
      autosave_unlock(save);

      if (differ)
      {
         /* Should probably deal with this more elegantly. */
         FILE *file = fopen(save->path, "wb");

         if (file)
         {
            bool failed = false;

            /* Avoid spamming down stderr ... */
            if (first_log)
            {
               RARCH_LOG("Autosaving SRAM to \"%s\", will continue to check every %u seconds ...\n",
                     save->path, save->interval);
               first_log = false;
            }
            else
               RARCH_LOG("SRAM changed ... autosaving ...\n");

            failed |= fwrite(save->buffer, 1, save->bufsize, file)
               != save->bufsize;
            failed |= fflush(file) != 0;
            failed |= fclose(file) != 0;
            if (failed)
               RARCH_WARN("Failed to autosave SRAM. Disk might be full.\n");
         }
      }

      slock_lock(save->cond_lock);

      if (!save->quit)
         scond_wait_timeout(save->cond, save->cond_lock,
               save->interval * 1000000LL);

      slock_unlock(save->cond_lock);
   }
}
示例#3
0
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size,
      bool is_perfcnt_enable)
{
   coreaudio_t *dev   = (coreaudio_t*)data;
   const uint8_t *buf = (const uint8_t*)buf_;
   size_t written     = 0;

   while (!g_interrupted && size > 0)
   {
      size_t write_avail;

      slock_lock(dev->lock);

      write_avail = fifo_write_avail(dev->buffer);
      if (write_avail > size)
         write_avail = size;

      fifo_write(dev->buffer, buf, write_avail);
      buf += write_avail;
      written += write_avail;
      size -= write_avail;

      if (dev->nonblock)
      {
         slock_unlock(dev->lock);
         break;
      }

#if TARGET_OS_IPHONE
      if (write_avail == 0 && !scond_wait_timeout(
               dev->cond, dev->lock, 3000000))
         g_interrupted = true;
#else
      if (write_avail == 0)
         scond_wait(dev->cond, dev->lock);
#endif
      slock_unlock(dev->lock);
   }

   return written;
}
static bool thread_frame(void *data, const void *frame_,
      unsigned width, unsigned height, unsigned pitch, const char *msg)
{
   unsigned copy_stride;
   const uint8_t *src  = NULL;
   uint8_t *dst        = NULL;
   thread_video_t *thr = (thread_video_t*)data;

   /* If called from within read_viewport, we're actually in the 
    * driver thread, so just render directly. */
   if (thr->frame.within_thread)
   {
      thread_update_driver_state(thr);

      if (thr->driver && thr->driver->frame)
         return thr->driver->frame(thr->driver_data, frame_,
               width, height, pitch, msg);
      return false;
   }

   RARCH_PERFORMANCE_INIT(thr_frame);
   RARCH_PERFORMANCE_START(thr_frame);

   copy_stride = width * (thr->info.rgb32 
         ? sizeof(uint32_t) : sizeof(uint16_t));

   src = (const uint8_t*)frame_;
   dst = thr->frame.buffer;

   slock_lock(thr->lock);

   if (!thr->nonblock)
   {
      settings_t *settings = config_get_ptr();

      retro_time_t target_frame_time = (retro_time_t)
         roundf(1000000 / settings->video.refresh_rate);
      retro_time_t target = thr->last_time + target_frame_time;

      /* Ideally, use absolute time, but that is only a good idea on POSIX. */
      while (thr->frame.updated)
      {
         retro_time_t current = rarch_get_time_usec();
         retro_time_t delta = target - current;

         if (delta <= 0)
            break;

         if (!scond_wait_timeout(thr->cond_cmd, thr->lock, delta))
            break;
      }
   }

   /* Drop frame if updated flag is still set, as thread is 
    * still working on last frame. */
   if (!thr->frame.updated)
   {
      if (src)
      {
         unsigned h;
         for (h = 0; h < height; h++, src += pitch, dst += copy_stride)
            memcpy(dst, src, copy_stride);
      }

      thr->frame.updated = true;
      thr->frame.width  = width;
      thr->frame.height = height;
      thr->frame.pitch  = copy_stride;

      if (msg)
         strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg));
      else
         *thr->frame.msg = '\0';

      scond_signal(thr->cond_thread);

#if defined(HAVE_MENU)
      if (thr->texture.enable)
      {
         while (thr->frame.updated)
            scond_wait(thr->cond_cmd, thr->lock);
      }
#endif
      thr->hit_count++;
   }
   else
      thr->miss_count++;

   slock_unlock(thr->lock);

   RARCH_PERFORMANCE_STOP(thr_frame);

   thr->last_time = rarch_get_time_usec();
   return true;
}
static bool thread_frame(void *data, const void *frame_,
      unsigned width, unsigned height, unsigned pitch, const char *msg)
{
   RARCH_PERFORMANCE_INIT(thread_frame);
   RARCH_PERFORMANCE_START(thread_frame);

   thread_video_t *thr = (thread_video_t*)data;
   unsigned copy_stride = width * (thr->info.rgb32 ? sizeof(uint32_t) : sizeof(uint16_t));

   const uint8_t *src = (const uint8_t*)frame_;
   uint8_t *dst = thr->frame.buffer;

   slock_lock(thr->lock);

   // scond_wait_timeout cannot be implemented on consoles.
#ifndef RARCH_CONSOLE
   if (!thr->nonblock)
   {
      retro_time_t target = thr->last_time + thr->target_frame_time;
      // Ideally, use absolute time, but that is only a good idea on POSIX.
      while (thr->frame.updated)
      {
         retro_time_t current = rarch_get_time_usec();
         retro_time_t delta = target - current;

         if (delta <= 0)
            break;

         if (!scond_wait_timeout(thr->cond_cmd, thr->lock, delta))
            break;
      }
   }
#endif

   // Drop frame if updated flag is still set, as thread is still working on last frame.
   if (!thr->frame.updated)
   {
      if (src)
      {
         unsigned h;
         for (h = 0; h < height; h++, src += pitch, dst += copy_stride)
            memcpy(dst, src, copy_stride);
      }

      thr->frame.updated = true;
      thr->frame.width  = width;
      thr->frame.height = height;
      thr->frame.pitch  = copy_stride;

      if (msg)
         strlcpy(thr->frame.msg, msg, sizeof(thr->frame.msg));
      else
         *thr->frame.msg = '\0';

      scond_signal(thr->cond_thread);

#if defined(HAVE_MENU)
      if (thr->texture.enable)
      {
         while (thr->frame.updated)
            scond_wait(thr->cond_cmd, thr->lock);
      }
#endif
      thr->hit_count++;
   }
   else
      thr->miss_count++;

   slock_unlock(thr->lock);

   RARCH_PERFORMANCE_STOP(thread_frame);

   thr->last_time = rarch_get_time_usec();
   return true;
}