Add Semaphores to r_util and use them for joining Tasks (#10622)

* Add Semaphores to r_util

* Use Semaphore for joining Tasks
This commit is contained in:
Florian Märkl 2018-07-05 00:25:57 +02:00 committed by radare
parent 78ece9fd2b
commit a566e7af99
6 changed files with 78 additions and 13 deletions

View File

@ -63,11 +63,12 @@ R_API void r_core_task_list(RCore *core, int mode) {
}
static void task_join(RCoreTask *task) {
RThreadLock *lock = task->running_lock;
if (!lock) {
RThreadSemaphore *sem = task->running_sem;
if (!sem) {
return;
}
r_th_lock_wait (lock);
r_th_sem_wait (sem);
r_th_sem_post (sem);
}
R_API void r_core_task_join(RCore *core, RCoreTask *current, RCoreTask *task) {
@ -109,7 +110,7 @@ R_API RCoreTask *r_core_task_new(RCore *core, bool create_cons, const char *cmd,
task->cmd = cmd ? strdup (cmd) : NULL;
task->cmd_log = false;
task->res = NULL;
task->running_lock = NULL;
task->running_sem = NULL;
task->dispatch_cond = r_th_cond_new ();
task->dispatch_lock = r_th_lock_new (false);
if (!task->dispatch_cond || !task->dispatch_lock) {
@ -143,7 +144,7 @@ R_API void r_core_task_free (RCoreTask *task) {
free (task->cmd);
free (task->res);
r_th_free (task->thread);
r_th_lock_free (task->running_lock);
r_th_sem_free (task->running_sem);
r_th_cond_free (task->dispatch_cond);
r_th_lock_free (task->dispatch_lock);
r_cons_context_free (task->cons_context);
@ -271,8 +272,8 @@ static int task_run(RCoreTask *task) {
task->cb (task->user, task->res);
}
if (task->running_lock) {
r_th_lock_leave (task->running_lock);
if (task->running_sem) {
r_th_sem_post (task->running_sem);
}
return res;
@ -284,11 +285,11 @@ static int task_run_thread(RThread *th) {
R_API void r_core_task_enqueue(RCore *core, RCoreTask *task) {
r_th_lock_enter (core->tasks_lock);
if (!task->running_lock) {
task->running_lock = r_th_lock_new (false);
if (!task->running_sem) {
task->running_sem = r_th_sem_new (1);
}
if (task->running_lock) {
r_th_lock_enter (task->running_lock);
if (task->running_sem) {
r_th_sem_wait (task->running_sem);
}
r_list_append (core->tasks, task);
task->thread = r_th_new (task_run_thread, task, 0);

View File

@ -721,7 +721,7 @@ typedef enum {
typedef struct r_core_task_t {
int id;
RTaskState state;
RThreadLock *running_lock;
RThreadSemaphore *running_sem;
void *user;
RCore *core;
RThreadCond *dispatch_cond;

View File

@ -11,14 +11,17 @@
#define R_TH_TID HANDLE
#define R_TH_LOCK_T CRITICAL_SECTION
#define R_TH_COND_T CONDITION_VARIABLE
#define R_TH_SEM_T HANDLE
//HANDLE
#elif HAVE_PTHREAD
#define __GNU
#include <semaphore.h>
#include <pthread.h>
#define R_TH_TID pthread_t
#define R_TH_LOCK_T pthread_mutex_t
#define R_TH_COND_T pthread_cond_t
#define R_TH_SEM_T sem_t
#else
#error Threading library only supported for pthread and w32
@ -30,6 +33,10 @@
extern "C" {
#endif
typedef struct r_th_sem_t {
R_TH_SEM_T sem;
} RThreadSemaphore;
typedef struct r_th_lock_t {
int refs;
R_TH_LOCK_T lock;
@ -71,6 +78,11 @@ R_API bool r_th_pause(RThread *th, bool enable);
R_API bool r_th_try_pause(RThread *th);
R_API R_TH_TID r_th_self(void);
R_API RThreadSemaphore *r_th_sem_new(unsigned int initial);
R_API void r_th_sem_free(RThreadSemaphore *sem);
R_API void r_th_sem_post(RThreadSemaphore *sem);
R_API void r_th_sem_wait(RThreadSemaphore *sem);
R_API RThreadLock *r_th_lock_new(bool recursive);
R_API int r_th_lock_wait(RThreadLock *th);
R_API int r_th_lock_check(RThreadLock *thl);

View File

@ -15,7 +15,7 @@ OBJS=binheap.o mem.o pool.o unum.o str.o hex.o file.o range.o tinyrange.o
OBJS+=prof.o cache.o sys.o buf.o w32-sys.o ubase64.o base85.o base91.o
OBJS+=list.o flist.o mixed.o btree.o chmod.o graph.o
OBJS+=regex/regcomp.o regex/regerror.o regex/regexec.o uleb128.o
OBJS+=sandbox.o calc.o thread.o thread_lock.o thread_cond.o
OBJS+=sandbox.o calc.o thread.o thread_sem.o thread_lock.o thread_cond.o
OBJS+=strpool.o bitmap.o date.o format.o pie.o print.o ctype.o
OBJS+=seven.o slist.o randomart.o log.o zip.o debruijn.o
OBJS+=utf8.o utf16.o utf32.o strbuf.o lib.o name.o spaces.o signal.o syscmd.o

View File

@ -62,6 +62,7 @@ files = [
'sys.c',
'syscmd.c',
'thread.c',
'thread_sem.c',
'thread_lock.c',
'thread_cond.c',
'thread_pipe.c',

51
libr/util/thread_sem.c Normal file
View File

@ -0,0 +1,51 @@
/* radare2 - LGPL - Copyright 2018 - thestr4ng3r */
#include <r_th.h>
R_API RThreadSemaphore *r_th_sem_new(unsigned int initial) {
RThreadSemaphore *sem = R_NEW (RThreadSemaphore);
if (!sem) {
return NULL;
}
#if HAVE_PTHREAD
if (sem_init (&sem->sem, 0, initial) != 0) {
free (sem);
return NULL;
}
#elif __WINDOWS__ && !defined(__CYGWIN__)
sem->sem = CreateSemaphore (NULL, (LONG)initial, ST32_MAX, NULL);
if (!sem->sem) {
free (sem);
return NULL;
}
#endif
return sem;
}
R_API void r_th_sem_free(RThreadSemaphore *sem) {
if (!sem) {
return;
}
#if HAVE_PTHREAD
sem_destroy (&sem->sem);
#elif __WINDOWS__ && !defined(__CYGWIN__)
CloseHandle (sem->sem);
#endif
free (sem);
}
R_API void r_th_sem_post(RThreadSemaphore *sem) {
#if HAVE_PTHREAD
sem_post (&sem->sem);
#elif __WINDOWS__ && !defined(__CYGWIN__)
ReleaseSemaphore (sem->sem, 1, NULL);
#endif
}
R_API void r_th_sem_wait(RThreadSemaphore *sem) {
#if HAVE_PTHREAD
sem_wait (&sem->sem);
#elif __WINDOWS__ && !defined(__CYGWIN__)
WaitForSingleObject (sem->sem, INFINITE);
#endif
}