I need a review of some code I created that tries to "emulate"
some of C11 threading capabilities. For some reason, I cannot
find a compiler that has C11 threading. Ming, MSVC, and others
do not seem to have completed C11. C++11 is another story. That
seems to have some very nice support! Damn. Anyway, here is a
mock up, based on pthreads, that allows one to program C11
threads. Well, at least it does for me. Anyway, this code is
pre-alpha, pre-origin, pre-universe state. Before I go any further
on this endeavor, well, I need a review of the code in its current
state!
Well, here is the pile!:
http://pastebin.com/bJUbDmKy
________________________________________________________________
#if ! defined (CT_C11_THREADS_H_EMULATION_H)
# define CT_C11_THREADS_H_EMULATION_H 1
# if defined (__cplusplus)
extern "C"
{
# endif
#if defined (CT_C11_THREADS_H_PRINTF_LOG)
# include <stdio.h>
# define CT_C11_THREADS_H_PRINTF(mp_exp) printf mp_exp
#else
# define CT_C11_THREADS_H_PRINTF(mp_exp) ((void)(0))
#endif
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
typedef int (*ct_thrd_start_t) (void*);
struct ct_thrd_user
{
pthread_t ptid;
};
struct ct_thrd_sys
{
ct_thrd_start_t fp_user;
void* user_ctx;
int user_ret;
};
enum ct_thrd_sys_status
{
ct_thrd_success = 0,
ct_thrd_nomem = 1,
ct_thrd_timedout = 2,
ct_thrd_busy = 3,
ct_thrd_error = 4
};
/* low-level system threading API's
__________________________________________________________________*/
static struct ct_thrd_sys*
ct_thrd_sys_create(
ct_thrd_start_t fp_user,
void* user_ctx
);
static void
ct_thrd_sys_destroy(
struct ct_thrd_sys* const self
);
static void*
ct_thrd_sys_entry(
void* self_raw
);
struct ct_thrd_sys*
ct_thrd_sys_create(
ct_thrd_start_t fp_user,
void* user_ctx
){
struct ct_thrd_sys* const self = malloc(sizeof(*self));
if (self)
{
self->fp_user = fp_user;
self->user_ctx = user_ctx;
self->user_ret = 0;
}
CT_C11_THREADS_H_PRINTF(("ct_thrd_sys_create = %p\r\n", (void*)self));
return self;
}
void
ct_thrd_sys_destroy(
struct ct_thrd_sys* const self
){
free(self);
CT_C11_THREADS_H_PRINTF(
("ct_thrd_sys_destroy(self = %p)\r\n", (void*)self)
);
}
void*
ct_thrd_sys_entry(
void* self_raw
){
struct ct_thrd_sys* const self = self_raw;
CT_C11_THREADS_H_PRINTF(
("ct_thrd_sys_entry(self_raw = %p):Enter\r\n", self_raw)
);
self->user_ret = self->fp_user(self->user_ctx);
CT_C11_THREADS_H_PRINTF(
("ct_thrd_sys_entry(self_raw = %p):Exit = %p\r\n", self_raw,
(void*)self)
);
return self;
}
/* C11 emulation API layer
__________________________________________________________________*/
/* Threading API
______________________________________________________________*/
typedef struct ct_thrd_user ct_thrd_t;
static int
ct_thrd_create(
ct_thrd_t* uself,
ct_thrd_start_t fp_user,
void* user_ctx
);
static int
ct_thrd_join(
ct_thrd_t self,
int* user_retv
);
int
ct_thrd_create(
ct_thrd_t* uself,
ct_thrd_start_t fp_user,
void* user_ctx
){
struct ct_thrd_sys* const self =
ct_thrd_sys_create(fp_user, user_ctx);
if (self)
{
int status = pthread_create(&uself->ptid, NULL, ct_thrd_sys_entry,
self);
if (! status)
{
return ct_thrd_success;
}
ct_thrd_sys_destroy(self);
}
return ct_thrd_nomem;
}
int
ct_thrd_join(
ct_thrd_t self,
int* user_retv
){
void* ptjret = NULL;
pthread_join(self.ptid, &ptjret);
if (ptjret)
{
struct ct_thrd_sys* const self = ptjret;
if (user_retv)
{
*user_retv = self->user_ret;
}
ct_thrd_sys_destroy(self);
return ct_thrd_success;
}
return ct_thrd_error;
}
/* Thread Specific Storage API
______________________________________________________________*/
typedef pthread_key_t ct_tss_t;
typedef void(*ct_tss_dtor_t) (void*);
static int
ct_tss_create(
ct_tss_t* self,
ct_tss_dtor_t fp_user_dtor
);
static void
ct_tss_delete(
ct_tss_t self
);
static int
ct_tss_set(
ct_tss_t self,
void* user_ctx
);
#define ct_tss_get(mp_self) pthread_getspecific((mp_self))
int
ct_tss_create(
ct_tss_t* self,
ct_tss_dtor_t fp_user_dtor
){
int status = pthread_key_create(self, fp_user_dtor);
if (!status)
{
return ct_thrd_success;
}
return ct_thrd_error;
}
void
ct_tss_delete(
ct_tss_t self
){
int status = pthread_key_delete(self);
if (! status)
{
return;
}
assert(! status);
}
int
ct_tss_set(
ct_tss_t self,
void* user_ctx
){
int status = pthread_setspecific(self, user_ctx);
if (!status)
{
return ct_thrd_success;
}
return ct_thrd_error;
}
/* Mutex API
______________________________________________________________*/
typedef pthread_mutex_t ct_mtx_t;
enum {
ct_mtx_plain = 1,
ct_mtx_recursive = 2,
ct_mtx_timed = 4
};
int
ct_mtx_init(
ct_mtx_t* self,
int type
){
if (type == ct_mtx_plain)
{
int status = pthread_mutex_init(self, NULL);
if (! status)
{
return ct_thrd_success;
}
}
return ct_thrd_error;
}
void
ct_mtx_destroy(
ct_mtx_t* self
){
int status = pthread_mutex_destroy(self);
if (! status)
{
return;
}
assert(! status);
}
int
ct_mtx_lock(
ct_mtx_t* self
){
int status = pthread_mutex_lock(self);
if (! status)
{
return ct_thrd_success;
}
assert(! status);
return ct_thrd_error;
}
int
ct_mtx_unlock(
ct_mtx_t* self
){
int status = pthread_mutex_unlock(self);
if (!status)
{
return ct_thrd_success;
}
assert(! status);
return ct_thrd_error;
}
/* Mutex API
______________________________________________________________*/
typedef pthread_cond_t ct_cnd_t;
int
ct_cnd_init(
ct_cnd_t* self
){
int status = pthread_cond_init(self, NULL);
if (! status)
{
return ct_thrd_success;
}
return ct_thrd_error;
}
void
ct_cnd_destroy(
ct_cnd_t* self
){
int status = pthread_cond_destroy(self);
if (! status)
{
return;
}
assert(! status);
}
int
ct_cnd_signal(
ct_cnd_t* self
){
int status = pthread_cond_signal(self);
if (! status)
{
return ct_thrd_success;
}
assert(! status);
return ct_thrd_error;
}
int
ct_cnd_broadcast(
ct_cnd_t* self
){
int status = pthread_cond_broadcast(self);
if (! status)
{
return ct_thrd_success;
}
assert(! status);
return ct_thrd_error;
}
int
ct_cnd_wait(
ct_cnd_t* self,
ct_mtx_t* mtx
){
int status = pthread_cond_wait(self, mtx);
if (! status)
{
return ct_thrd_success;
}
assert(! status);
return ct_thrd_error;
}
/* Mock up the final C11 API with some macros... ;^o
______________________________________________________________*/
/* C11 threading API
_________________________________________________*/
#define thrd_success ct_thrd_success
#define thrd_nomem ct_thrd_nomem
#define thrd_timedout ct_thrd_timedout
#define thrd_busy ct_thrd_busy
#define thrd_error ct_thrd_error
#define thrd_t ct_thrd_t
#define thrd_create ct_thrd_create
#define thrd_join ct_thrd_join
/* C11 thread specific storage API
_________________________________________________*/
#define tss_t ct_tss_t
#define tss_create ct_tss_create
#define tss_delete ct_tss_delete
#define tss_set ct_tss_set
#define tss_get ct_tss_get
/* C11 mutex API
_________________________________________________*/
#define mtx_plain ct_mtx_plain
#define mtx_recursive ct_mtx_recursive
#define mtx_timed ct_mtx_timed
#define mtx_t ct_mtx_t
#define mtx_init ct_mtx_init
#define mtx_destroy ct_mtx_destroy
#define mtx_lock ct_mtx_lock
#define mtx_unlock ct_mtx_unlock
/* C11 condition variable API
_________________________________________________*/
#define cnd_t ct_cnd_t
#define cnd_init ct_cnd_init
#define cnd_destroy ct_cnd_destroy
#define cnd_signal ct_cnd_signal
#define cnd_broadcast ct_cnd_broadcast
#define cnd_wait ct_cnd_wait
# if defined (__cplusplus)
}
# endif
#endif
________________________________________________________________
This is in my personal coding style. I am sorry if it ends up pissing you
off!
;^o
Anyway, what do you think?
:^)