|
@@ -208,134 +208,134 @@ DEFINE_PRIM(_VOID, tls_set, _TLS _DYN);
|
|
|
|
|
|
// ----------------- DEQUE
|
|
// ----------------- DEQUE
|
|
|
|
|
|
-typedef struct _tqueue {
|
|
|
|
- vdynamic *msg;
|
|
|
|
- struct _tqueue *next;
|
|
|
|
-} tqueue;
|
|
|
|
-
|
|
|
|
-struct _hl_deque;
|
|
|
|
-typedef struct _hl_deque hl_deque;
|
|
|
|
-
|
|
|
|
-struct _hl_deque {
|
|
|
|
- void (*free)( hl_deque * );
|
|
|
|
- tqueue *first;
|
|
|
|
- tqueue *last;
|
|
|
|
-#ifdef HL_THREADS
|
|
|
|
-# ifdef HL_WIN
|
|
|
|
- CRITICAL_SECTION lock;
|
|
|
|
- HANDLE wait;
|
|
|
|
-# else
|
|
|
|
- pthread_mutex_t lock;
|
|
|
|
- pthread_cond_t wait;
|
|
|
|
-# endif
|
|
|
|
-#endif
|
|
|
|
|
|
+typedef struct _tqueue {
|
|
|
|
+ vdynamic *msg;
|
|
|
|
+ struct _tqueue *next;
|
|
|
|
+} tqueue;
|
|
|
|
+
|
|
|
|
+struct _hl_deque;
|
|
|
|
+typedef struct _hl_deque hl_deque;
|
|
|
|
+
|
|
|
|
+struct _hl_deque {
|
|
|
|
+ void (*free)( hl_deque * );
|
|
|
|
+ tqueue *first;
|
|
|
|
+ tqueue *last;
|
|
|
|
+#ifdef HL_THREADS
|
|
|
|
+# ifdef HL_WIN
|
|
|
|
+ CRITICAL_SECTION lock;
|
|
|
|
+ HANDLE wait;
|
|
|
|
+# else
|
|
|
|
+ pthread_mutex_t lock;
|
|
|
|
+ pthread_cond_t wait;
|
|
|
|
+# endif
|
|
|
|
+#endif
|
|
};
|
|
};
|
|
|
|
|
|
#if !defined(HL_THREADS)
|
|
#if !defined(HL_THREADS)
|
|
# define LOCK(l)
|
|
# define LOCK(l)
|
|
# define UNLOCK(l)
|
|
# define UNLOCK(l)
|
|
# define SIGNAL(l)
|
|
# define SIGNAL(l)
|
|
-#elif defined(HL_WIN)
|
|
|
|
-# define LOCK(l) EnterCriticalSection(&(l))
|
|
|
|
-# define UNLOCK(l) LeaveCriticalSection(&(l))
|
|
|
|
-# define SIGNAL(l) ReleaseSemaphore(l,1,NULL)
|
|
|
|
-#else
|
|
|
|
-# define LOCK(l) pthread_mutex_lock(&(l))
|
|
|
|
-# define UNLOCK(l) pthread_mutex_unlock(&(l))
|
|
|
|
-# define SIGNAL(l) pthread_cond_signal(&(l))
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-static void hl_deque_free( hl_deque *q ) {
|
|
|
|
- hl_remove_root(&q->first);
|
|
|
|
-# if !defined(HL_THREADS)
|
|
|
|
-# elif defined(HL_WIN)
|
|
|
|
- DeleteCriticalSection(&q->lock);
|
|
|
|
- CloseHandle(q->wait);
|
|
|
|
-# else
|
|
|
|
- pthread_mutex_destroy(&q->lock);
|
|
|
|
- pthread_cond_destroy(&q->wait);
|
|
|
|
-# endif
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-HL_API hl_deque *hl_deque_alloc() {
|
|
|
|
- hl_deque *q = (hl_deque*)hl_gc_alloc_finalizer(sizeof(hl_deque));
|
|
|
|
- q->free = hl_deque_free;
|
|
|
|
- q->first = NULL;
|
|
|
|
- q->last = NULL;
|
|
|
|
- hl_add_root(&q->first);
|
|
|
|
-# if !defined(HL_THREADS)
|
|
|
|
-# elif defined(HL_WIN)
|
|
|
|
- q->wait = CreateSemaphore(NULL,0,(1 << 30),NULL);
|
|
|
|
- InitializeCriticalSection(&q->lock);
|
|
|
|
-# else
|
|
|
|
- pthread_mutex_init(&q->lock,NULL);
|
|
|
|
- pthread_cond_init(&q->wait,NULL);
|
|
|
|
-# endif
|
|
|
|
- return q;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-HL_API void hl_deque_add( hl_deque *q, vdynamic *msg ) {
|
|
|
|
- tqueue *t = (tqueue*)hl_gc_alloc_raw(sizeof(tqueue));
|
|
|
|
- t->msg = msg;
|
|
|
|
- t->next = NULL;
|
|
|
|
- LOCK(q->lock);
|
|
|
|
- if( q->last == NULL )
|
|
|
|
- q->first = t;
|
|
|
|
- else
|
|
|
|
- q->last->next = t;
|
|
|
|
- q->last = t;
|
|
|
|
- SIGNAL(q->wait);
|
|
|
|
- UNLOCK(q->lock);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-HL_API void hl_deque_push( hl_deque *q, vdynamic *msg ) {
|
|
|
|
- tqueue *t = (tqueue*)hl_gc_alloc_raw(sizeof(tqueue));
|
|
|
|
- t->msg = msg;
|
|
|
|
- LOCK(q->lock);
|
|
|
|
- t->next = q->first;
|
|
|
|
- q->first = t;
|
|
|
|
- if( q->last == NULL )
|
|
|
|
- q->last = t;
|
|
|
|
- SIGNAL(q->wait);
|
|
|
|
- UNLOCK(q->lock);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-HL_API vdynamic *hl_deque_pop( hl_deque *q, bool block ) {
|
|
|
|
- vdynamic *msg;
|
|
|
|
- hl_blocking(true);
|
|
|
|
- LOCK(q->lock);
|
|
|
|
- while( q->first == NULL )
|
|
|
|
- if( block ) {
|
|
|
|
-# if !defined(HL_THREADS)
|
|
|
|
-# elif defined(HL_WIN)
|
|
|
|
- UNLOCK(q->lock);
|
|
|
|
- WaitForSingleObject(q->wait,INFINITE);
|
|
|
|
- LOCK(q->lock);
|
|
|
|
-# else
|
|
|
|
- pthread_cond_wait(&q->wait,&q->lock);
|
|
|
|
-# endif
|
|
|
|
- } else {
|
|
|
|
- UNLOCK(q->lock);
|
|
|
|
- hl_blocking(false);
|
|
|
|
- return NULL;
|
|
|
|
- }
|
|
|
|
- msg = q->first->msg;
|
|
|
|
- q->first = q->first->next;
|
|
|
|
- if( q->first == NULL )
|
|
|
|
- q->last = NULL;
|
|
|
|
- else
|
|
|
|
- SIGNAL(q->wait);
|
|
|
|
- UNLOCK(q->lock);
|
|
|
|
- hl_blocking(false);
|
|
|
|
- return msg;
|
|
|
|
-}
|
|
|
|
|
|
+#elif defined(HL_WIN)
|
|
|
|
+# define LOCK(l) EnterCriticalSection(&(l))
|
|
|
|
+# define UNLOCK(l) LeaveCriticalSection(&(l))
|
|
|
|
+# define SIGNAL(l) ReleaseSemaphore(l,1,NULL)
|
|
|
|
+#else
|
|
|
|
+# define LOCK(l) pthread_mutex_lock(&(l))
|
|
|
|
+# define UNLOCK(l) pthread_mutex_unlock(&(l))
|
|
|
|
+# define SIGNAL(l) pthread_cond_signal(&(l))
|
|
|
|
+#endif
|
|
|
|
+
|
|
|
|
+static void hl_deque_free( hl_deque *q ) {
|
|
|
|
+ hl_remove_root(&q->first);
|
|
|
|
+# if !defined(HL_THREADS)
|
|
|
|
+# elif defined(HL_WIN)
|
|
|
|
+ DeleteCriticalSection(&q->lock);
|
|
|
|
+ CloseHandle(q->wait);
|
|
|
|
+# else
|
|
|
|
+ pthread_mutex_destroy(&q->lock);
|
|
|
|
+ pthread_cond_destroy(&q->wait);
|
|
|
|
+# endif
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+HL_API hl_deque *hl_deque_alloc() {
|
|
|
|
+ hl_deque *q = (hl_deque*)hl_gc_alloc_finalizer(sizeof(hl_deque));
|
|
|
|
+ q->free = hl_deque_free;
|
|
|
|
+ q->first = NULL;
|
|
|
|
+ q->last = NULL;
|
|
|
|
+ hl_add_root(&q->first);
|
|
|
|
+# if !defined(HL_THREADS)
|
|
|
|
+# elif defined(HL_WIN)
|
|
|
|
+ q->wait = CreateSemaphore(NULL,0,(1 << 30),NULL);
|
|
|
|
+ InitializeCriticalSection(&q->lock);
|
|
|
|
+# else
|
|
|
|
+ pthread_mutex_init(&q->lock,NULL);
|
|
|
|
+ pthread_cond_init(&q->wait,NULL);
|
|
|
|
+# endif
|
|
|
|
+ return q;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+HL_API void hl_deque_add( hl_deque *q, vdynamic *msg ) {
|
|
|
|
+ tqueue *t = (tqueue*)hl_gc_alloc_raw(sizeof(tqueue));
|
|
|
|
+ t->msg = msg;
|
|
|
|
+ t->next = NULL;
|
|
|
|
+ LOCK(q->lock);
|
|
|
|
+ if( q->last == NULL )
|
|
|
|
+ q->first = t;
|
|
|
|
+ else
|
|
|
|
+ q->last->next = t;
|
|
|
|
+ q->last = t;
|
|
|
|
+ SIGNAL(q->wait);
|
|
|
|
+ UNLOCK(q->lock);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+HL_API void hl_deque_push( hl_deque *q, vdynamic *msg ) {
|
|
|
|
+ tqueue *t = (tqueue*)hl_gc_alloc_raw(sizeof(tqueue));
|
|
|
|
+ t->msg = msg;
|
|
|
|
+ LOCK(q->lock);
|
|
|
|
+ t->next = q->first;
|
|
|
|
+ q->first = t;
|
|
|
|
+ if( q->last == NULL )
|
|
|
|
+ q->last = t;
|
|
|
|
+ SIGNAL(q->wait);
|
|
|
|
+ UNLOCK(q->lock);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+HL_API vdynamic *hl_deque_pop( hl_deque *q, bool block ) {
|
|
|
|
+ vdynamic *msg;
|
|
|
|
+ hl_blocking(true);
|
|
|
|
+ LOCK(q->lock);
|
|
|
|
+ while( q->first == NULL )
|
|
|
|
+ if( block ) {
|
|
|
|
+# if !defined(HL_THREADS)
|
|
|
|
+# elif defined(HL_WIN)
|
|
|
|
+ UNLOCK(q->lock);
|
|
|
|
+ WaitForSingleObject(q->wait,INFINITE);
|
|
|
|
+ LOCK(q->lock);
|
|
|
|
+# else
|
|
|
|
+ pthread_cond_wait(&q->wait,&q->lock);
|
|
|
|
+# endif
|
|
|
|
+ } else {
|
|
|
|
+ UNLOCK(q->lock);
|
|
|
|
+ hl_blocking(false);
|
|
|
|
+ return NULL;
|
|
|
|
+ }
|
|
|
|
+ msg = q->first->msg;
|
|
|
|
+ q->first = q->first->next;
|
|
|
|
+ if( q->first == NULL )
|
|
|
|
+ q->last = NULL;
|
|
|
|
+ else
|
|
|
|
+ SIGNAL(q->wait);
|
|
|
|
+ UNLOCK(q->lock);
|
|
|
|
+ hl_blocking(false);
|
|
|
|
+ return msg;
|
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
#define _DEQUE _ABSTRACT(hl_deque)
|
|
#define _DEQUE _ABSTRACT(hl_deque)
|
|
-DEFINE_PRIM(_DEQUE, deque_alloc, _NO_ARG);
|
|
|
|
-DEFINE_PRIM(_VOID, deque_add, _DEQUE _DYN);
|
|
|
|
-DEFINE_PRIM(_VOID, deque_push, _DEQUE _DYN);
|
|
|
|
-DEFINE_PRIM(_DYN, deque_pop, _DEQUE _BOOL);
|
|
|
|
|
|
+DEFINE_PRIM(_DEQUE, deque_alloc, _NO_ARG);
|
|
|
|
+DEFINE_PRIM(_VOID, deque_add, _DEQUE _DYN);
|
|
|
|
+DEFINE_PRIM(_VOID, deque_push, _DEQUE _DYN);
|
|
|
|
+DEFINE_PRIM(_DYN, deque_pop, _DEQUE _BOOL);
|
|
|
|
|
|
// ----------------- THREAD
|
|
// ----------------- THREAD
|
|
|
|
|