Esempio n. 1
0
static void data_runloop_thread_deinit(data_runloop_t *runloop)
{
   if (!runloop->thread_inited)
   {
      slock_lock(runloop->cond_lock);
      runloop->alive = false;
      scond_signal(runloop->cond);
      slock_unlock(runloop->cond_lock);
      sthread_join(runloop->thread);

      slock_free(runloop->lock);
      slock_free(runloop->cond_lock);
      slock_free(runloop->overlay_lock);
      scond_free(runloop->cond);
   }
}
Esempio n. 2
0
void Task::Impl::execute(const TWork &work, void *param)
{
	slock_lock(this->mutex);

	if (work == NULL || !this->_isThreadRunning)
   {
		slock_unlock(this->mutex);
		return;
	}

	this->workFunc = work;
	this->workFuncParam = param;
	scond_signal(this->condWork);

	slock_unlock(this->mutex);
}
Esempio n. 3
0
static void android_app_set_activity_state (void *data, int8_t cmd)
{
   struct android_app *android_app = (struct android_app*)data;

   if (!android_app)
      return;

   slock_lock(android_app->mutex);
   android_app_write_cmd(android_app, cmd);
   while (android_app->activityState != cmd && android_app->activityState != APP_CMD_DEAD)
      scond_wait(android_app->cond, android_app->mutex);
   slock_unlock(android_app->mutex);

   if (android_app->activityState == APP_CMD_DEAD)
      RARCH_LOG("RetroArch native thread is dead.\n");
}
Esempio n. 4
0
const char *rarch_main_msg_queue_pull(void)
{
   const char *ret = NULL;

#ifdef HAVE_THREADS
   slock_lock(mq_lock);
#endif

   ret = msg_queue_pull(g_msg_queue);

#ifdef HAVE_THREADS
   slock_unlock(mq_lock);
#endif

   return ret;
}
Esempio n. 5
0
static void data_runloop_thread_deinit(void)
{
   if (!g_data_runloop.thread_inited)
   {
      slock_lock(g_data_runloop.cond_lock);
      g_data_runloop.alive = false;
      scond_signal(g_data_runloop.cond);
      slock_unlock(g_data_runloop.cond_lock);
      sthread_join(g_data_runloop.thread);

      slock_free(g_data_runloop.lock);
      slock_free(g_data_runloop.cond_lock);
      rarch_main_data_overlay_thread_uninit();
      scond_free(g_data_runloop.cond);
   }
}
static bool thread_alive(void *data)
{
   thread_video_t *thr = (thread_video_t*)data;
   if (g_extern.is_paused)
   {
      thread_send_cmd(thr, CMD_ALIVE);
      thread_wait_reply(thr, CMD_ALIVE);
      return thr->cmd_data.b;
   }
   else
   {
      slock_lock(thr->lock);
      bool ret = thr->alive;
      slock_unlock(thr->lock);
      return ret;
   }
}
Esempio n. 7
0
static void retro_task_threaded_cancel(void *task)
{
   retro_task_t *t;

   slock_lock(running_lock);

   for (t = tasks_running.front; t; t = t->next)
   {
      if (t == task)
      {
        t->cancelled = true;
        break;
      }
   }

   slock_unlock(running_lock);
}
Esempio n. 8
0
static void adapter_thread(void *data)
{
   uint8_t __attribute__((aligned(32))) send_command_buf[4096];
   struct wiiusb_adapter *adapter = (struct wiiusb_adapter*)data;
   wiiusb_hid_t *hid = adapter ? adapter->hid : NULL;

   if (!adapter)
      return;

   while (!adapter->quitting)
   {
      size_t send_command_size;
      int tmp;
      int report_number;
      int size = 0;

      (void)tmp;
      (void)report_number;

      slock_lock(adapter->send_control_lock);

      if (fifo_read_avail(adapter->send_control_buffer) >= sizeof(send_command_size))
      {
         fifo_read(adapter->send_control_buffer, &send_command_size, sizeof(send_command_size));
         if (fifo_read_avail(adapter->send_control_buffer) >= sizeof(send_command_size))
         {
            fifo_read(adapter->send_control_buffer, send_command_buf, send_command_size);
            USB_WriteIntrMsg(adapter->handle, adapter->endpoint_out, send_command_size, send_command_buf);
         }
      }
      slock_unlock(adapter->send_control_lock);

      size = USB_ReadIntrMsg(adapter->handle, adapter->endpoint_in, adapter->endpoint_in_max_size, &adapter->data[0]);
      /* RARCH_LOG("%p USB_ReadIntrMsg(%i, %i, %i, %p): %i\n", &adapter->data[0],
         adapter->handle, adapter->endpoint_in, adapter->endpoint_in_max_size, &adapter->data[0],
         size); */

      //RARCH_LOG("%03i %03i %03i %03i\n", adapter->data[0], adapter->data[1], adapter->data[2], adapter->data[3], adapter->data[4]);
      //memmove(&adapter->data[1], &adapter->data[0], 2048);

      if (adapter && hid && hid->slots && size)
         pad_connection_packet(&hid->slots[adapter->slot], adapter->slot,
               adapter->data - 1, size+1);
   }
}
Esempio n. 9
0
static ssize_t rs_write(void *data, const void *buf, size_t size)
{
   rsd_t *rsd = (rsd_t*)data;

   if (rsd->has_error)
      return -1;

   if (rsd->nonblock)
   {
      rsd_callback_lock(rsd->rd);
      size_t avail = fifo_write_avail(rsd->buffer);
      size_t write_amt = avail > size ? size : avail;
      fifo_write(rsd->buffer, buf, write_amt);
      rsd_callback_unlock(rsd->rd);
      return write_amt;
   }
   else
   {
      size_t written = 0;
      while (written < size && !rsd->has_error)
      {
         rsd_callback_lock(rsd->rd);
         size_t avail = fifo_write_avail(rsd->buffer);

         if (avail == 0)
         {
            rsd_callback_unlock(rsd->rd);
            if (!rsd->has_error)
            {
               slock_lock(rsd->cond_lock);
               scond_wait(rsd->cond, rsd->cond_lock);
               slock_unlock(rsd->cond_lock);
            }
         }
         else
         {
            size_t write_amt = size - written > avail ? avail : size - written;
            fifo_write(rsd->buffer, (const char*)buf + written, write_amt);
            rsd_callback_unlock(rsd->rd);
            written += write_amt;
         }
      }
      return written;
   }
}
Esempio n. 10
0
void rarch_main_msg_queue_free(void)
{
   if (!g_msg_queue)
      return;

#ifdef HAVE_THREADS
   slock_lock(mq_lock);
#endif

   msg_queue_free(g_msg_queue);

#ifdef HAVE_THREADS
   slock_unlock(mq_lock);
   slock_free(mq_lock);
#endif

   g_msg_queue = NULL;
}
Esempio n. 11
0
static bool thread_alive(void *data)
{
   bool ret;
   thread_video_t *thr = (thread_video_t*)data;

   if (rarch_main_is_paused())
   {
      thread_packet_t pkt = { CMD_ALIVE };
      thread_send_and_wait(thr, &pkt);
      return pkt.data.b;
   }

   slock_lock(thr->lock);
   ret = thr->alive;
   slock_unlock(thr->lock);

   return ret;
}
Esempio n. 12
0
void Task::Impl::start(bool spinlock)
{
	slock_lock(this->mutex);

	if (this->_isThreadRunning) {
		slock_unlock(this->mutex);
		return;
	}

	this->workFunc = NULL;
	this->workFuncParam = NULL;
	this->ret = NULL;
	this->exitThread = false;
	this->_thread = (sthread_t*)sthread_create(&taskProc, this);
	this->_isThreadRunning = true;

	slock_unlock(this->mutex);
}
Esempio n. 13
0
/**
 * autosave_free:
 * @handle          : pointer to autosave object
 *
 * Frees autosave object.
 **/
void autosave_free(autosave_t *handle)
{
   if (!handle)
      return;

   slock_lock(handle->cond_lock);
   handle->quit = true;
   slock_unlock(handle->cond_lock);
   scond_signal(handle->cond);
   sthread_join(handle->thread);

   slock_free(handle->lock);
   slock_free(handle->cond_lock);
   scond_free(handle->cond);

   free(handle->buffer);
   free(handle);
}
Esempio n. 14
0
static void retro_task_threaded_deinit(void)
{
   slock_lock(running_lock);
   worker_continue = false;
   scond_signal(worker_cond);
   slock_unlock(running_lock);

   sthread_join(worker_thread);

   scond_free(worker_cond);
   slock_free(running_lock);
   slock_free(finished_lock);

   worker_thread = NULL;
   worker_cond   = NULL;
   running_lock  = NULL;
   finished_lock = NULL;
}
bool CDIF_MT::ReadRawSector(uint8 *buf, uint32 lba)
{
   bool found = FALSE;
   bool error_condition = false;

   if(UnrecoverableError)
   {
      memset(buf, 0, 2352 + 96);
      return(false);
   }

   // This shouldn't happen, the emulated-system-specific CDROM emulation code should make sure the emulated program doesn't try
   // to read past the last "real" sector of the disc.
   if(lba >= disc_toc.tracks[100].lba)
   {
      printf("Attempt to read LBA %d, >= LBA %d\n", lba, disc_toc.tracks[100].lba);
      return(FALSE);
   }

   ReadThreadQueue.Write(CDIF_Message(CDIF_MSG_READ_SECTOR, lba));

   slock_lock((slock_t*)SBMutex);

   do
   {
      int i;
      for(i = 0; i < SBSize; i++)
      {
         if(SectorBuffers[i].valid && SectorBuffers[i].lba == lba)
         {
            error_condition = SectorBuffers[i].error;
            memcpy(buf, SectorBuffers[i].data, 2352 + 96);
            found = TRUE;
         }
      }

      if(!found)
         scond_wait((scond_t*)SBCond, (slock_t*)SBMutex);
   } while(!found);

   slock_unlock((slock_t*)SBMutex);

   return(!error_condition);
}
Esempio n. 16
0
static void autosave_thread(void *data)
{
   autosave_t *save = (autosave_t*)data;

   bool first_log = true;

   while (!save->quit)
   {
      autosave_lock(save);
      bool 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)
         {
            // 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");

            bool failed = false;
            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 * 1000);
      slock_unlock(save->cond_lock);
   }
}
Esempio n. 17
0
static void adapter_thread(void *data)
{
   uint8_t send_command_buf[4096];
   struct libusb_adapter *adapter = (struct libusb_adapter*)data;
   libusb_hid_t *hid              = adapter ? adapter->hid : NULL;

   if (!adapter)
      return;

   while (!adapter->quitting)
   {
      size_t send_command_size;
      int tmp;
      int report_number;
      int size = 0;

      slock_lock(adapter->send_control_lock);
      if (fifo_read_avail(adapter->send_control_buffer) 
            >= sizeof(send_command_size))
      {
         fifo_read(adapter->send_control_buffer,
               &send_command_size, sizeof(send_command_size));

         if (fifo_read_avail(adapter->send_control_buffer) 
               >= sizeof(send_command_size))
         {
            fifo_read(adapter->send_control_buffer,
                  send_command_buf, send_command_size);
            libusb_interrupt_transfer(adapter->handle,
                  adapter->endpoint_out, send_command_buf,
                  send_command_size, &tmp, 1000);
         }
      }
      slock_unlock(adapter->send_control_lock);

      libusb_interrupt_transfer(adapter->handle,
            adapter->endpoint_in, &adapter->data[1],
            adapter->endpoint_in_max_size, &size, 1000);

      if (adapter && hid && hid->slots && size)
         pad_connection_packet(&hid->slots[adapter->slot], adapter->slot,
               adapter->data, size+1);
   }
}
Esempio n. 18
0
static void deinit_thread(ffemu_t *handle)
{
   if (handle->thread)
   {
      slock_lock(handle->cond_lock);
      handle->alive = false;
      handle->can_sleep = false;
      slock_unlock(handle->cond_lock);

      scond_signal(handle->cond);
      sthread_join(handle->thread);

      slock_free(handle->lock);
      slock_free(handle->cond_lock);
      scond_free(handle->cond);

      handle->thread = NULL;
   }
}
Esempio n. 19
0
/**
 * rarch_threaded_audio_init:
 * @out_driver                : output driver
 * @out_data                  : output audio data
 * @device                    : audio device (optional)
 * @out_rate                  : output audio rate
 * @latency                   : audio latency
 * @driver                    : audio driver
 *
 * Starts a audio driver in a new thread.
 * Access to audio driver will be mediated through this driver.
 * This driver interfaces with audio callback and is 
 * only used in that case.
 *
 * Returns: true (1) if successful, otherwise false (0).
 **/
bool rarch_threaded_audio_init(const audio_driver_t **out_driver,
      void **out_data, const char *device, unsigned audio_out_rate,
      unsigned latency, const audio_driver_t *drv)
{
   audio_thread_t *thr = (audio_thread_t*)calloc(1, sizeof(*thr));
   if (!thr)
      return false;

   thr->driver         = (const audio_driver_t*)drv;
   thr->device         = device;
   thr->out_rate       = audio_out_rate;
   thr->latency        = latency;

   if (!(thr->cond     = scond_new()))
      goto error;
   if (!(thr->lock     = slock_new()))
      goto error;

   thr->alive = true;
   thr->stopped = true;

   if (!(thr->thread   = sthread_create(audio_thread_loop, thr)))
      goto error;

   /* Wait until thread has initialized (or failed) the driver. */
   slock_lock(thr->lock);
   while (!thr->inited)
      scond_wait(thr->cond, thr->lock);
   slock_unlock(thr->lock);

   if (thr->inited < 0) /* Thread failed. */
      goto error;

   *out_driver         = &audio_thread;
   *out_data           = thr;
   return true;

error:
   *out_driver         = NULL;
   *out_data           = NULL;
   audio_thread_free(thr);
   return false;
}
Esempio n. 20
0
static void audio_thread_block(audio_thread_t *thr)
{
   if (!thr)
      return;

   if (thr->stopped)
      return;

   slock_lock(thr->lock);
   thr->stopped_ack = false;
   thr->stopped = true;
   scond_signal(thr->cond);

   /* Wait until audio driver actually goes to sleep. */
   while (!thr->stopped_ack)
      scond_wait(thr->cond, thr->lock);

   slock_unlock(thr->lock);
}
Esempio n. 21
0
void tactx_Recycle(TA_context* poped_ctx)
{
#ifndef TARGET_NO_THREADS
   slock_lock(mtx_pool);
#endif
   if (ctx_pool.size()>2)
   {
      poped_ctx->Free();
      delete poped_ctx;
   }
   else
   {
      poped_ctx->Reset();
      ctx_pool.push_back(poped_ctx);
   }
#ifndef TARGET_NO_THREADS
   slock_unlock(mtx_pool);
#endif
}
Esempio n. 22
0
static bool video_thread_alive(void *data)
{
   bool ret;
   thread_video_t *thr = (thread_video_t*)data;

   if (runloop_ctl(RUNLOOP_CTL_IS_PAUSED, NULL))
   {
      thread_packet_t pkt = { CMD_ALIVE };

      video_thread_send_and_wait_user_to_thread(thr, &pkt);
      return pkt.data.b;
   }

   slock_lock(thr->lock);
   ret = thr->alive;
   slock_unlock(thr->lock);

   return ret;
}
Esempio n. 23
0
static bool retro_task_threaded_find(
      retro_task_finder_t func, void *user_data)
{
   retro_task_t *task = NULL;
   bool result = false;

   slock_lock(running_lock);
   for (task = tasks_running.front; task; task = task->next)
   {
      if (func(task, user_data))
      {
         result = true;
         break;
      }
   }
   slock_unlock(running_lock);

   return result;
}
Esempio n. 24
0
static ssize_t sdl_audio_write(void *data, const void *buf, size_t size)
{
   sdl_audio_t *sdl = (sdl_audio_t*)data;

   ssize_t ret = 0;
   if (sdl->nonblock)
   {
      SDL_LockAudio();
      size_t avail = fifo_write_avail(sdl->buffer);
      size_t write_amt = avail > size ? size : avail;
      fifo_write(sdl->buffer, buf, write_amt);
      SDL_UnlockAudio();
      ret = write_amt;
   }
   else
   {
      size_t written = 0;
      while (written < size)
      {
         SDL_LockAudio();
         size_t avail = fifo_write_avail(sdl->buffer);

         if (avail == 0)
         {
            SDL_UnlockAudio();
            slock_lock(sdl->lock);
            scond_wait(sdl->cond, sdl->lock);
            slock_unlock(sdl->lock);
         }
         else
         {
            size_t write_amt = size - written > avail ? avail : size - written;
            fifo_write(sdl->buffer, (const char*)buf + written, write_amt);
            SDL_UnlockAudio();
            written += write_amt;
         }
      }
      ret = written;
   }

   return ret;
}
Esempio n. 25
0
static OSStatus audio_write_cb(void *userdata,
      AudioUnitRenderActionFlags *action_flags,
      const AudioTimeStamp *time_stamp, UInt32 bus_number,
      UInt32 number_frames, AudioBufferList *io_data)
{
   void *outbuf;
   unsigned write_avail;
   coreaudio_t *dev = (coreaudio_t*)userdata;

   (void)time_stamp;
   (void)bus_number;
   (void)number_frames;

   if (!io_data)
      return noErr;
   if (io_data->mNumberBuffers != 1)
      return noErr;

   write_avail = io_data->mBuffers[0].mDataByteSize;
   outbuf = io_data->mBuffers[0].mData;

   slock_lock(dev->lock);

   if (fifo_read_avail(dev->buffer) < write_avail)
   {
      *action_flags = kAudioUnitRenderAction_OutputIsSilence;

      /* Seems to be needed. */
      memset(outbuf, 0, write_avail);

      slock_unlock(dev->lock);

      /* Technically possible to deadlock without. */
      scond_signal(dev->cond); 
      return noErr;
   }

   fifo_read(dev->buffer, outbuf, write_avail);
   slock_unlock(dev->lock);
   scond_signal(dev->cond);
   return noErr;
}
Esempio n. 26
0
void ssem_wait(ssem_t *semaphore)
{
   if (!semaphore)
      return;

   slock_lock(semaphore->mutex);
   semaphore->value--;

   if (semaphore->value < 0)
   {
      do
      {
         scond_wait(semaphore->cond, semaphore->mutex);
      }while (semaphore->wakeups < 1);

      semaphore->wakeups--;
   }

   slock_unlock(semaphore->mutex);
}
Esempio n. 27
0
static ssize_t audio_thread_write(void *data, const void *buf, size_t size)
{
   ssize_t ret;
   audio_thread_t *thr = (audio_thread_t*)data;

   if (!thr)
      return 0;

   ret = thr->driver->write(thr->driver_data, buf, size);

   if (ret < 0)
   {
      slock_lock(thr->lock);
      thr->alive = false;
      scond_signal(thr->cond);
      slock_unlock(thr->lock);
   }

   return ret;
}
Esempio n. 28
0
void* Task::Impl::finish()
{
	void *returnValue = NULL;

	slock_lock(this->mutex);

	if (!this->_isThreadRunning) {
		slock_unlock(this->mutex);
		return returnValue;
	}

	while (this->workFunc != NULL)
		scond_wait(this->condWork, this->mutex);

	returnValue = this->ret;

	slock_unlock(this->mutex);

	return returnValue;
}
Esempio n. 29
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;
}
Esempio n. 30
0
static void libusb_hid_device_send_control(void *data,
      uint8_t* data_buf, size_t size)
{
   struct libusb_adapter *adapter = (struct libusb_adapter*)data;

   if (!adapter)
      return;

   slock_lock(adapter->send_control_lock);

   if (fifo_write_avail(adapter->send_control_buffer) >= size + sizeof(size))
   {
      fifo_write(adapter->send_control_buffer, &size, sizeof(size));
      fifo_write(adapter->send_control_buffer, data_buf, size);
   }
   else
   {
      RARCH_WARN("adapter write buffer is full, cannot write send control\n");
   }
   slock_unlock(adapter->send_control_lock);
}