Beispiel #1
0
void
_gsl_tick_stamp_set_leap (guint ticks)
{
  GSL_SPIN_LOCK (&global_tick_stamp_mutex);
  global_tick_stamp_leaps = ticks;
  GSL_SPIN_UNLOCK (&global_tick_stamp_mutex);
}
Beispiel #2
0
GslDataCache*
gsl_data_cache_new (GslDataHandle *dhandle,
		    guint	   padding)
{
  guint node_size = CONFIG_NODE_SIZE () / sizeof (GslDataType);
  GslDataCache *dcache;

  g_return_val_if_fail (dhandle != NULL, NULL);
  g_return_val_if_fail (padding > 0, NULL);
  g_return_val_if_fail (dhandle->name != NULL, NULL);
  g_assert (node_size == sfi_alloc_upper_power2 (node_size));
  g_return_val_if_fail (padding < node_size / 2, NULL);

  /* allocate new closed dcache if necessary */
  dcache = sfi_new_struct (GslDataCache, 1);
  dcache->dhandle = gsl_data_handle_ref (dhandle);
  dcache->open_count = 0;
  sfi_mutex_init (&dcache->mutex);
  dcache->ref_count = 1;
  dcache->node_size = node_size;
  dcache->padding = padding;
  dcache->max_age = 0;
  dcache->high_persistency = FALSE;
  dcache->n_nodes = 0;
  dcache->nodes = g_renew (GslDataCacheNode*, NULL, UPPER_POWER2 (dcache->n_nodes));

  GSL_SPIN_LOCK (&global_dcache_mutex);
  global_dcache_list = sfi_ring_append (global_dcache_list, dcache);
  global_dcache_count++;
  GSL_SPIN_UNLOCK (&global_dcache_mutex);

  return dcache;
}
Beispiel #3
0
void
gsl_data_cache_open (GslDataCache *dcache)
{
  g_return_if_fail (dcache != NULL);
  g_return_if_fail (dcache->ref_count > 0);

  GSL_SPIN_LOCK (&dcache->mutex);
  if (!dcache->open_count)
    {
      BseErrorType error;

      error = gsl_data_handle_open (dcache->dhandle);
      if (error)
	{
	  /* FIXME: this is pretty fatal, throw out zero blocks now? */
	  sfi_diag ("%s: failed to open \"%s\": %s", G_STRLOC, dcache->dhandle->name, bse_error_blurb (error));
	}
      else
	{
          dcache->high_persistency = gsl_data_handle_needs_cache (dcache->dhandle);
	  dcache->open_count = 1;
	  dcache->ref_count++;
	}
    }
  else
    dcache->open_count++;
  GSL_SPIN_UNLOCK (&dcache->mutex);
}
Beispiel #4
0
/**
 * @return GSL's execution tick stamp as unsigned 64bit integer
 *
 * Retrieve the global GSL tick counter stamp.
 * GSL increments its global tick stamp at certain intervals,
 * by specific amounts (refer to bse_engine_init() for further
 * details). The tick stamp is a non-wrapping, unsigned 64bit
 * integer greater than 0. Threads can schedule sleep interruptions
 * at certain tick stamps with sfi_thread_awake_after() and
 * sfi_thread_awake_before(). Tick stamp updating occours at
 * GSL engine block processing boundaries, so code that can
 * guarantee to not run across those boundaries (for instance
 * BseProcessFunc() functions) may use the macro GSL_TICK_STAMP
 * to retrieve the current tick in a faster manner (not involving
 * mutex locking). See also bse_module_tick_stamp().
 * This function is MT-safe and may be called from any thread.
 */
guint64
gsl_tick_stamp (void)
{
  guint64 stamp;

  GSL_SPIN_LOCK (&global_tick_stamp_mutex);
  stamp = bse_engine_exvar_tick_stamp;
  GSL_SPIN_UNLOCK (&global_tick_stamp_mutex);

  return stamp;
}
Beispiel #5
0
void
gsl_data_cache_unref (GslDataCache *dcache)
{
  g_return_if_fail (dcache != NULL);
 restart:
  g_return_if_fail (dcache->ref_count > 0);

  if (dcache->ref_count == 1)	/* possible destruction, need global lock */
    {
      g_return_if_fail (dcache->open_count == 0);

      GSL_SPIN_LOCK (&global_dcache_mutex);
      GSL_SPIN_LOCK (&dcache->mutex);
      if (dcache->ref_count != 1)
	{
	  /* damn, some other thread trapped in, restart */
	  GSL_SPIN_UNLOCK (&dcache->mutex);
	  GSL_SPIN_UNLOCK (&global_dcache_mutex);
	  goto restart;
	}
      dcache->ref_count = 0;
      global_dcache_list = sfi_ring_remove (global_dcache_list, dcache);
      GSL_SPIN_UNLOCK (&dcache->mutex);
      global_dcache_count--;
      global_dcache_n_aged_nodes -= dcache->n_nodes;
      GSL_SPIN_UNLOCK (&global_dcache_mutex);
      dcache_free (dcache);
    }
  else
    {
      GSL_SPIN_LOCK (&dcache->mutex);
      if (dcache->ref_count < 2)
	{
	  /* damn, some other thread trapped in, restart */
	  GSL_SPIN_UNLOCK (&dcache->mutex);
	  goto restart;
	}
      dcache->ref_count--;
      GSL_SPIN_UNLOCK (&dcache->mutex);
    }
}
Beispiel #6
0
/**
 * @return Current tick stamp and system time in micro seconds
 *
 * Get the system time of the last GSL global tick stamp update.
 * This function is MT-safe and may be called from any thread.
 */
GslTickStampUpdate
gsl_tick_stamp_last (void)
{
  GslTickStampUpdate ustamp;

  GSL_SPIN_LOCK (&global_tick_stamp_mutex);
  ustamp.tick_stamp = bse_engine_exvar_tick_stamp;
  ustamp.system_time = tick_stamp_system_time;
  GSL_SPIN_UNLOCK (&global_tick_stamp_mutex);

  return ustamp;
}
Beispiel #7
0
GslDataHandle*
gsl_data_handle_ref (GslDataHandle *dhandle)
{
  g_return_val_if_fail (dhandle != NULL, NULL);
  g_return_val_if_fail (dhandle->ref_count > 0, NULL);
  
  GSL_SPIN_LOCK (&dhandle->mutex);
  dhandle->ref_count++;
  GSL_SPIN_UNLOCK (&dhandle->mutex);
  
  return dhandle;
}
Beispiel #8
0
GslDataCache*
gsl_data_cache_ref (GslDataCache *dcache)
{
  g_return_val_if_fail (dcache != NULL, NULL);
  g_return_val_if_fail (dcache->ref_count > 0, NULL);

  /* we might get invoked with global_dcache_mutex locked */
  GSL_SPIN_LOCK (&dcache->mutex);
  dcache->ref_count++;
  GSL_SPIN_UNLOCK (&dcache->mutex);

  return dcache;
}
Beispiel #9
0
guint
gsl_data_handle_bit_depth (GslDataHandle *dhandle)
{
  guint n;

  g_return_val_if_fail (dhandle != NULL, 0);
  g_return_val_if_fail (dhandle->open_count > 0, 0);

  GSL_SPIN_LOCK (&dhandle->mutex);
  n = dhandle->open_count ? dhandle->setup.bit_depth : 0;
  GSL_SPIN_UNLOCK (&dhandle->mutex);

  return n;
}
Beispiel #10
0
GslLong
gsl_data_handle_length (GslDataHandle *dhandle)
{
  GslLong l;

  g_return_val_if_fail (dhandle != NULL, 0);
  g_return_val_if_fail (dhandle->open_count > 0, 0);

  GSL_SPIN_LOCK (&dhandle->mutex);
  l = dhandle->open_count ? dhandle->setup.n_values : 0;
  GSL_SPIN_UNLOCK (&dhandle->mutex);

  return l;
}
Beispiel #11
0
void
_gsl_tick_stamp_inc (void)
{
  volatile guint64 newstamp;
  guint64 systime;

  g_return_if_fail (global_tick_stamp_leaps > 0);

  systime = sfi_time_system ();
  newstamp = bse_engine_exvar_tick_stamp + global_tick_stamp_leaps;

  GSL_SPIN_LOCK (&global_tick_stamp_mutex);
  bse_engine_exvar_tick_stamp = newstamp;
  tick_stamp_system_time = systime;
  GSL_SPIN_UNLOCK (&global_tick_stamp_mutex);

  sfi_thread_emit_wakeups (newstamp);
}
Beispiel #12
0
void
gsl_data_handle_close (GslDataHandle *dhandle)
{
  gboolean need_unref;
  
  g_return_if_fail (dhandle != NULL);
  g_return_if_fail (dhandle->ref_count > 0);
  g_return_if_fail (dhandle->open_count > 0);
  
  GSL_SPIN_LOCK (&dhandle->mutex);
  dhandle->open_count--;
  need_unref = !dhandle->open_count;
  if (!dhandle->open_count)
    dhandle->vtable->close (dhandle);
  GSL_SPIN_UNLOCK (&dhandle->mutex);
  if (need_unref)
    gsl_data_handle_unref (dhandle);
}
Beispiel #13
0
void
gsl_data_handle_unref (GslDataHandle *dhandle)
{
  gboolean destroy;
  
  g_return_if_fail (dhandle != NULL);
  g_return_if_fail (dhandle->ref_count > 0);
  
  GSL_SPIN_LOCK (&dhandle->mutex);
  dhandle->ref_count--;
  destroy = dhandle->ref_count == 0;
  GSL_SPIN_UNLOCK (&dhandle->mutex);
  if (destroy)
    {
      g_return_if_fail (dhandle->open_count == 0);
      dhandle->vtable->destroy (dhandle);
    }
}
Beispiel #14
0
void
gsl_data_cache_close (GslDataCache *dcache)
{
  gboolean need_unref;

  g_return_if_fail (dcache != NULL);
  g_return_if_fail (dcache->ref_count > 0);
  g_return_if_fail (dcache->open_count > 0);

  GSL_SPIN_LOCK (&dcache->mutex);
  dcache->open_count--;
  need_unref = !dcache->open_count;
  if (!dcache->open_count)
    {
      dcache->high_persistency = FALSE;
      gsl_data_handle_close (dcache->dhandle);
    }
  GSL_SPIN_UNLOCK (&dcache->mutex);
  if (need_unref)
    gsl_data_cache_unref (dcache);
}
Beispiel #15
0
GslLong
gsl_data_handle_read (GslDataHandle *dhandle,
		      GslLong        value_offset,
		      GslLong        n_values,
		      gfloat        *values)
{
  GslLong l;
  
  g_return_val_if_fail (dhandle != NULL, -1);
  g_return_val_if_fail (dhandle->open_count > 0, -1);
  g_return_val_if_fail (value_offset >= 0, -1);
  if (n_values < 1)
    return 0;
  g_return_val_if_fail (values != NULL, -1);
  g_return_val_if_fail (value_offset < dhandle->setup.n_values, -1);
  
  n_values = MIN (n_values, dhandle->setup.n_values - value_offset);
  GSL_SPIN_LOCK (&dhandle->mutex);
  l = dhandle->vtable->read (dhandle, value_offset, n_values, values);
  GSL_SPIN_UNLOCK (&dhandle->mutex);
  
  return l;
}
Beispiel #16
0
GslErrorType
gsl_data_handle_open (GslDataHandle *dhandle)
{
  g_return_val_if_fail (dhandle != NULL, GSL_ERROR_INTERNAL);
  g_return_val_if_fail (dhandle->ref_count > 0, GSL_ERROR_INTERNAL);

  GSL_SPIN_LOCK (&dhandle->mutex);
  if (dhandle->open_count == 0)
    {
      GslErrorType error;

      memset (&dhandle->setup, 0, sizeof (dhandle->setup));
      error = dhandle->vtable->open (dhandle, &dhandle->setup);
      if (!error && (dhandle->setup.n_values < 0 ||
		     dhandle->setup.n_channels < 1 ||
		     dhandle->setup.bit_depth < 1))
	{
	  g_warning ("internal error in data handle open() (%p): nv=%ld nc=%u bd=%u",
		     dhandle->vtable->open, dhandle->setup.n_values, dhandle->setup.n_channels, dhandle->setup.bit_depth);
	  dhandle->vtable->close (dhandle);
	  error = GSL_ERROR_INTERNAL;
	}
      if (error)
	{
	  memset (&dhandle->setup, 0, sizeof (dhandle->setup));
	  GSL_SPIN_UNLOCK (&dhandle->mutex);
	  return error;
	}
      dhandle->ref_count++;
      dhandle->open_count++;
    }
  else
    dhandle->open_count++;
  GSL_SPIN_UNLOCK (&dhandle->mutex);
  
  return GSL_ERROR_NONE;
}