]> pd.if.org Git - pdclib.old/commitdiff
Add pthreads threading backend and move the POSIX port over to using it
authorOwen Shepherd <owen.shepherd@e43.eu>
Thu, 27 Dec 2012 21:49:28 +0000 (21:49 +0000)
committerOwen Shepherd <owen.shepherd@e43.eu>
Thu, 27 Dec 2012 21:49:28 +0000 (21:49 +0000)
opt/pthreads/_PDCLIB_threadconfig.h [new file with mode: 0644]
opt/pthreads/call_once.c [new file with mode: 0644]
opt/pthreads/mtx_destroy.c [new file with mode: 0644]
opt/pthreads/mtx_init.c [new file with mode: 0644]
opt/pthreads/mtx_lock.c [new file with mode: 0644]
opt/pthreads/mtx_timedlock.c [new file with mode: 0644]
opt/pthreads/mtx_trylock.c [new file with mode: 0644]
opt/pthreads/mtx_unlock.c [new file with mode: 0644]
platform/posix/Config.jam
platform/posix/functions/_PDCLIB/stdinit.c
platform/posix/internals/_PDCLIB_config.h

diff --git a/opt/pthreads/_PDCLIB_threadconfig.h b/opt/pthreads/_PDCLIB_threadconfig.h
new file mode 100644 (file)
index 0000000..75e6f3a
--- /dev/null
@@ -0,0 +1,23 @@
+#ifndef _PDCLIB_THREADCONFIG_H
+#define _PDCLIB_THREADCONFIG_H
+#include <_PDCLIB_aux.h>
+#include <_PDCLIB_config.h>
+
+#ifdef __APPLE__
+#include <_types.h>
+#define _PDCLIB_THR_T __darwin_pthread_t
+#define _PDCLIB_CND_T __darwin_pthread_cond_t
+#define _PDCLIB_MTX_T __darwin_pthread_mutex_t
+
+#define _PDCLIB_TSS_DTOR_ITERATIONS 5
+#define _PDCLIB_TSS_T __darwin_pthread_key_t
+
+typedef __darwin_pthread_once_t _PDCLIB_once_flag;
+#define _PDCLIB_ONCE_FLAG_INIT {_PTHREAD_ONCE_SIG_init, {0}}
+
+#else
+#error Need to interrogate the C library headers for your platform
+#endif
+
+_PDCLIB_END_EXTERN_C
+#endif
diff --git a/opt/pthreads/call_once.c b/opt/pthreads/call_once.c
new file mode 100644 (file)
index 0000000..123ad3a
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef REGTEST
+#include <threads.h>
+#include <pthread.h>
+
+void call_once(once_flag *flag, void (*func)(void))
+{
+    pthread_once(flag, func);
+}
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+#ifndef REGTEST
+static int count = 0;
+static once_flag once = ONCE_FLAG_INIT;
+
+static void do_once(void)
+{
+    count++;
+}
+#endif
+
+int main( void )
+{
+#ifndef REGTEST
+    TESTCASE(count == 0);
+    call_once(&once, do_once);
+    TESTCASE(count == 1);
+    call_once(&once, do_once);
+    TESTCASE(count == 1);
+    do_once();
+    TESTCASE(count == 2);
+#endif
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/pthreads/mtx_destroy.c b/opt/pthreads/mtx_destroy.c
new file mode 100644 (file)
index 0000000..2d0a2a2
--- /dev/null
@@ -0,0 +1,19 @@
+#ifndef REGTEST
+#include <threads.h>
+#include <pthread.h>
+
+void mtx_destroy(mtx_t *mtx)
+{
+    pthread_mutex_destroy(mtx);
+}
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/pthreads/mtx_init.c b/opt/pthreads/mtx_init.c
new file mode 100644 (file)
index 0000000..90c67e6
--- /dev/null
@@ -0,0 +1,44 @@
+#ifndef REGTEST
+#include <threads.h>
+#include <pthread.h>
+
+int mtx_init(mtx_t *mtx, int type)
+{
+    if(type == mtx_plain || type == mtx_timed) {
+        if(pthread_mutex_init(mtx, NULL) == 0)
+            return thrd_success;
+        else
+            return thrd_error;
+
+    } else if (type == mtx_recursive || type == (mtx_recursive | mtx_timed)) {
+        int rc = thrd_error;
+        pthread_mutexattr_t attr;
+
+        if(pthread_mutexattr_init(&attr))
+            goto cleanup1;
+
+        if(pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE))
+            goto cleanup2;
+
+        if(pthread_mutex_init(mtx, &attr) == 0)
+            rc = thrd_success;
+
+    cleanup2:
+        pthread_mutexattr_destroy(&attr);
+    cleanup1:
+        return rc;
+    } else {
+        return thrd_error;
+    }
+}
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/pthreads/mtx_lock.c b/opt/pthreads/mtx_lock.c
new file mode 100644 (file)
index 0000000..88a1304
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef REGTEST
+#include <threads.h>
+#include <pthread.h>
+
+int mtx_lock(mtx_t *mtx)
+{
+    if(pthread_mutex_lock(mtx))
+        return thrd_error;
+    else return thrd_success;
+}
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/pthreads/mtx_timedlock.c b/opt/pthreads/mtx_timedlock.c
new file mode 100644 (file)
index 0000000..ed490a8
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef REGTEST
+#include <threads.h>
+// On Mac OS X, supress system definition of struct timespec
+#ifdef __APPLE__
+    #define _STRUCT_TIMESPEC struct timespec
+#endif
+#include <unistd.h>
+#include <pthread.h>
+
+/* Can only implement if timeouts are supported.
+ *
+ * Namely, Mac OS X does not implement timeouts 
+ */
+#if defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS - 200112L) >= 0L
+int mtx_timedlock(mtx_t *restrict mtx, const struct timespec *restrict ts)
+{
+    switch(pthread_mutex_timedlock(mtx, ts)) {
+        case 0:
+            return thrd_success;
+        case ETIMEDOUT:
+            return thrd_timeout;
+        default:
+            return thrd_error;
+    }
+}
+#endif
+
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/pthreads/mtx_trylock.c b/opt/pthreads/mtx_trylock.c
new file mode 100644 (file)
index 0000000..8a095a5
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef REGTEST
+#include <threads.h>
+#include <pthread.h>
+#include <errno.h>
+
+int mtx_trylock(mtx_t *mtx)
+{
+    switch(pthread_mutex_trylock(mtx)) {
+        case 0:
+            return thrd_success;
+        case EBUSY:
+            return thrd_busy;
+        default:
+            return thrd_error;
+    }
+}
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
diff --git a/opt/pthreads/mtx_unlock.c b/opt/pthreads/mtx_unlock.c
new file mode 100644 (file)
index 0000000..0da592a
--- /dev/null
@@ -0,0 +1,21 @@
+#ifndef REGTEST
+#include <threads.h>
+#include <pthread.h>
+
+int mtx_unlock(mtx_t *mtx)
+{
+    if(pthread_mutex_unlock(mtx) == 0)
+        return thrd_success;
+    return thrd_error;
+}
+#endif
+
+#ifdef TEST
+#include <_PDCLIB_test.h>
+
+int main( void )
+{
+    return TEST_RESULTS;
+}
+
+#endif
index f068ce64af1e7d0797abfefdd8411337a9dc0c9f..20fc4ad82897b965fea845d311ca9eab8e2f5e58 100644 (file)
@@ -11,4 +11,4 @@ if $(OS) = "MACOSX" {
     PDCLIB_TEST_LINKLIBS += -lgcc ;\r
 }\r
 \r
-PDCLIB_OPTIONS = nothread notime dlmalloc ;
\ No newline at end of file
+PDCLIB_OPTIONS = pthreads notime dlmalloc ;
\ No newline at end of file
index 8400ce3e9f00f0b07a3041dfa2c78029fd375e48..a3c9e8b6e2ec19025187f46c5ef0998e6c683581 100644 (file)
@@ -16,6 +16,7 @@
 #include <limits.h>
 
 #ifndef REGTEST
+#include <threads.h>
 
 /* In a POSIX system, stdin / stdout / stderr are equivalent to the (int) file
    descriptors 0, 1, and 2 respectively.
@@ -30,14 +31,62 @@ static unsigned char _PDCLIB_sout_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
 static unsigned char _PDCLIB_serr_ungetbuf[_PDCLIB_UNGETCBUFSIZE];
 
 extern _PDCLIB_fileops_t _PDCLIB_fileops;
-static struct _PDCLIB_file_t _PDCLIB_serr = { &_PDCLIB_fileops, { .sval = 2 }, 0, _PDCLIB_serr_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_serr_ungetbuf, _IONBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, NULL, NULL };
-static struct _PDCLIB_file_t _PDCLIB_sout = { &_PDCLIB_fileops, { .sval = 1 }, 0, _PDCLIB_sout_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sout_ungetbuf, _IOLBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, NULL, &_PDCLIB_serr };
-static struct _PDCLIB_file_t _PDCLIB_sin  = { &_PDCLIB_fileops, { .sval = 0 }, 0, _PDCLIB_sin_buffer, BUFSIZ, 0, 0, { 0, 0 }, 0, _PDCLIB_sin_ungetbuf, _IOLBF | _PDCLIB_FREAD | _PDCLIB_STATIC, NULL, &_PDCLIB_sout };
+
+static struct _PDCLIB_file_t _PDCLIB_serr = { 
+    .ops        = &_PDCLIB_fileops, 
+    .handle     = { .sval = 2 }, 
+    .buffer     = _PDCLIB_serr_buffer, 
+    .bufsize    = BUFSIZ, 
+    .bufidx     = 0, 
+    .bufend     = 0, 
+    .pos        = { 0, 0 }, 
+    .ungetidx   = 0, 
+    .ungetbuf   = _PDCLIB_serr_ungetbuf, 
+    .status     = _IONBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, 
+    .filename   = NULL, 
+    .next       = NULL,
+};
+static struct _PDCLIB_file_t _PDCLIB_sout = { 
+    .ops        = &_PDCLIB_fileops, 
+    .handle     = { .sval = 1 },
+    .buffer     = _PDCLIB_sout_buffer, 
+    .bufsize    = BUFSIZ, 
+    .bufidx     = 0, 
+    .bufend     = 0, 
+    .pos        = { 0, 0 }, 
+    .ungetidx   = 0, 
+    .ungetbuf   = _PDCLIB_sout_ungetbuf, 
+    .status     = _IOLBF | _PDCLIB_FWRITE | _PDCLIB_STATIC, 
+    .filename   = NULL, 
+    .next       = &_PDCLIB_serr 
+};
+static struct _PDCLIB_file_t _PDCLIB_sin  = { 
+    .ops        = &_PDCLIB_fileops, 
+    .handle     = { .sval = 0 }, 
+    .buffer     = _PDCLIB_sin_buffer, 
+    .bufsize    = BUFSIZ, 
+    .bufidx     = 0, 
+    .bufend     = 0, 
+    .pos        = { 0, 0 }, 
+    .ungetidx   = 0, 
+    .ungetbuf   = _PDCLIB_sin_ungetbuf, 
+    .status     = _IOLBF | _PDCLIB_FREAD | _PDCLIB_STATIC, 
+    .filename   = NULL, 
+    .next       = &_PDCLIB_sout 
+};
 
 struct _PDCLIB_file_t * stdin  = &_PDCLIB_sin;
 struct _PDCLIB_file_t * stdout = &_PDCLIB_sout;
 struct _PDCLIB_file_t * stderr = &_PDCLIB_serr;
 
+/* Todo: Better solution than this! */
+__attribute__((constructor)) void init_stdio(void)
+{
+    mtx_init(&stdin->lock,  mtx_recursive);
+    mtx_init(&stdout->lock, mtx_recursive);
+    mtx_init(&stderr->lock, mtx_recursive);
+}
+
 /* FIXME: This approach is a possible attack vector. */
 struct _PDCLIB_file_t * _PDCLIB_filelist = &_PDCLIB_sin;
 
index 5cee1ef51340c69a394ea335101e32a18534cd9b..099e970fda5d7240f23ad88cf0446a3caefddd0b 100644 (file)
@@ -186,7 +186,7 @@ struct _PDCLIB_imaxdiv_t
  * any functions for manipulating more accurate values of time_t, this is 
  * probably not useful.
  */
-#define _PDCLIB_time  unsigned long long
+#define _PDCLIB_time  long
 
 /* <time.h>: clock_t
  *