xref: /6.0.3/forestdb/src/arch.h (revision cc8ad991)
1/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 *     Copyright 2010 Couchbase, Inc
4 *
5 *   Licensed under the Apache License, Version 2.0 (the "License");
6 *   you may not use this file except in compliance with the License.
7 *   You may obtain a copy of the License at
8 *
9 *       http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *   Unless required by applicable law or agreed to in writing, software
12 *   distributed under the License is distributed on an "AS IS" BASIS,
13 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *   See the License for the specific language governing permissions and
15 *   limitations under the License.
16 */
17
18#ifndef _JSAHN_ARCH_H
19#define _JSAHN_ARCH_H
20
21#ifndef __STDC_FORMAT_MACROS
22#define __STDC_FORMAT_MACROS
23#endif
24
25#include <stdio.h>
26#include <fcntl.h>
27
28#include "forestdb_endian.h"
29/* Large File Support */
30#define _LARGE_FILE 1
31#ifndef _FILE_OFFSET_BITS
32#  define _FILE_OFFSET_BITS 64
33#elif (_FILE_OFFSET_BITS != 64)
34#error "bad things"
35#endif
36#define _LARGEFILE_SOURCE 1
37#ifndef O_LARGEFILE
38# define O_LARGEFILE 0
39#endif
40
41#ifndef _MSC_VER
42#include <stdbool.h>
43#else
44#ifndef __cplusplus
45#pragma once
46#define false (0)
47#define true (1)
48#define bool int
49#endif
50#endif
51
52#ifdef HAVE_JEMALLOC
53#ifdef WIN32
54/* jemalloc.h tries to include strings.h, but on win32
55   that is our own "hacked" version that provides stuff
56   we use elsewhere in the system. By including that
57   file you might end up having to link with the
58   platform lib which supplies a lot of the functions
59   forestdb also provides an implementation of (but
60   with a different linkage)
61*/
62#define STRINGS_H
63#endif
64
65#include <jemalloc/jemalloc.h>
66
67#ifdef WIN32
68#undef STRINGS_H
69#endif
70
71#undef malloc
72#undef calloc
73#undef realloc
74#undef free
75#undef posix_memalign
76#undef memalign
77#undef aligned_malloc
78#undef aligned_free
79
80#define malloc(size) je_malloc(size)
81#define calloc(nmemb, size) je_calloc(nmemb, size)
82#define realloc(ptr, size) je_realloc(ptr, size)
83#define free(addr) je_free(addr)
84#define posix_memalign(memptr, alignment, size) \
85	je_posix_memalign(memptr, alignment, size)
86#define memalign(alignment, size) je_memalign(alignment, size)
87#define aligned_malloc(size, align) je_aligned_malloc(size, align)
88#define aligned_free(addr) je_aligned_free(addr)
89#endif //HAVE_JEMALLOC
90
91#ifdef __APPLE__
92    #include <inttypes.h>
93    #include <alloca.h>
94    #include <TargetConditionals.h>
95
96    #define INLINE extern inline
97
98    #define _X64 "llx"
99    #define _F64 "lld"
100    #define _FSEC "ld"
101    #define _FUSEC "d"
102
103    #define _ARCH_O_DIRECT (0x0)
104
105    #if TARGET_CPU_ARM
106    #define _ALIGN_MEM_ACCESS
107    #endif
108
109    #define malloc_align(addr, align, size)                     \
110        {if ( 0 != posix_memalign(&(addr), (align), (size)) ) { \
111            (addr) = NULL;                                      \
112         } }
113    #define free_align(addr) free(addr)
114
115    #ifndef spin_t
116        // spinlock
117        #include <libkern/OSAtomic.h>
118        #define spin_t OSSpinLock
119        #define spin_lock(arg) OSSpinLockLock(arg)
120        #define spin_trylock(arg) OSSpinLockTry(arg)
121        #define spin_unlock(arg) OSSpinLockUnlock(arg)
122        #define SPIN_INITIALIZER (spin_t)(0)
123        #define spin_init(arg) *(arg) = (spin_t)(0)
124        #define spin_destroy(arg)
125    #endif
126    #ifndef mutex_t
127        // mutex
128        #include <pthread.h>
129        #define mutex_t pthread_mutex_t
130        #define mutex_init(arg) pthread_mutex_init(arg, NULL)
131        #define mutex_lock(arg) pthread_mutex_lock(arg)
132        #define mutex_trylock(arg) \
133            (pthread_mutex_trylock(arg) == 0)
134        #define mutex_unlock(arg) pthread_mutex_unlock(arg)
135        #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
136        #define mutex_destroy(arg) pthread_mutex_destroy(arg)
137    #endif
138    #ifndef thread_t
139            // thread
140        #include <pthread.h>
141        #define thread_t pthread_t
142        #define thread_cond_t pthread_cond_t
143        #define thread_create(tid, func, args) \
144            pthread_create((tid), NULL, (func), (args))
145        #define thread_join(tid, ret) pthread_join(tid, ret)
146        #define thread_cancel(tid) pthread_cancel(tid)
147        #define thread_exit(code) pthread_exit(code)
148        #define thread_cond_init(cond) pthread_cond_init(cond, NULL)
149        #define thread_cond_destroy(cond) pthread_cond_destroy(cond)
150        #define thread_cond_wait(cond, mutex) pthread_cond_wait(cond, mutex)
151        #define thread_cond_timedwait(cond, mutex, ms) \
152            { \
153            struct timespec ts = convert_reltime_to_abstime(ms); \
154            pthread_cond_timedwait(cond, mutex, &ts); \
155            }
156        #define thread_cond_signal(cond) pthread_cond_signal(cond)
157        #define thread_cond_broadcast(cond) pthread_cond_broadcast(cond)
158    #endif
159
160#elif __ANDROID__
161    #include <inttypes.h>
162    #include <alloca.h>
163
164    #define INLINE static __inline
165
166    #define _X64 "llx"
167    #define _F64 "lld"
168    #define _FSEC "ld"
169    #define _FUSEC "ld"
170
171    #define _ARCH_O_DIRECT (O_DIRECT)
172    #define malloc_align(addr, align, size) \
173        (addr = memalign((align), (size)))
174    #define free_align(addr) free(addr)
175
176    #ifndef spin_t
177        // spinlock
178        #include <pthread.h>
179        #define spin_t pthread_mutex_t
180        #define spin_init(arg) pthread_mutex_init(arg, NULL)
181        #define spin_lock(arg) pthread_mutex_lock(arg)
182        #define spin_trylock(arg) \
183            (pthread_mutex_trylock(arg) == 0)
184        #define spin_unlock(arg) pthread_mutex_unlock(arg)
185        #define spin_destroy(arg) pthread_mutex_destroy(arg)
186        #define SPIN_INITIALIZER ((spin_t)PTHREAD_MUTEX_INITIALIZER)
187    #endif
188    #ifndef mutex_t
189        // mutex
190        #include <pthread.h>
191        #define mutex_t pthread_mutex_t
192        #define mutex_init(arg) pthread_mutex_init(arg, NULL)
193        #define mutex_lock(arg) pthread_mutex_lock(arg)
194        #define mutex_trylock(arg) \
195            (pthread_mutex_trylock(arg) == 0)
196        #define mutex_unlock(arg) pthread_mutex_unlock(arg)
197        #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
198        #define mutex_destroy(arg) pthread_mutex_destroy(arg)
199    #endif
200    #ifndef thread_t
201        // thread
202        #include <pthread.h>
203        #define thread_t pthread_t
204        #define thread_cond_t pthread_cond_t
205        #define thread_create(tid, func, args) \
206            pthread_create((tid), NULL, (func), (args))
207        #define thread_join(tid, ret) pthread_join(tid, ret)
208        #define thread_cancel(tid) pthread_cancel(tid)
209        #define thread_exit(code) pthread_exit(code)
210        #define thread_cond_init(cond) pthread_cond_init(cond, NULL)
211        #define thread_cond_destroy(cond) pthread_cond_destroy(cond)
212        #define thread_cond_wait(cond, mutex) pthread_cond_wait(cond, mutex)
213        #define thread_cond_timedwait(cond, mutex, ms) \
214            { \
215            struct timespec ts = convert_reltime_to_abstime(ms); \
216            pthread_cond_timedwait(cond, mutex, &ts); \
217            }
218        #define thread_cond_signal(cond) pthread_cond_signal(cond)
219        #define thread_cond_broadcast(cond) pthread_cond_broadcast(cond)
220    #endif
221
222    #ifdef assert
223        #undef assert
224    #endif
225    #define assert(a) (a)
226
227#elif __linux__ && __arm__
228    #include <inttypes.h>
229    #include <alloca.h>
230
231    #define INLINE static __inline
232
233    #define _X64 "llx"
234    #define _F64 "lld"
235    #define _FSEC "ld"
236    #define _FUSEC "ld"
237
238    #define _ARCH_O_DIRECT (O_DIRECT)
239    #define malloc_align(addr, align, size) \
240        (addr = memalign((align), (size)))
241    #define free_align(addr) free(addr)
242
243    #ifndef spin_t
244        // spinlock
245        #include <pthread.h>
246        #define spin_t pthread_spinlock_t
247        #define spin_init(arg) pthread_spin_init(arg, PTHREAD_PROCESS_SHARED)
248        #define spin_lock(arg) pthread_spin_lock(arg)
249        #define spin_trylock(arg) \
250            (pthread_spin_trylock(arg) == 0)
251        #define spin_unlock(arg) pthread_spin_unlock(arg)
252        #define spin_destroy(arg) pthread_spin_destroy(arg)
253        #define SPIN_INITIALIZER (spin_t)(0)
254    #endif
255    #ifndef mutex_t
256        // mutex
257        #include <pthread.h>
258        #define mutex_t pthread_mutex_t
259        #define mutex_init(arg) pthread_mutex_init(arg, NULL)
260        #define mutex_lock(arg) pthread_mutex_lock(arg)
261        #define mutex_trylock(arg) \
262            (pthread_mutex_trylock(arg) == 0)
263        #define mutex_unlock(arg) pthread_mutex_unlock(arg)
264        #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
265        #define mutex_destroy(arg) pthread_mutex_destroy(arg)
266    #endif
267    #ifndef thread_t
268        // thread
269        #include <pthread.h>
270        #define thread_t pthread_t
271        #define thread_cond_t pthread_cond_t
272        #define thread_create(tid, func, args) \
273            pthread_create((tid), NULL, (func), (args))
274        #define thread_join(tid, ret) pthread_join(tid, ret)
275        #define thread_cancel(tid) pthread_cancel(tid)
276        #define thread_exit(code) pthread_exit(code)
277        #define thread_cond_init(cond) pthread_cond_init(cond, NULL)
278        #define thread_cond_destroy(cond) pthread_cond_destroy(cond)
279        #define thread_cond_wait(cond, mutex) pthread_cond_wait(cond, mutex)
280        #define thread_cond_timedwait(cond, mutex, ms) \
281            { \
282            struct timespec ts = convert_reltime_to_abstime(ms); \
283            pthread_cond_timedwait(cond, mutex, &ts); \
284            }
285        #define thread_cond_signal(cond) pthread_cond_signal(cond)
286        #define thread_cond_broadcast(cond) pthread_cond_broadcast(cond)
287    #endif
288
289#elif __linux__
290    #include <inttypes.h>
291    #include <alloca.h>
292
293    #define INLINE __inline
294
295    #define _X64 PRIx64
296    #define _F64 PRIu64
297    #define _FSEC "ld"
298    #define _FUSEC "ld"
299
300    #define _ARCH_O_DIRECT (O_DIRECT)
301
302    #define malloc_align(addr, align, size)                     \
303        {if ( 0 != posix_memalign(&(addr), (align), (size)) ) { \
304            (addr) = NULL;                                      \
305         } }
306    #define free_align(addr) free(addr)
307
308    #ifndef spin_t
309        // spinlock
310        #include <pthread.h>
311        #define spin_t pthread_spinlock_t
312        #define spin_init(arg) pthread_spin_init(arg, PTHREAD_PROCESS_SHARED)
313        #define spin_lock(arg) pthread_spin_lock(arg)
314        #define spin_trylock(arg) \
315            (pthread_spin_trylock(arg) == 0)
316        #define spin_unlock(arg) pthread_spin_unlock(arg)
317        #define spin_destroy(arg) pthread_spin_destroy(arg)
318        #define SPIN_INITIALIZER (spin_t)(1)
319    #endif
320    #ifndef mutex_t
321        // mutex
322        #include <pthread.h>
323        #define mutex_t pthread_mutex_t
324        #define mutex_init(arg) pthread_mutex_init(arg, NULL)
325        #define mutex_lock(arg) pthread_mutex_lock(arg)
326        #define mutex_trylock(arg) \
327            (pthread_mutex_trylock(arg) == 0)
328        #define mutex_unlock(arg) pthread_mutex_unlock(arg)
329        #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
330        #define mutex_destroy(arg) pthread_mutex_destroy(arg)
331    #endif
332    #ifndef thread_t
333        // thread
334        #include <pthread.h>
335        #define thread_t pthread_t
336        #define thread_cond_t pthread_cond_t
337        #define thread_create(tid, func, args) \
338            pthread_create((tid), NULL, (func), (args))
339        #define thread_join(tid, ret) pthread_join(tid, ret)
340        #define thread_cancel(tid) pthread_cancel(tid)
341        #define thread_exit(code) pthread_exit(code)
342        #define thread_cond_init(cond) pthread_cond_init(cond, NULL)
343        #define thread_cond_destroy(cond) pthread_cond_destroy(cond)
344        #define thread_cond_wait(cond, mutex) pthread_cond_wait(cond, mutex)
345        #define thread_cond_timedwait(cond, mutex, ms) \
346            { \
347            struct timespec ts = convert_reltime_to_abstime(ms); \
348            pthread_cond_timedwait(cond, mutex, &ts); \
349            }
350        #define thread_cond_signal(cond) pthread_cond_signal(cond)
351        #define thread_cond_broadcast(cond) pthread_cond_broadcast(cond)
352    #endif
353
354#elif defined(WIN32) || defined(_WIN32)
355    // mingw compatiable
356
357    #define _FSEC "ld"
358    #define _FUSEC "ld"
359
360    #define _ARCH_O_DIRECT (0x0)
361
362#ifdef _MSC_VER
363    // visual studio CL compiler
364    #include <Windows.h>
365    #include "gettimeofday_vs.h"
366    #define INLINE static inline
367    //#define alloca(size) _alloca(size)
368    #define _X64 "llx"
369    #define _F64 "llu"
370#ifndef _CRT_SECURE_NO_WARNINGS
371    #define _CRT_SECURE_NO_WARNINGS
372#endif
373    #define gettimeofday gettimeofday_vs
374    #define sleep(sec) Sleep((sec)*1000)
375    typedef unsigned long mode_t;
376    #include <BaseTsd.h>
377    typedef SSIZE_T ssize_t;
378#else
379    #include <inttypes.h>
380    #include <windows.h>
381    #define _X64 PRIx64
382    #define _F64 PRIu64
383    #define INLINE __inline
384#endif
385    #include <stdint.h>
386    #include <stdlib.h>
387    #define malloc_align(addr, align, size) \
388        (addr = (void*)_aligned_malloc((size), (align)))
389    #define free_align(addr) _aligned_free(addr)
390
391    #ifndef spin_t
392        // spinlock
393        #define spin_t CRITICAL_SECTION
394        #define spin_init(arg) InitializeCriticalSection(arg)
395        #define spin_lock(arg) EnterCriticalSection(arg)
396        #define spin_trylock(arg) TryEnterCriticalSection(arg)
397        #define spin_unlock(arg) LeaveCriticalSection(arg)
398        #define spin_destroy(arg) DeleteCriticalSection(arg)
399    #endif
400    #ifndef mutex_t
401        // mutex
402        #define mutex_t CRITICAL_SECTION
403        #define mutex_init(arg) InitializeCriticalSection(arg)
404        #define mutex_lock(arg) EnterCriticalSection(arg)
405        #define mutex_trylock(arg) TryEnterCriticalSection(arg)
406        #define mutex_unlock(arg) LeaveCriticalSection(arg)
407        #define mutex_destroy(arg) DeleteCriticalSection(arg)
408    #endif
409    #ifndef thread_t
410        // thread
411        #define thread_t HANDLE
412        #define thread_cond_t CONDITION_VARIABLE
413        #define thread_create(tid, func, args) \
414            { \
415            DWORD __dt__; \
416            *(tid) = CreateThread(NULL, 0, \
417                (LPTHREAD_START_ROUTINE)(func), (args), 0, &__dt__); \
418            }
419        #define thread_join(tid, ret) WaitForSingleObject(tid, INFINITE)
420        #define thread_cancel(tid) TerminateThread(tid, 0);
421        #define thread_exit(code) ExitThread(code)
422        #define thread_cond_init(cond) InitializeConditionVariable(cond)
423        #define thread_cond_destroy(cond) (void)cond
424        #define thread_cond_wait(cond, mutex) SleepConditionVariableCS(cond, mutex, INFINITE)
425        #define thread_cond_timedwait(cond, mutex, msec) \
426            SleepConditionVariableCS(cond, mutex, msec)
427        #define thread_cond_signal(cond) WakeConditionVariable(cond)
428        #define thread_cond_broadcast(cond) WakeAllConditionVariable(cond)
429    #endif
430
431#elif __CYGWIN__
432    // cygwin compatiable
433    #include <inttypes.h>
434    #include <alloca.h>
435
436    #define INLINE __inline
437
438    #define _X64 PRIx64
439    #define _F64 PRIu64
440    #define _FSEC "ld"
441    #define _FUSEC "ld"
442
443    #define _ARCH_O_DIRECT (0x0)
444
445    #define malloc_align(addr, align, size) \
446        (addr = (void *)memalign((align), (size)))
447    #define free_align(addr) free(addr)
448
449    #ifndef spin_t
450        // spinlock
451        #include <pthread.h>
452        #define spin_t pthread_spinlock_t
453        #define spin_init(arg) pthread_spin_init(arg, PTHREAD_PROCESS_SHARED)
454        #define spin_lock(arg) pthread_spin_lock(arg)
455        #define spin_trylock(arg) \
456            (pthread_spin_trylock(arg) == 0)
457        #define spin_unlock(arg) pthread_spin_unlock(arg)
458        #define spin_destroy(arg) pthread_spin_destroy(arg)
459        #define SPIN_INITIALIZER (spin_t)(1)
460    #endif
461    #ifndef mutex_t
462        // mutex
463        #include <pthread.h>
464        #define mutex_t pthread_mutex_t
465        #define mutex_init(arg) pthread_mutex_init(arg, NULL)
466        #define mutex_lock(arg) pthread_mutex_lock(arg)
467        #define mutex_trylock(arg) \
468            (pthread_mutex_trylock(arg) == 0)
469        #define mutex_unlock(arg) pthread_mutex_unlock(arg)
470        #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
471        #define mutex_destroy(arg) pthread_mutex_destroy(arg)
472    #endif
473    #ifndef thread_t
474        // thread
475        #include <pthread.h>
476        #define thread_t pthread_t
477        #define thread_cond_t pthread_cond_t
478        #define thread_create(tid, func, args) \
479            pthread_create((tid), NULL, (func), (args))
480        #define thread_join(tid, ret) pthread_join(tid, ret)
481        #define thread_cancel(tid) pthread_cancel(tid)
482        #define thread_exit(code) pthread_exit(code)
483        #define thread_cond_init(cond) pthread_cond_init(cond, NULL)
484        #define thread_cond_destroy(cond) pthread_cond_destroy(cond)
485        #define thread_cond_wait(cond, mutex) pthread_cond_wait(cond, mutex)
486        #define thread_cond_timedwait(cond, mutex, ms) \
487            { \
488            struct timespec ts = convert_reltime_to_abstime(ms); \
489            pthread_cond_timedwait(cond, mutex, &ts); \
490            }
491        #define thread_cond_signal(cond) pthread_cond_signal(cond)
492        #define thread_cond_broadcast(cond) pthread_cond_broadcast(cond)
493    #endif
494
495#elif __sun
496    #include <inttypes.h>
497    #include <alloca.h>
498
499    #define INLINE __inline
500
501    #define _X64 PRIx64
502    #define _F64 PRIu64
503    #define _FSEC "ld"
504    #define _FUSEC "ld"
505
506    /* Solaris don't have flag to open to set direct io, but
507       rather use directio() afterwards to enable it. lets look
508       into that later on.
509    */
510    #define _ARCH_O_DIRECT (0)
511
512    #define malloc_align(addr, align, size)                     \
513        {if ( 0 != posix_memalign(&(addr), (align), (size)) ) { \
514            (addr) = NULL;                                      \
515         } }
516    #define free_align(addr) free(addr)
517
518    #ifndef spin_t
519        // spinlock
520        // There isn't much point of keeping a separate
521        // spinlock datatype, because the mutexes on
522        // solaris is adaptive anyway and will spin
523        // initially.
524        #include <pthread.h>
525        #define spin_t pthread_mutex_t
526        #define spin_init(arg) pthread_mutex_init(arg, NULL)
527        #define spin_lock(arg) pthread_mutex_lock(arg)
528        #define spin_trylock(arg) \
529            (pthread_mutex_trylock(arg) == 0)
530        #define spin_unlock(arg) pthread_mutex_unlock(arg)
531        #define spin_destroy(arg) pthread_mutex_destroy(arg)
532        #define SPIN_INITIALIZER PTHREAD_MUTEX_INITIALIZER
533    #endif
534    #ifndef mutex_t
535        // mutex
536        #include <pthread.h>
537        #define mutex_t pthread_mutex_t
538        #define mutex_init(arg) pthread_mutex_init(arg, NULL)
539        #define mutex_lock(arg) pthread_mutex_lock(arg)
540        #define mutex_trylock(arg) \
541            (pthread_mutex_trylock(arg) == 0)
542        #define mutex_unlock(arg) pthread_mutex_unlock(arg)
543        #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
544        #define mutex_destroy(arg) pthread_mutex_destroy(arg)
545    #endif
546    #ifndef thread_t
547        // thread
548        #include <pthread.h>
549        #define thread_t pthread_t
550        #define thread_cond_t pthread_cond_t
551        #define thread_create(tid, func, args) \
552            pthread_create((tid), NULL, (func), (args))
553        #define thread_join(tid, ret) pthread_join(tid, ret)
554        #define thread_cancel(tid) pthread_cancel(tid)
555        #define thread_exit(code) pthread_exit(code)
556        #define thread_cond_init(cond) pthread_cond_init(cond, NULL)
557        #define thread_cond_destroy(cond) pthread_cond_destroy(cond)
558        #define thread_cond_wait(cond, mutex) pthread_cond_wait(cond, mutex)
559        #define thread_cond_timedwait(cond, mutex, ms) \
560            { \
561            struct timespec ts = convert_reltime_to_abstime(ms); \
562            pthread_cond_timedwait(cond, mutex, &ts); \
563            }
564        #define thread_cond_signal(cond) pthread_cond_signal(cond)
565        #define thread_cond_broadcast(cond) pthread_cond_broadcast(cond)
566    #endif
567
568#elif __FreeBSD__
569    #include <inttypes.h>
570
571    #define INLINE __inline
572
573    #define _X64 PRIx64
574    #define _F64 PRIu64
575    #define _FSEC "ld"
576    #define _FUSEC "ld"
577
578    #define _ARCH_O_DIRECT (O_DIRECT)
579
580    #define malloc_align(addr, align, size)                     \
581        {if ( 0 != posix_memalign(&(addr), (align), (size)) ) { \
582            (addr) = NULL;                                      \
583         } }
584    #define free_align(addr) free(addr)
585
586    #ifndef spin_t
587        // spinlock
588        #include <pthread.h>
589        #define spin_t pthread_mutex_t
590        #define spin_init(arg) pthread_mutex_init(arg, NULL)
591        #define spin_lock(arg) pthread_mutex_lock(arg)
592        #define spin_trylock(arg) \
593            (pthread_mutex_trylock(arg) == 0)
594        #define spin_unlock(arg) pthread_mutex_unlock(arg)
595        #define spin_destroy(arg) pthread_mutex_destroy(arg)
596        #define SPIN_INITIALIZER PTHREAD_MUTEX_INITIALIZER
597    #endif
598    #ifndef mutex_t
599        // mutex
600        #include <pthread.h>
601        #define mutex_t pthread_mutex_t
602        #define mutex_init(arg) pthread_mutex_init(arg, NULL)
603        #define mutex_lock(arg) pthread_mutex_lock(arg)
604        #define mutex_trylock(arg) \
605            (pthread_mutex_trylock(arg) == 0)
606        #define mutex_unlock(arg) pthread_mutex_unlock(arg)
607        #define MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
608        #define mutex_destroy(arg) pthread_mutex_destroy(arg)
609    #endif
610    #ifndef thread_t
611        // thread
612        #include <pthread.h>
613        #define thread_t pthread_t
614        #define thread_cond_t pthread_cond_t
615        #define thread_create(tid, func, args) \
616            pthread_create((tid), NULL, (func), (args))
617        #define thread_join(tid, ret) pthread_join(tid, ret)
618        #define thread_cancel(tid) pthread_cancel(tid)
619        #define thread_exit(code) pthread_exit(code)
620        #define thread_cond_init(cond) pthread_cond_init(cond, NULL)
621        #define thread_cond_destroy(cond) pthread_cond_destroy(cond)
622        #define thread_cond_wait(cond, mutex) pthread_cond_wait(cond, mutex)
623        #define thread_cond_timedwait(cond, mutex, ms) \
624            { \
625            struct timespec ts = convert_reltime_to_abstime(ms); \
626            pthread_cond_timedwait(cond, mutex, &ts); \
627            }
628        #define thread_cond_signal(cond) pthread_cond_signal(cond)
629        #define thread_cond_broadcast(cond) pthread_cond_broadcast(cond)
630    #endif
631
632
633#else
634#pragma error "Unknown architecture"
635    #define INLINE make_error
636#endif
637
638#endif
639