diff options
Diffstat (limited to 'flow/gsl/gslcommon.h')
-rw-r--r-- | flow/gsl/gslcommon.h | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/flow/gsl/gslcommon.h b/flow/gsl/gslcommon.h new file mode 100644 index 0000000..6b74c77 --- /dev/null +++ b/flow/gsl/gslcommon.h @@ -0,0 +1,293 @@ +/* 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., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307, 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__ */ |