mailing list of musl libc
 help / color / mirror / code / Atom feed
* C11 threads
@ 2014-07-25 10:00 Jens Gustedt
  2014-07-25 10:40 ` Szabolcs Nagy
  0 siblings, 1 reply; 21+ messages in thread
From: Jens Gustedt @ 2014-07-25 10:00 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1555 bytes --]

Hi everybody,
 after I have seen that gcc since 4.9 has a working implementation of
atomics, I convinced myself to implement C11 threads within musl.

I was really amazed, in essence this was just work of several
hours. The cleanness of musl made it really a pleasant experience.

I think the implementation is straight forward, there are only very
few minor glitches possible. But I thought that I first discuss with
you.

Choices :

 - all types are just the corresponding POSIX types

Issues :

 - a lot of C11 are just weak symbols. to avoid polluting the link
   space of a C11 application, I had to transform a lot of POSIX
   function symbols into weak symbols, too.

 - the include file threads.h includes pthread.h, so the namespace of
   the C11 implementation is poluted with the pthreads stuff

 - pthread_create and thrd_create are still too tightly linked
   together. It would be good to split the corresponding file in two,
   but this would make maintenance a bit more difficult.

 - there are still some symbols missing, for some of the functions
   that I implemented as macro. work for a winter day

 - I don't have much tests for all of this


I join my version of the threads.h file that has some comments on the
minor choices.

Jens


-- 
:: INRIA Nancy Grand Est ::: AlGorille ::: ICube/ICPS :::
:: ::::::::::::::: office Strasbourg : +33 368854536   ::
:: :::::::::::::::::::::: gsm France : +33 651400183   ::
:: ::::::::::::::: gsm international : +49 15737185122 ::
:: http://icube-icps.unistra.fr/index.php/Jens_Gustedt ::




[-- Attachment #2: threads.h --]
[-- Type: text/x-chdr, Size: 3757 bytes --]

#ifndef _THREADS_H
#define _THREADS_H

#include <pthread.h>
#include <errno.h>

enum {
  thrd_success = 0,
  thrd_busy = EBUSY,
  thrd_error = EINVAL,
  thrd_nomem = ENOMEM,
  thrd_timedout = ETIMEDOUT,
};

enum {
  mtx_plain = 0,
  mtx_recursive = PTHREAD_MUTEX_RECURSIVE,
  mtx_check = PTHREAD_MUTEX_ERRORCHECK,
  // all mutexes are timed, here. so this is a no-op
  mtx_timed = 0,
};

_Static_assert((mtx_plain | mtx_recursive | mtx_check | mtx_timed) == 3,
               "This implementation only works on top of musl");

#define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
#define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS

typedef pthread_cond_t cnd_t;
typedef pthread_mutex_t mtx_t;
typedef pthread_once_t once_flag;
typedef pthread_t thrd_t;
typedef pthread_key_t tss_t;

typedef int (*thrd_start_t)(void*);
typedef void (*tss_dtor_t)(void*);

#define thread_local _Thread_local

/* Don't create just additional symbols for the simple reason that the
   return type of the POSIX and C11 functions are different. */

int __pthread_once(once_flag *, void (*)(void));
// void call_once(once_flag *flag, void (*func)(void));
#define _call_once(FL, FU) (void)__pthread_once((FL), (FU))
#define call_once _call_once

_Noreturn void __pthread_exit(void *);
// _Noreturn void thrd_exit(int res);
#define _thrd_exit(RES) (__pthread_exit((void*)(intptr_t)(RES)))
#define thrd_exit _thrd_exit

int __pthread_cond_destroy(cnd_t *cond);
// void cnd_destroy(cnd_t *cond);
#define _cnd_destroy(CND) (void)__pthread_cond_destroy((CND))
#define cnd_destroy _cnd_destroy

void __pthread_mutex_destroy(mtx_t *mtx);
// void mtx_destroy(mtx_t *mtx);
#define _mtx_destroy(MTX) (void)__pthread_mutex_destroy((MTX))
#define mtx_destroy _mtx_destroy

int __pthread_mutex_unlock(mtx_t *mtx);
// int mtx_unlock(mtx_t *mtx);
#define _mtx_unlock(MTX) (__pthread_mutex_unlock((MTX)) ? thrd_error : thrd_success)
#define mtx_unlock _mtx_unlock

int __pthread_key_delete(tss_t key);
// void tss_delete(tss_t key);
#define _tss_delete(KEY)  (void)__pthread_key_delete((KEY))
#define tss_delete _tss_delete


/* Best of all worlds, these are just weak aliases */
int cnd_broadcast(cnd_t *);                   // pthread_cond_broadcast
int cnd_signal(cnd_t *);                      // pthread_cond_signal
int cnd_timedwait(cnd_t *restrict,            // pthread_cond_timedwait
                  mtx_t *restrict,
                  const struct timespec *restrict);
int cnd_wait(cnd_t *cond, mtx_t *mtx);        // pthread_cond_wait

int mtx_lock(mtx_t *);                        // pthread_mutex_lock
int mtx_timedlock(mtx_t *restrict,            // pthread_mutex_timedlock
                  const struct timespec *restrict);
int mtx_trylock(mtx_t *);                     // pthread_mutex_trylock

thrd_t thrd_current(void);                    // pthread_self
int thrd_equal(thrd_t, thrd_t);               // pthread_equal
int thrd_detach(thrd_t);                      // pthread_detach

int tss_create(tss_t *, tss_dtor_t);          // pthread_key_create
void *tss_get(tss_t);                         // pthread_getspecific
int tss_set(tss_t, void *);                   // pthread_setspecific


/* specialized implementations */

int cnd_init(cnd_t *);
int mtx_init(mtx_t *, int);

// reimplemented because of different calling convention
// shaves of a lot of code for attributes and cancelation
int thrd_create(thrd_t *,
                thrd_start_t,
                void *);

// reimplemented because of different calling convention
int thrd_join(thrd_t, int *);

// reimplemented because of different return value convention
int thrd_sleep(const struct timespec *,
               struct timespec *);

// reimplemented because of different return type
void thrd_yield(void);

#endif

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2014-07-26 15:48 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-25 10:00 C11 threads Jens Gustedt
2014-07-25 10:40 ` Szabolcs Nagy
2014-07-25 11:06   ` Jens Gustedt
2014-07-25 13:04     ` Szabolcs Nagy
2014-07-25 13:38       ` Jens Gustedt
2014-07-25 13:42       ` Morten Welinder
2014-07-25 14:15         ` Szabolcs Nagy
2014-07-25 16:14       ` Rich Felker
2014-07-25 21:59         ` Jens Gustedt
2014-07-25 22:25           ` Rich Felker
2014-07-25 15:41     ` Rich Felker
2014-07-25 17:10       ` Jens Gustedt
2014-07-25 22:19         ` Rich Felker
2014-07-25 23:26           ` Jens Gustedt
2014-07-26  2:24             ` Rich Felker
2014-07-26  7:16               ` Jens Gustedt
2014-07-26  7:35                 ` Rich Felker
2014-07-26  8:32                   ` Jens Gustedt
2014-07-26  9:03                     ` Rich Felker
2014-07-26 11:15                       ` Jens Gustedt
2014-07-26 15:48                 ` Jens Gustedt

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).