1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
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., 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__ */
|