You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
arts/flow/gsl/gslcommon.h

294 lines
11 KiB

/* GSL - Generic Sound Layer
* Copyright (C) 2001 Tim Janik
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
* Public License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef __GSL_COMMON_H__
#define __GSL_COMMON_H__
#include <gsl/gsldefs.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
/* --- global initialization --- */
typedef struct
{
const char *value_name;
double value;
} GslConfigValue;
typedef struct
{
guint n_processors;
/* # values to pad around wave chunk blocks per channel */
guint wave_chunk_padding;
guint wave_chunk_big_pad;
/* data (file) cache block size (aligned to power of 2) */
guint dcache_block_size;
/* amount of bytes to spare for memory cache */
guint dcache_cache_memory;
guint midi_kammer_note;
/* kammer frequency, normally 440Hz, historically 435Hz */
gfloat kammer_freq;
} GslConfig;
typedef struct _GslMutexTable GslMutexTable;
void gsl_init (const GslConfigValue values[],
GslMutexTable *mtable);
const GslConfig* gsl_get_config (void) G_GNUC_CONST;
#define GSL_CONFIG(value) ((gsl_get_config () [0]) . value)
/* --- memory allocation --- */
#define gsl_new_struct(type, n) ((type*) gsl_alloc_memblock (sizeof (type) * (n)))
#define gsl_new_struct0(type, n) ((type*) gsl_alloc_memblock0 (sizeof (type) * (n)))
#define gsl_delete_struct(type, mem) gsl_delete_structs (type, 1, (mem))
#ifndef __GNUC__
# define gsl_delete_structs(type, n, mem) (gsl_free_memblock (sizeof (type) * (n), (mem)))
#else /* provide typesafety if possible */
# define gsl_delete_structs(type, n, mem) do { \
type *__typed_pointer = (mem); \
gsl_free_memblock (sizeof (type) * (n), __typed_pointer); \
} while(0)
#endif
#define GSL_ALIGNED_SIZE(size,align) ((align) > 0 ? _GSL_INTERN_ALIGN (((gsize) (size)), ((gsize) (align))) : (gsize) (size))
#define _GSL_INTERN_ALIGN(s, a) (((s + (a - 1)) / a) * a)
#define GSL_STD_ALIGN (MAX (MAX (sizeof (float), sizeof (int)), sizeof (void*)))
/* --- ring (circular-list) --- */
struct _GslRing
{
GslRing *next;
GslRing *prev;
gpointer data;
};
GslRing* gsl_ring_prepend (GslRing *head,
gpointer data);
GslRing* gsl_ring_prepend_uniq (GslRing *head,
gpointer data);
GslRing* gsl_ring_append (GslRing *head,
gpointer data);
GslRing* gsl_ring_insert_sorted (GslRing *head,
gpointer data,
GCompareFunc func);
GslRing* gsl_ring_remove_node (GslRing *head,
GslRing *node);
GslRing* gsl_ring_remove (GslRing *head,
gpointer data);
guint gsl_ring_length (GslRing *head);
GslRing* gsl_ring_concat (GslRing *head1,
GslRing *head2);
GslRing* gsl_ring_find (GslRing *head,
gconstpointer data);
GslRing* gsl_ring_nth (GslRing *head,
guint n);
gpointer gsl_ring_nth_data (GslRing *head,
guint n);
gpointer gsl_ring_pop_head (GslRing **head);
gpointer gsl_ring_pop_tail (GslRing **head);
#define gsl_ring_push_head gsl_ring_prepend
#define gsl_ring_push_tail gsl_ring_append
void gsl_ring_free (GslRing *head);
#define gsl_ring_walk(head,node) ((node) != (head)->prev ? (node)->next : NULL)
/* --- GslMessage and debugging --- */
typedef enum /*< skip >*/
{
GSL_MSG_NOTIFY = 1 << 0,
GSL_MSG_DATA_CACHE = 1 << 1,
GSL_MSG_DATA_HANDLE = 1 << 2,
GSL_MSG_LOADER = 1 << 3,
GSL_MSG_OSC = 1 << 4,
GSL_MSG_ENGINE = 1 << 5,
GSL_MSG_JOBS = 1 << 6,
GSL_MSG_FJOBS = 1 << 7,
GSL_MSG_SCHED = 1 << 8,
GSL_MSG_MASTER = 1 << 9,
GSL_MSG_SLAVE = 1 << 10
} GslDebugFlags;
extern const GDebugKey *gsl_debug_keys;
extern const guint gsl_n_debug_keys;
void gsl_debug (GslDebugFlags reporter,
const gchar *section,
const gchar *format,
...) G_GNUC_PRINTF (3, 4);
void gsl_debug_enable (GslDebugFlags dbg_flags);
void gsl_debug_disable (GslDebugFlags dbg_flags);
gboolean gsl_debug_check (GslDebugFlags dbg_flags);
void gsl_message_send (GslDebugFlags reporter,
const gchar *section, /* maybe NULL */
GslErrorType error, /* maybe 0 */
const gchar *messagef,
...) G_GNUC_PRINTF (4, 5);
const gchar* gsl_strerror (GslErrorType error);
/* provide message/debugging macro templates, so custom messages
* are done as:
* #define FOO_DEBUG GSL_DEBUG_FUNCTION (GSL_MSG_LOADER, "FOO")
* FOO_DEBUG ("some debug message and number: %d", 5);
*/
#define GSL_DEBUG_FUNCTION(reporter, section) _GSL_DEBUG_MACRO_IMPL((reporter), (section))
#define GSL_MESSAGE_FUNCTION(reporter, section) _GSL_MESSAGE_MACRO_IMPL((reporter), (section))
/* --- GslThread --- */
typedef void (*GslThreadFunc) (gpointer user_data);
GslThread* gsl_thread_new (GslThreadFunc func,
gpointer user_data);
guint gsl_threads_get_count (void);
GslThread* gsl_thread_self (void);
GslThread* gsl_thread_main (void);
/* --- tick stamps --- */
typedef struct {
guint64 tick_stamp;
guint64 system_time;
} GslTickStampUpdate;
guint64 gsl_tick_stamp (void);
guint64 gsl_time_system (void);
GslTickStampUpdate gsl_tick_stamp_last (void);
#define GSL_TICK_STAMP (_GSL_TICK_STAMP_VAL ())
#define GSL_MAX_TICK_STAMP (G_MAXUINT64)
/* --- thread syncronization --- */
gboolean gsl_thread_sleep (glong max_msec);
gboolean gsl_thread_aborted (void);
void gsl_thread_queue_abort (GslThread *thread);
void gsl_thread_abort (GslThread *thread);
void gsl_thread_wakeup (GslThread *thread);
void gsl_thread_awake_after (guint64 tick_stamp);
void gsl_thread_awake_before (guint64 tick_stamp);
void gsl_thread_get_pollfd (GPollFD *pfd);
/* --- GslMutex --- */
#define gsl_mutex_init(mutex) (gsl_mutex_table.mutex_init (mutex))
#define GSL_SPIN_LOCK(mutex) (gsl_mutex_table.mutex_lock (mutex))
#define GSL_SPIN_UNLOCK(mutex) (gsl_mutex_table.mutex_unlock (mutex))
#define GSL_SYNC_LOCK(mutex) (gsl_mutex_table.mutex_lock (mutex))
#define GSL_SYNC_UNLOCK(mutex) (gsl_mutex_table.mutex_unlock (mutex))
#define gsl_mutex_trylock(mutex) (!gsl_mutex_table.mutex_trylock (mutex))
#define gsl_mutex_destroy(mutex) (gsl_mutex_table.mutex_destroy (mutex))
#define gsl_rec_mutex_init(rmutex) (gsl_mutex_table.rec_mutex_init (rmutex))
#define gsl_rec_mutex_lock(rmutex) (gsl_mutex_table.rec_mutex_lock (rmutex))
#define gsl_rec_mutex_unlock(rmutex) (gsl_mutex_table.rec_mutex_unlock (rmutex))
#define gsl_rec_mutex_trylock(rmutex) (!gsl_mutex_table.rec_mutex_trylock (rmutex))
#define gsl_rec_mutex_destroy(rmutex) (gsl_mutex_table.rec_mutex_destroy (rmutex))
#define gsl_cond_init(cond) (gsl_mutex_table.cond_init (cond))
#define gsl_cond_signal(cond) (gsl_mutex_table.cond_signal (cond))
#define gsl_cond_broadcast(cond) (gsl_mutex_table.cond_broadcast (cond))
#define gsl_cond_wait(cond, mutex) (gsl_mutex_table.cond_wait ((cond), (mutex)))
#define gsl_cond_destroy(cond) (gsl_mutex_table.cond_destroy (cond))
void gsl_cond_wait_timed (GslCond *cond,
GslMutex *mutex,
glong max_useconds);
struct _GslMutexTable
{
void (*mutex_init) (GslMutex *mutex);
void (*mutex_lock) (GslMutex *mutex);
int (*mutex_trylock) (GslMutex *mutex); /* 0==has_lock */
void (*mutex_unlock) (GslMutex *mutex);
void (*mutex_destroy) (GslMutex *mutex);
void (*rec_mutex_init) (GslRecMutex *mutex);
void (*rec_mutex_lock) (GslRecMutex *mutex);
int (*rec_mutex_trylock) (GslRecMutex *mutex); /* 0==has_lock */
void (*rec_mutex_unlock) (GslRecMutex *mutex);
void (*rec_mutex_destroy) (GslRecMutex *mutex);
void (*cond_init) (GslCond *cond);
void (*cond_signal) (GslCond *cond);
void (*cond_broadcast) (GslCond *cond);
void (*cond_wait) (GslCond *cond,
GslMutex *mutex);
void (*cond_wait_timed) (GslCond *cond,
GslMutex *mutex,
gulong abs_secs,
gulong abs_usecs);
void (*cond_destroy) (GslCond *cond);
};
/* --- misc --- */
const gchar* gsl_byte_order_to_string (guint byte_order);
guint gsl_byte_order_from_string (const gchar *string);
GslErrorType gsl_error_from_errno (gint sys_errno,
GslErrorType fallback);
GslErrorType gsl_check_file (const gchar *file_name,
const gchar *mode);
/* --- implementation details --- */
gpointer gsl_alloc_memblock (gsize size);
gpointer gsl_alloc_memblock0 (gsize size);
void gsl_free_memblock (gsize size,
gpointer memblock);
void gsl_alloc_report (void);
const guint gsl_alloc_upper_power2 (const gulong number);
void _gsl_tick_stamp_inc (void);
void _gsl_tick_stamp_set_leap (guint ticks);
void _gsl_init_signal (void);
void _gsl_init_fd_pool (void);
void _gsl_init_data_caches (void);
void _gsl_init_engine_utils (void);
void _gsl_init_loader_gslwave (void);
void _gsl_init_loader_wav (void);
void _gsl_init_loader_oggvorbis (void);
void _gsl_init_loader_mad (void);
#define GSL_N_IO_RETRIES (5)
#define _GSL_TICK_STAMP_VAL() (gsl_externvar_tick_stamp + 0)
extern volatile guint64 gsl_externvar_tick_stamp;
extern GslMutexTable gsl_mutex_table;
/* we need to provide a REPORTER and SECTION string for the debugging
* and message generation functions. for GCC, we also want to make use
* of printf style format checking with G_GNUC_PRINTF(). for the non GCC
* case, we push REPORTER and SECTION as thread specific data before
* invoking the debugging/message generation function. for the GCC case
* we use GNUC varargs. (using ISO varargs wouldn't provide any benefit,
* for one, ISO vararg support is broken with gcc-2.95 and ansi/c++, and
* we only need the macro magic for GCC in the first place to make use
* of G_GNUC_PRINTF()).
*/
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
#define _GSL_DEBUG_MACRO_IMPL(reporter, section) gsl_debug ((reporter), (section), _GSL_DEBUG_GCCTAIL
#define _GSL_DEBUG_GCCTAIL(GCCARGS...) GCCARGS )
#define _GSL_MESSAGE_MACRO_IMPL(reporter, section) gsl_message_send ((reporter), (section), _GSL_MESSGAE_GCCTAIL
#define _GSL_MESSGAE_GCCTAIL(GCCARGS...) GCCARGS )
#else /* non GCC, push data and invoke function */
#define _GSL_DEBUG_MACRO_IMPL(reporter, section) (gsl_auxlog_push ((reporter), (section)), gsl_auxlog_debug)
#define _GSL_MESSAGE_MACRO_IMPL(reporter, section) (gsl_auxlog_push ((reporter), (section)), gsl_auxlog_message)
#endif
/* non-GCC message helpers */
void gsl_auxlog_push (GslDebugFlags reporter,
const gchar *section);
void gsl_auxlog_debug (const gchar *format,
...);
void gsl_auxlog_message (GslErrorType error,
const gchar *format,
...);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GSL_COMMON_H__ */