예제 #1
0
static void
wq_init(workqueue_t *wq, int nfiles)
{
	int throttle, nslots, i;

	if (getenv("CTFMERGE_MAX_SLOTS"))
		nslots = atoi(getenv("CTFMERGE_MAX_SLOTS"));
	else
		nslots = MERGE_PHASE1_MAX_SLOTS;

	if (getenv("CTFMERGE_PHASE1_BATCH_SIZE"))
		wq->wq_maxbatchsz = atoi(getenv("CTFMERGE_PHASE1_BATCH_SIZE"));
	else
		wq->wq_maxbatchsz = MERGE_PHASE1_BATCH_SIZE;

	nslots = MIN(nslots, (nfiles + wq->wq_maxbatchsz - 1) /
	    wq->wq_maxbatchsz);

	wq->wq_wip = xcalloc(sizeof (wip_t) * nslots);
	wq->wq_nwipslots = nslots;
	wq->wq_nthreads = MIN(sysconf(_SC_NPROCESSORS_ONLN) * 3 / 2, nslots);
	wq->wq_thread = xmalloc(sizeof (pthread_t) * wq->wq_nthreads);

	if (getenv("CTFMERGE_INPUT_THROTTLE"))
		throttle = atoi(getenv("CTFMERGE_INPUT_THROTTLE"));
	else
		throttle = MERGE_INPUT_THROTTLE_LEN;
	wq->wq_ithrottle = throttle * wq->wq_nthreads;

	debug(1, "Using %d slots, %d threads\n", wq->wq_nwipslots,
	    wq->wq_nthreads);

	wq->wq_next_batchid = 0;

	for (i = 0; i < nslots; i++) {
		pthread_mutex_init(&wq->wq_wip[i].wip_lock, NULL);
		wq->wq_wip[i].wip_batchid = wq->wq_next_batchid++;
	}

	pthread_mutex_init(&wq->wq_queue_lock, NULL);
	wq->wq_queue = fifo_new();
	pthread_cond_init(&wq->wq_work_avail, NULL);
	pthread_cond_init(&wq->wq_work_removed, NULL);
	wq->wq_ninqueue = nfiles;
	wq->wq_nextpownum = 0;

	pthread_mutex_init(&wq->wq_donequeue_lock, NULL);
	wq->wq_donequeue = fifo_new();
	wq->wq_lastdonebatch = -1;

	pthread_cond_init(&wq->wq_done_cv, NULL);

	pthread_cond_init(&wq->wq_alldone_cv, NULL);
	wq->wq_alldone = 0;

	barrier_init(&wq->wq_bar1, wq->wq_nthreads);
	barrier_init(&wq->wq_bar2, wq->wq_nthreads);

	wq->wq_nomorefiles = 0;
}
예제 #2
0
파일: init_ev.c 프로젝트: yuyang0/yaspider
void init_ev()
{
    main_base = event_base_new();
    dns_base = evdns_base_new(main_base, 1);
    
    ready_sites_fifo = fifo_new(NULL);
    wait_sites_fifo = fifo_new(NULL);
    /* set timer */
    struct event *ev;
    struct timeval tv;
    tv.tv_sec = 0;
    tv.tv_usec = 50000;         /* 30 milliseconds */
    ev = event_new(main_base, -1, EV_TIMEOUT | EV_PERSIST, timer_cb, NULL);
    event_add(ev, &tv);
}
예제 #3
0
파일: keeper.c 프로젝트: AlexKordic/lanes
// in: linda_ud, key, ...
// out: true|false
int keepercall_send( lua_State* L)
{
	keeper_fifo* fifo;
	int n = lua_gettop( L) - 2;
	push_table( L, 1);                           // ud key ... fifos
	// get the fifo associated to this key in this linda, create it if it doesn't exist
	lua_pushvalue( L, 2);                        // ud key ... fifos key
	lua_rawget( L, -2);                          // ud key ... fifos fifo
	if( lua_isnil( L, -1))
	{
		lua_pop( L, 1);                            // ud key ... fifos
		fifo_new( L);                              // ud key ... fifos fifo
		lua_pushvalue( L, 2);                      // ud key ... fifos fifo key
		lua_pushvalue( L, -2);                     // ud key ... fifos fifo key fifo
		lua_rawset( L, -4);                        // ud key ... fifos fifo
	}
	lua_remove( L, -2);                          // ud key ... fifo
	fifo = (keeper_fifo*) lua_touserdata( L, -1);
	if( fifo->limit >= 0 && fifo->count + n > fifo->limit)
	{
		lua_settop( L, 0);                         //
		lua_pushboolean( L, 0);                    // false
	}
	else
	{
		fifo = prepare_fifo_access( L, -1);
		lua_replace( L, 2);                        // ud fifo ...
		fifo_push( L, fifo, n);                    // ud fifo
		lua_settop( L, 0);                         //
		lua_pushboolean( L, 1);                    // true
	}
	return 1;
}
예제 #4
0
/* Add an operation to the queue for tile @index
 * Note: if an operation affects more than one tile, it must be added once per tile.
 *
 * Concurrency: This function is not thread-safe on the same @self instance. */
void
operation_queue_add(OperationQueue *self, TileIndex index, OperationDataDrawDab *op)
{
    while (!tile_map_contains(self->tile_map, index)) {
#ifdef HEAVY_DEBUG
        operation_queue_resize(self, self->tile_map->size+1);
#else
        operation_queue_resize(self, self->tile_map->size*2);
#endif
    }

    Fifo **queue_pointer = (Fifo **)tile_map_get(self->tile_map, index);
    Fifo *op_queue = *queue_pointer;

    if (op_queue == NULL) {
        // Lazy initialization
        op_queue = fifo_new();
        *queue_pointer = op_queue;
    }

    if (fifo_peek_first(op_queue) == NULL) {
        // Critical section, not thread-safe
       if (!(self->dirty_tiles_n < self->tile_map->size*2*self->tile_map->size*2)) {
           // Prune duplicate tiles that cause us to almost exceed max
           self->dirty_tiles_n = remove_duplicate_tiles(self->dirty_tiles, self->dirty_tiles_n);
       }
       assert(self->dirty_tiles_n < self->tile_map->size*2*self->tile_map->size*2);
       self->dirty_tiles[self->dirty_tiles_n++] = index;
    }
    fifo_push(op_queue, (void *)op);
}
예제 #5
0
// in: linda_ud key n
// out: true or nil
int keepercall_limit( lua_State* L)
{
	keeper_fifo* fifo;
	int limit = (int) lua_tointeger( L, 3);
	push_table( L, 1);                                 // ud key n fifos
	lua_replace( L, 1);                                // fifos key n
	lua_pop( L, 1);                                    // fifos key
	lua_pushvalue( L, -1);                             // fifos key key
	lua_rawget( L, -3);                                // fifos key fifo|nil
	fifo = (keeper_fifo*) lua_touserdata( L, -1);
	if( fifo ==  NULL)
	{                                                  // fifos key nil
		lua_pop( L, 1);                                  // fifos key
		fifo_new( L);                                    // fifos key fifo
		fifo = (keeper_fifo*) lua_touserdata( L, -1);
		lua_rawset( L, -3);                              // fifos
	}
	// remove any clutter on the stack
	lua_settop( L, 0);
	// return true if we decide that blocked threads waiting to write on that key should be awakened
	// this is the case if we detect the key was full but it is no longer the case
	if(
			 ((fifo->limit >= 0) && (fifo->count >= fifo->limit)) // the key was full if limited and count exceeded the previous limit
		&& ((limit < 0) || (fifo->count < limit)) // the key is not full if unlimited or count is lower than the new limit
	)
	{
		lua_pushboolean( L, 1);
	}
	// set the new limit
	fifo->limit = limit;
	// return 0 or 1 value
	return lua_gettop( L);
}
예제 #6
0
파일: keeper.c 프로젝트: AlexKordic/lanes
//in: linda_ud key [val]
int keepercall_set( lua_State* L)
{
	STACK_GROW( L, 6);
	// make sure we have a value on the stack
	if( lua_gettop( L) == 2)                          // ud key val?
	{
		lua_pushnil( L);                                // ud key nil
	}

	// retrieve fifos associated with the linda
	push_table( L, 1);                                // ud key val fifos
	lua_replace( L, 1);                               // fifos key val

	if( !lua_isnil( L, 3)) // set/replace contents stored at the specified key?
	{
		keeper_fifo* fifo;
		lua_pushvalue( L, -2);                          // fifos key val key
		lua_rawget( L, 1);                              // fifos key val fifo|nil
		fifo = (keeper_fifo*) lua_touserdata( L, -1);
		if( fifo == NULL) // might be NULL if we set a nonexistent key to nil
		{
			lua_pop( L, 1);                               // fifos key val
			fifo_new( L);                                 // fifos key val fifo
			lua_pushvalue( L, 2);                         // fifos key val fifo key
			lua_pushvalue( L, -2);                        // fifos key val fifo key fifo
			lua_rawset( L, 1);                            // fifos key val fifo
		}
		else // the fifo exists, we just want to clear its contents
		{
			// empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
			lua_newtable( L);                             // fifos key val fifo {}
			lua_setuservalue( L, -2);                     // fifos key val fifo
			fifo->first = 1;
			fifo->count = 0;
		}
		fifo = prepare_fifo_access( L, -1);
		lua_insert( L, -2);                             // fifos key fifo val
		fifo_push( L, fifo, 1);                         // fifos key fifo
	}
	else // val == nil                                // fifos key nil
	{
		keeper_fifo* fifo;
		lua_pop( L, 1);                                 // fifos key
		lua_rawget( L, 1);                              // fifos fifo|nil
		// empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
		fifo = (keeper_fifo*) lua_touserdata( L, -1);
		if( fifo != NULL) // might be NULL if we set a nonexistent key to nil
		{
			lua_newtable( L);                             // fifos fifo {}
			lua_setuservalue( L, -2);                     // fifos fifo
			fifo->first = 1;
			fifo->count = 0;
		}
	}
	return 0;
}
예제 #7
0
파일: ffemu.c 프로젝트: Wyrick/RetroArch
static bool init_thread(ffemu_t *handle)
{
   handle->lock = slock_new();
   handle->cond_lock = slock_new();
   handle->cond = scond_new();
   handle->audio_fifo = fifo_new(32000 * sizeof(int16_t) * handle->params.channels * MAX_FRAMES / 60);
   handle->attr_fifo = fifo_new(sizeof(struct ffemu_video_data) * MAX_FRAMES);
   handle->video_fifo = fifo_new(handle->params.fb_width * handle->params.fb_height *
            handle->video.pix_size * MAX_FRAMES);

   handle->alive = true;
   handle->can_sleep = true;
   handle->thread = sthread_create(ffemu_thread, handle);

   assert(handle->lock && handle->cond_lock &&
      handle->cond && handle->audio_fifo &&
      handle->attr_fifo && handle->video_fifo && handle->thread);

   return true;
}
예제 #8
0
static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency)
{
   (void)device;
   if (SDL_WasInit(0) == 0)
   {
      if (SDL_Init(SDL_INIT_AUDIO) < 0)
         return NULL;
   }
   else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0)
      return NULL;

   sdl_audio_t *sdl = (sdl_audio_t*)calloc(1, sizeof(*sdl));
   if (!sdl)
      return NULL;

   // We have to buffer up some data ourselves, so we let SDL carry approx half of the latency. SDL double buffers audio and we do as well.
   int frames = find_num_frames(rate, latency / 4);

   SDL_AudioSpec spec = {0};
   spec.freq = rate;
   spec.format = AUDIO_S16SYS;
   spec.channels = 2;
   spec.samples = frames; // This is in audio frames, not samples ... :(
   spec.callback = sdl_audio_cb;
   spec.userdata = sdl;

   SDL_AudioSpec out;

   if (SDL_OpenAudio(&spec, &out) < 0)
   {
      RARCH_ERR("Failed to open SDL audio: %s\n", SDL_GetError());
      free(sdl);
      return 0;
   }
   g_settings.audio.out_rate = out.freq;

   sdl->lock = slock_new();
   sdl->cond = scond_new();

   RARCH_LOG("SDL audio: Requested %u ms latency, got %d ms\n", latency, (int)(out.samples * 4 * 1000 / g_settings.audio.out_rate));

   // Create a buffer twice as big as needed and prefill the buffer.
   size_t bufsize = out.samples * 4 * sizeof(int16_t);
   void *tmp = calloc(1, bufsize);
   sdl->buffer = fifo_new(bufsize);
   if (tmp)
   {
      fifo_write(sdl->buffer, tmp, bufsize);
      free(tmp);
   }

   SDL_PauseAudio(0);
   return sdl;
}
예제 #9
0
static cell_audio_handle_t audioport_init(const struct cell_audio_params *params)
{
   init_audioport();

   audioport_t *handle = calloc(1, sizeof(*handle));

   CellAudioPortParam port_params = {
      .nChannel = params->channels,
      .nBlock = 8,
      .attr = 0
   };

   handle->channels = params->channels;

   handle->sample_cb = params->sample_cb;
   handle->userdata = params->userdata;
   handle->buffer = fifo_new(params->buffer_size ? params->buffer_size : 4096);

   if (params->samplerate != 48000)
   {
      handle->re = resampler_new(resampler_cb, 48000.0 / params->samplerate, params->channels, handle);
   }

   sys_lwmutex_attribute_t attr;
   sys_lwmutex_attribute_t attr2;
   sys_lwmutex_attribute_t cond_attr;

   sys_lwmutex_attribute_initialize(attr);
   sys_lwmutex_create(&handle->lock, &attr);

   sys_lwmutex_attribute_initialize(attr2);
   sys_lwmutex_create(&handle->cond_lock, &attr2);

   sys_lwcond_attribute_initialize(cond_attr);
   sys_lwcond_create(&handle->cond, &handle->cond_lock, &cond_attr);

   cellAudioPortOpen(&port_params, &handle->audio_port);
   cellAudioPortStart(handle->audio_port);

   pthread_create(&handle->thread, NULL, event_loop, handle);
   return handle;
}

static void audioport_pause(cell_audio_handle_t handle)
{
   audioport_t *port = handle;
   port->is_paused = 1;
   cellAudioPortStop(port->audio_port);
}
예제 #10
0
int main(int argc, char *argv[])
{
    random_fd = open("/dev/urandom", O_RDONLY);
    if (random_fd < 0) {
        perror("Could not open /dev/urandom");
        return random_fd;
    }

    fifo = fifo_new(16);
    if (!fifo) {
        perror("Could not create fifo");
        close(random_fd);
        return -1;
    }

    struct producer ps[] = {
        {.start=5, .end=60},
        {.start=50, .end=125},
예제 #11
0
static void *rs_init(const char *device, unsigned rate, unsigned latency)
{
   int channels, format;
   rsd_t *rsd = (rsd_t*)calloc(1, sizeof(rsd_t));
   if (!rsd)
      return NULL;

   rsound_t *rd;

   if (rsd_init(&rd) < 0)
   {
      free(rsd);
      return NULL;
   }

   rsd->cond_lock = slock_new();
   rsd->cond = scond_new();

   rsd->buffer = fifo_new(1024 * 4);

   channels = 2;
   format   = RSD_S16_NE;

   rsd_set_param(rd, RSD_CHANNELS, &channels);
   rsd_set_param(rd, RSD_SAMPLERATE, &rate);
   rsd_set_param(rd, RSD_LATENCY, &latency);

   if (device)
      rsd_set_param(rd, RSD_HOST, (void*)device);

   rsd_set_param(rd, RSD_FORMAT, &format);

   rsd_set_callback(rd, rsound_audio_cb, err_cb, 256, rsd);

   if (rsd_start(rd) < 0)
   {
      free(rsd);
      rsd_free(rd);
      return NULL;
   }

   rsd->rd = rd;
   return rsd;
}
예제 #12
0
파일: fifo_test.c 프로젝트: lijie/siriusdb
static void test2() {
  fifo_t *f1 = fifo_new(1024 * 4);
  int i;
  void *p;

  for (i = 0; i < 1023; i++) {
    p = fifo_alloc(f1, 13);
    assert(p);
    *(int *)p = i;
    fifo_put(f1, p, 13);

    p = fifo_get(f1, 13);
    assert(p);
    assert(*(int *)p == i);
    fifo_end(f1, p, 13);
  }

  assert(fifo_empty(f1));
}
예제 #13
0
파일: keeper.c 프로젝트: AlexKordic/lanes
// in: linda_ud key n
// out: nothing
int keepercall_limit( lua_State* L)
{
	keeper_fifo* fifo;
	int limit = (int) lua_tointeger( L, 3);
	push_table( L, 1);                                 // ud key n fifos
	lua_replace( L, 1);                                // fifos key n
	lua_pop( L, 1);                                    // fifos key
	lua_pushvalue( L, -1);                             // fifos key key
	lua_rawget( L, -3);                                // fifos key fifo
	fifo = (keeper_fifo*) lua_touserdata( L, -1);
	if( fifo ==  NULL)
	{
		lua_pop( L, 1);                                  // fifos key
		fifo_new( L);                                    // fifos key fifo
		fifo = (keeper_fifo*) lua_touserdata( L, -1);
		lua_rawset( L, -3);                              // fifos
	}
	fifo->limit = limit;
	return 0;
}
예제 #14
0
task task_new(void)
{
    task p;
    int err;

    if ((p = calloc(1, sizeof *p)) == NULL)
        return NULL;

    if ((err = pthread_rwlock_init(&p->sublock, NULL)) != 0) {
        free(p);
        return NULL;
    }

    if ((p->q = fifo_new(METAL_TASK_QUEUE_SIZE)) == NULL) {
        free(p);
        return NULL;
    }

    p->name[0] = '\0';
    p->tid = 0; // system tid. Hmm... -1 is not allowed.

    return p;
}
예제 #15
0
파일: fifo_test.c 프로젝트: lijie/siriusdb
static void test3() {
  fifo_t *f1 = fifo_new(1024 * 4);
  int i;
  void *p;

  for (i = 0; i < 1023; i++) {
    p = fifo_alloc(f1, 13);
    assert(p);
    *(int *)p = i;
    fifo_put(f1, p, 13);

    p = fifo_extend(f1, p, 13, 13 * 2);
    assert(p);
    fifo_put(f1, p, 26);

    printf("%u %u\n", f1->pt, f1->gt);
    p = fifo_get(f1, 26);
    assert(p);
    assert(*(int *)p == i);
    fifo_end(f1, p, 26);
  }

  assert(fifo_empty(f1));
}
예제 #16
0
bool initialize_packet_slinger()
{
	if (slinger_initialized) return true;

	initialize_slinger_frame_lookup();

	e_memset(link_state, 0, 2 * sizeof(slinger_link_state_t));

	link_state[slinger_link_highrate].link_enum = slinger_link_highrate;
	link_state[slinger_link_biphase].link_enum = slinger_link_biphase;

	link_state[slinger_link_highrate].downlink_pq = create_pq(SLINGER_MAX_PRIORITY);
	link_state[slinger_link_biphase].downlink_pq = create_pq(SLINGER_MAX_PRIORITY);
	link_state[slinger_link_highrate].resend_fifo = fifo_new();
	link_state[slinger_link_biphase].resend_fifo = fifo_new();

	link_state[slinger_link_highrate].control_fifo_queue = fifo_new();
	link_state[slinger_link_highrate].downlink_fifo = fifo_new();
	link_state[slinger_link_biphase].control_fifo_queue = fifo_new();
	link_state[slinger_link_biphase].downlink_fifo = fifo_new();

	link_state[slinger_link_highrate].fifo_pause_us = 50000;
	link_state[slinger_link_biphase].fifo_pause_us = 9984;

	link_state[slinger_link_highrate].device = bstrdup(err, "/dev/ttyHighRate");
	link_state[slinger_link_biphase].device = bstrdup(err, "/dev/bi0_pci");

	link_state[slinger_link_biphase].bps = 1000000;

	/// Initialize the downlink rate for TDRSS Omni-directional
	set_slinger_dl_rate(CommandData.packet_slinger.downlink_rate_bps);

	initialize_slinger_tables();
	if (!slinger_xml_load_preferences("/data/etc/packetslinger.xml")) return false;

	slinger_initialized = true;
	return true;
}
예제 #17
0
static void *alsa_thread_init(const char *device,
      unsigned rate, unsigned latency)
{
   snd_pcm_uframes_t buffer_size;
   snd_pcm_format_t format;
   snd_pcm_hw_params_t *params    = NULL;
   snd_pcm_sw_params_t *sw_params = NULL;
   const char *alsa_dev           = device ? device : "default";
   unsigned latency_usec          = latency * 1000 / 2;
   unsigned channels              = 2;
   unsigned periods               = 4;
   alsa_thread_t            *alsa = (alsa_thread_t*)
      calloc(1, sizeof(alsa_thread_t));

   if (!alsa)
      return NULL;

   TRY_ALSA(snd_pcm_open(&alsa->pcm, alsa_dev, SND_PCM_STREAM_PLAYBACK, 0));

   TRY_ALSA(snd_pcm_hw_params_malloc(&params));
   alsa->has_float = alsathread_find_float_format(alsa->pcm, params);
   format = alsa->has_float ? SND_PCM_FORMAT_FLOAT : SND_PCM_FORMAT_S16;

   TRY_ALSA(snd_pcm_hw_params_any(alsa->pcm, params));
   TRY_ALSA(snd_pcm_hw_params_set_access(
            alsa->pcm, params, SND_PCM_ACCESS_RW_INTERLEAVED));
   TRY_ALSA(snd_pcm_hw_params_set_format(alsa->pcm, params, format));
   TRY_ALSA(snd_pcm_hw_params_set_channels(alsa->pcm, params, channels));
   TRY_ALSA(snd_pcm_hw_params_set_rate(alsa->pcm, params, rate, 0));

   TRY_ALSA(snd_pcm_hw_params_set_buffer_time_near(
            alsa->pcm, params, &latency_usec, NULL));
   TRY_ALSA(snd_pcm_hw_params_set_periods_near(
            alsa->pcm, params, &periods, NULL));

   TRY_ALSA(snd_pcm_hw_params(alsa->pcm, params));

   /* Shouldn't have to bother with this, 
    * but some drivers are apparently broken. */
   if (snd_pcm_hw_params_get_period_size(params, &alsa->period_frames, NULL))
      snd_pcm_hw_params_get_period_size_min(
            params, &alsa->period_frames, NULL);
   RARCH_LOG("ALSA: Period size: %d frames\n", (int)alsa->period_frames);
   if (snd_pcm_hw_params_get_buffer_size(params, &buffer_size))
      snd_pcm_hw_params_get_buffer_size_max(params, &buffer_size);
   RARCH_LOG("ALSA: Buffer size: %d frames\n", (int)buffer_size);

   alsa->buffer_size = snd_pcm_frames_to_bytes(alsa->pcm, buffer_size);
   alsa->period_size = snd_pcm_frames_to_bytes(alsa->pcm, alsa->period_frames);

   TRY_ALSA(snd_pcm_sw_params_malloc(&sw_params));
   TRY_ALSA(snd_pcm_sw_params_current(alsa->pcm, sw_params));
   TRY_ALSA(snd_pcm_sw_params_set_start_threshold(
            alsa->pcm, sw_params, buffer_size / 2));
   TRY_ALSA(snd_pcm_sw_params(alsa->pcm, sw_params));

   snd_pcm_hw_params_free(params);
   snd_pcm_sw_params_free(sw_params);

   alsa->fifo_lock = slock_new();
   alsa->cond_lock = slock_new();
   alsa->cond = scond_new();
   alsa->buffer = fifo_new(alsa->buffer_size);
   if (!alsa->fifo_lock || !alsa->cond_lock || !alsa->cond || !alsa->buffer)
      goto error;

   alsa->worker_thread = sthread_create(alsa_worker_thread, alsa);
   if (!alsa->worker_thread)
   {
      RARCH_ERR("error initializing worker thread");
      goto error;
   }

   return alsa;

error:
   RARCH_ERR("ALSA: Failed to initialize...\n");
   if (params)
      snd_pcm_hw_params_free(params);

   if (sw_params)
      snd_pcm_sw_params_free(sw_params);

   alsa_thread_free(alsa);

   return NULL;
}
예제 #18
0
//in: linda_ud key [[val] ...]
//out: true or nil
int keepercall_set( lua_State* L)
{
	bool_t should_wake_writers = FALSE;
	STACK_GROW( L, 6);

	// retrieve fifos associated with the linda
	push_table( L, 1);                                // ud key [val [, ...]] fifos
	lua_replace( L, 1);                               // fifos key [val [, ...]]

	// make sure we have a value on the stack
	if( lua_gettop( L) == 2)                          // fifos key
	{
		keeper_fifo* fifo;
		lua_pushvalue( L, -1);                          // fifos key key
		lua_rawget( L, 1);                              // fifos key fifo|nil
		// empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
		fifo = (keeper_fifo*) lua_touserdata( L, -1);
		if( fifo != NULL) // might be NULL if we set a nonexistent key to nil
		{                                               // fifos key fifo
			if( fifo->limit < 0) // fifo limit value is the default (unlimited): we can totally remove it
			{
				lua_pop( L, 1);                             // fifos key
				lua_pushnil( L);                            // fifos key nil
				lua_rawset( L, -3);                         // fifos
			}
			else
			{
				// we create room if the fifo was full but it is no longer the case
				should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit);
				lua_remove( L, -2);                         // fifos fifo
				lua_newtable( L);                           // fifos fifo {}
				lua_setuservalue( L, -2);                   // fifos fifo
				fifo->first = 1;
				fifo->count = 0;
			}
		}
	}
	else // set/replace contents stored at the specified key?
	{
		int count = lua_gettop( L) - 2; // number of items we want to store
		keeper_fifo* fifo;                              // fifos key [val [, ...]]
		lua_pushvalue( L, 2);                           // fifos key [val [, ...]] key
		lua_rawget( L, 1);                              // fifos key [val [, ...]] fifo|nil
		fifo = (keeper_fifo*) lua_touserdata( L, -1);
		if( fifo == NULL) // can be NULL if we store a value at a new key
		{                                               // fifos key [val [, ...]] nil
			// no need to wake writers in that case, because a writer can't wait on an inexistent key
			lua_pop( L, 1);                               // fifos key [val [, ...]]
			fifo_new( L);                                 // fifos key [val [, ...]] fifo
			lua_pushvalue( L, 2);                         // fifos key [val [, ...]] fifo key
			lua_pushvalue( L, -2);                        // fifos key [val [, ...]] fifo key fifo
			lua_rawset( L, 1);                            // fifos key [val [, ...]] fifo
		}
		else // the fifo exists, we just want to update its contents
		{                                               // fifos key [val [, ...]] fifo
			// we create room if the fifo was full but it is no longer the case
			should_wake_writers = (fifo->limit > 0) && (fifo->count >= fifo->limit) && (count < fifo->limit);
			// empty the fifo for the specified key: replace uservalue with a virgin table, reset counters, but leave limit unchanged!
			lua_newtable( L);                             // fifos key [val [, ...]] fifo {}
			lua_setuservalue( L, -2);                     // fifos key [val [, ...]] fifo
			fifo->first = 1;
			fifo->count = 0;
		}
		fifo = prepare_fifo_access( L, -1);
		// move the fifo below the values we want to store
		lua_insert( L, 3);                              // fifos key fifo [val [, ...]]
		fifo_push( L, fifo, count);                     // fifos key fifo
	}
	return should_wake_writers ? (lua_pushboolean( L, 1), 1) : 0;
}
예제 #19
0
static void *ps3_audio_init(const char *device,
      unsigned rate, unsigned latency)
{
   CellAudioPortParam params;
   ps3_audio_t *data = NULL;

   (void)latency;
   (void)device;
   (void)rate;

   data = calloc(1, sizeof(*data));
   if (!data)
      return NULL;

   cellAudioInit();

   params.numChannels = AUDIO_CHANNELS;
   params.numBlocks = AUDIO_BLOCKS;
#if 0
#ifdef HAVE_HEADSET
   if(global->console.sound.mode == SOUND_MODE_HEADSET)
      params.param_attrib = CELL_AUDIO_PORTATTR_OUT_SECONDARY;
   else
#endif
#endif
      params.param_attrib = 0;

   if (cellAudioPortOpen(&params, &data->audio_port) != CELL_OK)
   {
      cellAudioQuit();
      free(data);
      return NULL;
   }

   data->buffer = fifo_new(CELL_AUDIO_BLOCK_SAMPLES * 
         AUDIO_CHANNELS * AUDIO_BLOCKS * sizeof(float));

#ifdef __PSL1GHT__
   sys_lwmutex_attr_t lock_attr = 
   {SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"};
   sys_lwmutex_attr_t cond_lock_attr =
   {SYS_LWMUTEX_ATTR_PROTOCOL, SYS_LWMUTEX_ATTR_RECURSIVE, "\0"};
   sys_lwcond_attribute_t cond_attr = {"\0"};
#else
   sys_lwmutex_attribute_t lock_attr;
   sys_lwmutex_attribute_t cond_lock_attr;
   sys_lwcond_attribute_t cond_attr;

   sys_lwmutex_attribute_initialize(lock_attr);
   sys_lwmutex_attribute_initialize(cond_lock_attr);
   sys_lwcond_attribute_initialize(cond_attr);
#endif

   sys_lwmutex_create(&data->lock, &lock_attr);
   sys_lwmutex_create(&data->cond_lock, &cond_lock_attr);
   sys_lwcond_create(&data->cond, &data->cond_lock, &cond_attr);

   cellAudioPortStart(data->audio_port);
   data->started = true;
   sys_ppu_thread_create(&data->thread, event_loop,
#ifdef __PSL1GHT__
   data,
#else
   (uint64_t)data,
#endif
   1500, 0x1000, SYS_PPU_THREAD_CREATE_JOINABLE, (char*)"sound");

   return data;
}
예제 #20
0
int main(void)
{
    fifo f;
    size_t i, nelem;
    status_t rc;
    char dummydata[1000] = "Hello";
    clock_t stop, start;
    double duration;


    nelem = 1*1000*1000;
    f = fifo_new(nelem);

#if 1

    /* Fill the fifo completely */
    start = clock();
    for (i = 0; i < nelem; i++) {
        rc = fifo_add(f, dummydata);
        assert(rc != 0);
    }
    stop = clock();
    duration = (stop - start) * 1.0 / CLOCKS_PER_SEC;
    printf("%s: Added %lu elements in %f seconds\n", __FILE__, (unsigned long)nelem, duration);

    assert(fifo_nelem(f) == nelem);

    /* Test fifo_peek() */
    for (i = 0; i < nelem; i++) {
        const char *s = fifo_peek(f, i);
        /* Stupid workaround for gcc 4.0.2 optimization in conjunction with assert() */
        int xi;
        xi = (s != NULL); assert(xi);
        xi = (strcmp(s, dummydata) == 0); assert(xi);
    }

    /* Add a new one, this should fail */
    assert(fifo_add(f, dummydata) == 0);

    /* Now read two and then add one. That should be possible */
    assert(fifo_get(f));
    assert(fifo_get(f));
    assert(fifo_nelem(f) == nelem - 2);
    assert(fifo_add(f, dummydata) != 0);
    assert(fifo_nelem(f) == nelem - 1);

    /* Test fifo_peek() */
    for (i = 0; i < fifo_nelem(f); i++) {
        const char *s = fifo_peek(f, i);
        int xi;
        xi = (s != NULL); assert(xi);
        xi = (strcmp(s, dummydata) == 0); assert(xi);
    }

    /* The first should be OK, the next must fail */
    assert(fifo_add(f, dummydata) != 0);
    assert(fifo_nelem(f) == nelem);

    assert(fifo_add(f, dummydata) == 0);
    assert(fifo_nelem(f) == nelem);

    start = clock();
    for (i = 0; i < nelem; i++) {
        char *x = fifo_get(f);
        (void)x;
    }
    stop = clock();
    duration = (stop - start) * 1.0 / CLOCKS_PER_SEC;
    printf("%s: Got %lu elements in %f seconds\n", __FILE__, (unsigned long)nelem, duration);

#endif

    /* Now check signalling and wait for data.
     * We start two threads, a reader and a writer.
     * The writer writes n times to the fifo and the reader
     * prints the data.
     * This thread joins the writer and calls fifo_wake() when
     * the writer is done, to stop the reader thread in a controlled
     * manner.
     */
     {
         pthread_t w, r;

        pthread_create(&r, NULL, reader, f);
        pthread_create(&w, NULL, writer, f);
        pthread_join(w, NULL);
        if (!fifo_wake(f))
            exit(EXIT_FAILURE);

        pthread_join(r, NULL);
     }

    fifo_free(f, free);
    return 0;
}
예제 #21
0
static void *coreaudio_init(const char *device,
      unsigned rate, unsigned latency)
{
   size_t fifo_size;
   UInt32 i_size;
   AudioStreamBasicDescription real_desc;
#ifdef OSX_PPC
   Component comp;
#else
   AudioComponent comp;
#endif
#ifndef TARGET_OS_IPHONE
   AudioChannelLayout layout               = {0};
#endif
   AURenderCallbackStruct cb               = {0};
   AudioStreamBasicDescription stream_desc = {0};
   bool component_unavailable              = false;
   static bool session_initialized         = false;
   coreaudio_t *dev                        = NULL;
#ifdef OSX_PPC
   ComponentDescription desc               = {0};
#else
   AudioComponentDescription desc          = {0};
#endif
   settings_t *settings                    = config_get_ptr();

   (void)session_initialized;
   (void)device;

   dev = (coreaudio_t*)calloc(1, sizeof(*dev));
   if (!dev)
      return NULL;

   dev->lock = slock_new();
   dev->cond = scond_new();

#if TARGET_OS_IPHONE
   if (!session_initialized)
   {
      session_initialized = true;
      AudioSessionInitialize(0, 0, coreaudio_interrupt_listener, 0);
      AudioSessionSetActive(true);
   }
#endif

   /* Create AudioComponent */
   desc.componentType = kAudioUnitType_Output;
#if TARGET_OS_IPHONE
   desc.componentSubType = kAudioUnitSubType_RemoteIO;
#else
   desc.componentSubType = kAudioUnitSubType_HALOutput;
#endif
   desc.componentManufacturer = kAudioUnitManufacturer_Apple;

#ifdef OSX_PPC
   comp = FindNextComponent(NULL, &desc);
#else
   comp = AudioComponentFindNext(NULL, &desc);
#endif
   if (comp == NULL)
      goto error;
   
#ifdef OSX_PPC
   component_unavailable = (OpenAComponent(comp, &dev->dev) != noErr);
#else
   component_unavailable = (AudioComponentInstanceNew(comp, &dev->dev) != noErr);
#endif

   if (component_unavailable)
      goto error;

#if !TARGET_OS_IPHONE
   if (device)
      choose_output_device(dev, device);
#endif

   dev->dev_alive = true;

   /* Set audio format */
   stream_desc.mSampleRate       = rate;
   stream_desc.mBitsPerChannel   = sizeof(float) * CHAR_BIT;
   stream_desc.mChannelsPerFrame = 2;
   stream_desc.mBytesPerPacket   = 2 * sizeof(float);
   stream_desc.mBytesPerFrame    = 2 * sizeof(float);
   stream_desc.mFramesPerPacket  = 1;
   stream_desc.mFormatID         = kAudioFormatLinearPCM;
   stream_desc.mFormatFlags      = kAudioFormatFlagIsFloat | 
      kAudioFormatFlagIsPacked | (is_little_endian() ? 
            0 : kAudioFormatFlagIsBigEndian);
   
   if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_StreamFormat,
         kAudioUnitScope_Input, 0, &stream_desc, sizeof(stream_desc)) != noErr)
      goto error;
   
   /* Check returned audio format. */
   i_size = sizeof(real_desc);
   if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, 
            kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr)
      goto error;

   if (real_desc.mChannelsPerFrame != stream_desc.mChannelsPerFrame)
      goto error;
   if (real_desc.mBitsPerChannel != stream_desc.mBitsPerChannel)
      goto error;
   if (real_desc.mFormatFlags != stream_desc.mFormatFlags)
      goto error;
   if (real_desc.mFormatID != stream_desc.mFormatID)
      goto error;

   RARCH_LOG("[CoreAudio]: Using output sample rate of %.1f Hz\n",
         (float)real_desc.mSampleRate);
   settings->audio.out_rate = real_desc.mSampleRate;

   /* Set channel layout (fails on iOS). */
#ifndef TARGET_OS_IPHONE
   layout.mChannelLayoutTag = kAudioChannelLayoutTag_Stereo;
   if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_AudioChannelLayout,
         kAudioUnitScope_Input, 0, &layout, sizeof(layout)) != noErr)
      goto error;
#endif

   /* Set callbacks and finish up. */
   cb.inputProc = audio_write_cb;
   cb.inputProcRefCon = dev;

   if (AudioUnitSetProperty(dev->dev, kAudioUnitProperty_SetRenderCallback,
         kAudioUnitScope_Input, 0, &cb, sizeof(cb)) != noErr)
      goto error;

   if (AudioUnitInitialize(dev->dev) != noErr)
      goto error;

   fifo_size = (latency * settings->audio.out_rate) / 1000;
   fifo_size *= 2 * sizeof(float);
   dev->buffer_size = fifo_size;

   dev->buffer = fifo_new(fifo_size);
   if (!dev->buffer)
      goto error;

   RARCH_LOG("[CoreAudio]: Using buffer size of %u bytes: (latency = %u ms)\n",
         (unsigned)fifo_size, latency);

   if (AudioOutputUnitStart(dev->dev) != noErr)
      goto error;

   return dev;

error:
   RARCH_ERR("[CoreAudio]: Failed to initialize driver ...\n");
   coreaudio_free(dev);
   return NULL;
}
예제 #22
0
파일: dsound.c 프로젝트: Joonie86/RetroArch
static void *dsound_init(const char *device, unsigned rate, unsigned latency)
{
   WAVEFORMATEX wfx      = {0};
   DSBUFFERDESC bufdesc  = {0};
   struct dsound_dev dev = {0};
   dsound_t          *ds = (dsound_t*)calloc(1, sizeof(*ds));

   if (!ds)
      goto error;

   InitializeCriticalSection(&ds->crit);

   if (device)
      dev.device = strtoul(device, NULL, 0);

   RARCH_LOG("DirectSound devices:\n");
#ifndef _XBOX
   DirectSoundEnumerate(enumerate_cb, &dev);
#endif

   if (DirectSoundCreate(dev.guid, &ds->ds, NULL) != DS_OK)
      goto error;

#ifndef _XBOX
   if (IDirectSound_SetCooperativeLevel(ds->ds, GetDesktopWindow(), DSSCL_PRIORITY) != DS_OK)
      goto error;
#endif

   wfx.wFormatTag        = WAVE_FORMAT_PCM;
   wfx.nChannels         = 2;
   wfx.nSamplesPerSec    = rate;
   wfx.wBitsPerSample    = 16;
   wfx.nBlockAlign       = 2 * sizeof(int16_t);
   wfx.nAvgBytesPerSec   = rate * 2 * sizeof(int16_t);

   ds->buffer_size       = (latency * wfx.nAvgBytesPerSec) / 1000;
   ds->buffer_size      /= CHUNK_SIZE;
   ds->buffer_size      *= CHUNK_SIZE;
   if (ds->buffer_size < 4 * CHUNK_SIZE)
      ds->buffer_size    = 4 * CHUNK_SIZE;

   RARCH_LOG("[DirectSound]: Setting buffer size of %u bytes\n", ds->buffer_size);
   RARCH_LOG("[DirectSound]: Latency = %u ms\n", (unsigned)((1000 * ds->buffer_size) / wfx.nAvgBytesPerSec));

   bufdesc.dwSize        = sizeof(DSBUFFERDESC);
   bufdesc.dwFlags       = 0;
#ifndef _XBOX
   bufdesc.dwFlags       = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_GLOBALFOCUS;
#endif
   bufdesc.dwBufferBytes = ds->buffer_size;
   bufdesc.lpwfxFormat   = &wfx;

   ds->event = CreateEvent(NULL, false, false, NULL);
   if (!ds->event)
      goto error;

   ds->buffer = fifo_new(4 * 1024);
   if (!ds->buffer)
      goto error;

   if (IDirectSound_CreateSoundBuffer(ds->ds, &bufdesc, &ds->dsb, 0) != DS_OK)
      goto error;

   IDirectSoundBuffer_SetVolume(ds->dsb, DSBVOLUME_MAX);
   IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0);

   dsound_clear_buffer(ds);

   if (IDirectSoundBuffer_Play(ds->dsb, 0, 0, DSBPLAY_LOOPING) != DS_OK)
      goto error;

   if (!dsound_start_thread(ds))
      goto error;

   return ds;

error:
   RARCH_ERR("[DirectSound] Error occured in init.\n");
   dsound_free(ds);
   return NULL;
}
예제 #23
0
static int add_adapter(void *data, struct libusb_device *dev)
{
   int rc;
   struct libusb_device_descriptor desc;
   const char *device_name         = NULL;
   struct libusb_adapter *old_head = NULL;
   struct libusb_hid          *hid = (struct libusb_hid*)data;
   struct libusb_adapter *adapter  = (struct libusb_adapter*)
      calloc(1, sizeof(struct libusb_adapter));

   if (!adapter)
      return -1;

   if (!hid)
   {
      free(adapter);
      RARCH_ERR("Allocation of adapter failed.\n");
      return -1;
   }

   rc = libusb_get_device_descriptor(dev, &desc);

   if (rc != LIBUSB_SUCCESS)
   {
      RARCH_ERR("Error getting device descriptor.\n");
      goto error;
   }

   adapter->device = dev;

   libusb_get_description(adapter->device, adapter);

   if (adapter->endpoint_in == 0)
   {
      RARCH_ERR("Could not find HID config for device.\n");
      goto error;
   }

   rc = libusb_open (adapter->device, &adapter->handle);

   if (rc != LIBUSB_SUCCESS)
   {
      RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n",
            (void*)adapter->device, desc.idVendor, desc.idProduct);
      goto error;
   }

   if (desc.iManufacturer)
   {
      libusb_get_string_descriptor_ascii(adapter->handle,
            desc.iManufacturer, adapter->manufacturer_name,
            sizeof(adapter->manufacturer_name));
#if 0
      RARCH_ERR(" Adapter Manufacturer name: %s\n",
            adapter->manufacturer_name);
#endif
   }

   if (desc.iProduct)
   {
      libusb_get_string_descriptor_ascii(adapter->handle,
            desc.iProduct, adapter->name,
            sizeof(adapter->name));
#if 0
      RARCH_ERR(" Adapter name: %s\n", adapter->name);
#endif
   }

   device_name   = (const char*)adapter->name;

   if (string_is_empty((const char*)adapter->name))
      goto error;

   adapter->send_control_lock = slock_new();
   adapter->send_control_buffer = fifo_new(4096);

   if (!adapter->send_control_lock || !adapter->send_control_buffer)
   {
      RARCH_ERR("Error creating send control buffer.\n");
      goto error;
   }

   adapter->slot = pad_connection_pad_init(hid->slots,
         device_name, desc.idVendor, desc.idProduct,
         adapter, &libusb_hid_device_send_control);

   if (adapter->slot == -1)
      goto error;

   if (!pad_connection_has_interface(hid->slots, adapter->slot))
   {
      RARCH_ERR(" Interface not found (%s).\n", adapter->name);
      goto error;
   }

   RARCH_LOG("Interface found: [%s].\n", adapter->name);

   if (libusb_kernel_driver_active(adapter->handle, 0) == 1
         && libusb_detach_kernel_driver(adapter->handle, 0))
   {
      RARCH_ERR("Error detaching handle 0x%p from kernel.\n", adapter->handle);
      goto error;
   }

   rc = libusb_claim_interface(adapter->handle, adapter->interface_number);

   if (rc != LIBUSB_SUCCESS)
   {
      RARCH_ERR("Error claiming interface %d .\n", adapter->interface_number);
      goto error;
   }

   RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n",
         adapter->device, desc.idVendor, desc.idProduct);

   libusb_hid_device_add_autodetect(adapter->slot,
         device_name, libusb_hid.ident, desc.idVendor, desc.idProduct);

   adapter->hid = hid;
   adapter->thread = sthread_create(adapter_thread, adapter);

   if (!adapter->thread)
   {
      RARCH_ERR("Error initializing adapter thread.\n");
      goto error;
   }

   old_head      = adapters.next;
   adapters.next = adapter;
   adapter->next = old_head;

   return 0;

error:
   if (adapter->thread)
      sthread_join(adapter->thread);
   if (adapter->send_control_lock)
      slock_free(adapter->send_control_lock);
   if (adapter->send_control_buffer)
      fifo_free(adapter->send_control_buffer);
   if (adapter)
      free(adapter);
   return -1;
}
예제 #24
0
static int add_adapter(void *data, usb_device_entry *dev)
{
   int rc;
   usb_devdesc desc;
   const char *device_name = NULL;
   struct wiiusb_adapter *old_head = NULL;
   struct wiiusb_hid *hid = (struct wiiusb_hid*)data;
   struct wiiusb_adapter *adapter  = (struct wiiusb_adapter*)
      calloc(1, sizeof(struct wiiusb_adapter));

   (void)rc;

   if (!adapter)
      return -1;

   if (!hid)
   {
      free(adapter);
      RARCH_ERR("Allocation of adapter failed.\n");
      return -1;
   }

   if (USB_OpenDevice(dev->device_id, dev->vid, dev->pid, &adapter->handle) < 0)
   {
      RARCH_ERR("Error opening device 0x%p (VID/PID: %04x:%04x).\n",
            (void*)&adapter->device, dev->vid, dev->pid);
      free(adapter);
      return -1;
   }

   adapter->device = *dev;

   USB_GetDescriptors(adapter->handle, &desc);

   wiiusb_get_description(&adapter->device, adapter, &desc);

   if (adapter->endpoint_in == 0)
   {
      RARCH_ERR("Could not find HID config for device.\n");
      goto error;
   }

   if (desc.iManufacturer)
   {
      USB_GetAsciiString(adapter->handle, desc.iManufacturer, 0,
            sizeof(adapter->manufacturer_name), adapter->manufacturer_name);
#if 0
      RARCH_ERR(" Adapter Manufacturer name: %s\n", adapter->manufacturer_name);
#endif
   }

   if (desc.iProduct)
   {
      USB_GetAsciiString(adapter->handle, desc.iProduct, 0,
            sizeof(adapter->name), adapter->name);
#if 0
      RARCH_ERR(" Adapter name: %s\n", adapter->name);
#endif
   }

   device_name = (const char *)adapter->name;

   adapter->send_control_lock = slock_new();
   adapter->send_control_buffer = fifo_new(4096);

   if (!adapter->send_control_lock || !adapter->send_control_buffer)
   {
      RARCH_ERR("Error creating send control buffer.\n");
      goto error;
   }

   adapter->slot = pad_connection_pad_init(hid->slots,
         device_name, desc.idVendor, desc.idProduct,
         adapter, &wiiusb_hid_device_send_control);

   if (adapter->slot == -1)
      goto error;

   if (!pad_connection_has_interface(hid->slots, adapter->slot))
   {
      RARCH_ERR(" Interface not found (%s).\n", adapter->name);
      goto error;
   }

   RARCH_LOG("Interface found: [%s].\n", adapter->name);

   RARCH_LOG("Device 0x%p attached (VID/PID: %04x:%04x).\n",
         adapter->device, desc.idVendor, desc.idProduct);

   wiiusb_hid_device_add_autodetect(adapter->slot,
         device_name, wiiusb_hid.ident, desc.idVendor, desc.idProduct);

   adapter->hid = hid;
   adapter->thread = sthread_create(adapter_thread, adapter);

   if (!adapter->thread)
   {
      RARCH_ERR("Error initializing adapter thread.\n");
      goto error;
   }

   adapter->data = memalign(32, 2048);

   old_head = adapters.next;
   adapters.next = adapter;
   adapter->next = old_head;

   USB_FreeDescriptors(&desc);

   USB_DeviceRemovalNotifyAsync(adapter->handle, wiiusb_hid_removalnotify_cb, (void *)hid);

   return 0;

error:
   if (adapter->thread)
      sthread_join(adapter->thread);
   if (adapter->send_control_lock)
      slock_free(adapter->send_control_lock);
   if (adapter->send_control_buffer)
      fifo_free(adapter->send_control_buffer);
   if (adapter)
      free(adapter);
   USB_FreeDescriptors(&desc);
   USB_CloseDevice(&adapter->handle);
   return -1;
}