Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

highly limited pre-alpha C11 <threads.h> emulation...

99 views
Skip to first unread message

Chris M. Thomasson

unread,
Jun 27, 2015, 4:40:16 PM6/27/15
to
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?

:^)

0 new messages