summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Sherrill <joel@rtems.org>2017-10-05 08:59:43 -0500
committerJoel Sherrill <joel@rtems.org>2017-10-12 14:17:52 -0500
commit45bf0f4be0f73506b8abe6d092ac6f5b84c3d9fc (patch)
treea5b3ac778ba6fcd0bb098187b5cc9696484e9ab6
parentb6c5dbb24981b0ca93a94734acccb65be872b34f (diff)
Add C11 Threading Examples
-rw-r--r--c11/c11_cndvar01/Makefile20
-rw-r--r--c11/c11_cndvar01/rtems_config.c53
-rw-r--r--c11/c11_cndvar01/test.c141
-rw-r--r--c11/c11_cndvar01/wscript14
-rw-r--r--c11/c11_key01/Makefile20
-rw-r--r--c11/c11_key01/rtems_config.c53
-rw-r--r--c11/c11_key01/test.c123
-rw-r--r--c11/c11_key01/wscript14
-rw-r--r--c11/c11_mutex01/Makefile20
-rw-r--r--c11/c11_mutex01/rtems_config.c53
-rw-r--r--c11/c11_mutex01/test.c85
-rw-r--r--c11/c11_mutex01/wscript14
-rw-r--r--c11/c11_thread01/Makefile20
-rw-r--r--c11/c11_thread01/rtems_config.c53
-rw-r--r--c11/c11_thread01/test.c103
-rw-r--r--c11/c11_thread01/wscript14
-rw-r--r--c11/wscript13
-rw-r--r--wscript1
18 files changed, 814 insertions, 0 deletions
diff --git a/c11/c11_cndvar01/Makefile b/c11/c11_cndvar01/Makefile
new file mode 100644
index 0000000..f28b952
--- /dev/null
+++ b/c11/c11_cndvar01/Makefile
@@ -0,0 +1,20 @@
+#
+# RTEMS_MAKEFILE_PATH is typically set in an environment variable
+#
+
+PGM=${ARCH}/c11_cndvar01.exe
+
+# C source names
+CSRCS = rtems_config.c test.c
+COBJS = $(CSRCS:%.c=${ARCH}/%.o)
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)
+
+all: ${ARCH} $(PGM)
+
+$(PGM): $(OBJS)
+ $(make-exe)
diff --git a/c11/c11_cndvar01/rtems_config.c b/c11/c11_cndvar01/rtems_config.c
new file mode 100644
index 0000000..a596695
--- /dev/null
+++ b/c11/c11_cndvar01/rtems_config.c
@@ -0,0 +1,53 @@
+/**
+ * @brief RTEMS Configuration for C11 Mutex Example
+ */
+
+/*
+ * This file's license is 2-clause BSD as in this distribution's
+ * LICENSE.2 file.
+ */
+
+#include <stdlib.h>
+
+int main(int argc, char **argv);
+
+static char *argv_list[] = {
+ "c11-cndvar01",
+ ""
+};
+
+static void *POSIX_Init(void *arg)
+{
+ int rc;
+
+ (void) arg; /* deliberately ignored */
+
+ /*
+ * Initialize optional services
+ */
+
+ /*
+ * Could get arguments from command line or have a static set.
+ */
+ rc = main(1, argv_list);
+
+ exit(rc);
+ return NULL;
+}
+
+#include <bsp.h> /* for device driver prototypes */
+
+/* NOTICE: the clock driver is explicitly disabled */
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+#define CONFIGURE_UNLIMITED_OBJECTS
+#define CONFIGURE_UNIFIED_WORK_AREAS
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (64 * 1024)
+
+#define CONFIGURE_INIT
+#include <rtems/confdefs.h>
diff --git a/c11/c11_cndvar01/test.c b/c11/c11_cndvar01/test.c
new file mode 100644
index 0000000..451c7c2
--- /dev/null
+++ b/c11/c11_cndvar01/test.c
@@ -0,0 +1,141 @@
+/**
+ * @brief C11 Threads Example
+ */
+
+/*
+ * This file's license is 2-clause BSD as in this distribution's
+ * LICENSE.2 file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <threads.h>
+#include <assert.h>
+
+static thrd_t thread1;
+static mtx_t buffer_mutex;
+static cnd_t buffer_cnd;
+static int buffer_value;
+
+static int buffer_init(void)
+{
+ int rc;
+
+ puts("buffer - mtx_init()");
+ rc = mtx_init(&buffer_mutex, mtx_timed);
+ assert(rc == thrd_success);
+
+ puts("buffer - cnd_init()");
+ rc = cnd_init(&buffer_cnd);
+ assert(rc == thrd_success);
+
+ buffer_value = -1;
+}
+
+void buffer_destroy(void)
+{
+ puts("buffer - mtx_destroy()" );
+ mtx_destroy(&buffer_mutex);
+
+ puts("buffer - cnd_destroy()" );
+ cnd_destroy(&buffer_cnd);
+}
+
+static int buffer_get(void)
+{
+ int rc;
+ int value;
+
+ // puts("buffer - mtx_lock()");
+ rc = mtx_lock(&buffer_mutex);
+ assert(rc == thrd_success);
+
+ while (buffer_value == -1) {
+ // puts("buffer - cnd_wait()");
+ rc = cnd_wait(&buffer_cnd, &buffer_mutex);
+ assert(rc = thrd_success);
+ }
+
+ value = buffer_value;
+ buffer_value = -1;
+ // puts("buffer - return value");
+
+
+ // puts("buffer - mtx_unlock()");
+ rc = mtx_unlock(&buffer_mutex);
+ assert(rc == thrd_success);
+
+ return value;
+}
+
+static void buffer_put(int value)
+{
+ int rc;
+ int old_value;
+
+ // puts("buffer - mtx_lock()");
+ rc = mtx_lock(&buffer_mutex);
+ assert(rc == thrd_success);
+
+ old_value = buffer_value;
+ buffer_value = value;
+
+ if (old_value == -1) {
+ // puts("buffer - cnd_signal()");
+ rc = cnd_signal(&buffer_cnd);
+ assert(rc = thrd_success);
+ }
+
+ // puts("buffer - mtx_unlock()");
+ rc = mtx_unlock(&buffer_mutex);
+ assert(rc == thrd_success);
+
+}
+
+int Thread1_Body(void *arg)
+{
+ int rc;
+ int value;
+
+ (void) arg;
+
+ puts("Thread1 - Loop for values");
+ while (1) {
+ value = buffer_get();
+ printf("Thread1 value = %d\n", value);
+ }
+
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ int value;
+ struct timespec delay = {1, 0};
+
+ puts("*** START OF C11 CONDITION VARIABLE EXAMPLE ***");
+
+ puts("main - Create Thread1");
+ rc = thrd_create(&thread1, Thread1_Body, &thread1);
+ assert(rc == thrd_success);
+
+ buffer_init();
+
+ puts("main - yield to Thread1" );
+ thrd_yield();
+
+ for (value=1 ; value <= 3 ; value++) {
+ printf("main - put value = %d\n", value * 10);
+ buffer_put(value * 10);
+
+ puts("main - sleep to let Thread1 get the value");
+ rc = thrd_sleep(&delay, NULL);
+ assert(rc == 0);
+ }
+
+ buffer_destroy();
+
+ puts("*** END OF C11 CONDITION VARIABLE EXAMPLE ***");
+ return 0;
+}
diff --git a/c11/c11_cndvar01/wscript b/c11/c11_cndvar01/wscript
new file mode 100644
index 0000000..90e78a1
--- /dev/null
+++ b/c11/c11_cndvar01/wscript
@@ -0,0 +1,14 @@
+# Copyright 2017 Joel Sherrill (joel.sherrill@oarcorp.com)
+#
+# This file's license is 2-clause BSD as in this distribution's LICENSE.2 file.
+#
+
+# Waf build script for an RTEMS Hello
+import rtems_waf.rtems as rtems
+
+def build(bld):
+ rtems.build(bld)
+
+ bld(features = 'c cprogram',
+ target = 'c11_cndvar01.exe',
+ source = ['rtems_config.c', 'test.c'])
diff --git a/c11/c11_key01/Makefile b/c11/c11_key01/Makefile
new file mode 100644
index 0000000..db4d219
--- /dev/null
+++ b/c11/c11_key01/Makefile
@@ -0,0 +1,20 @@
+#
+# RTEMS_MAKEFILE_PATH is typically set in an environment variable
+#
+
+PGM=${ARCH}/c11_key01.exe
+
+# C source names
+CSRCS = rtems_config.c test.c
+COBJS = $(CSRCS:%.c=${ARCH}/%.o)
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)
+
+all: ${ARCH} $(PGM)
+
+$(PGM): $(OBJS)
+ $(make-exe)
diff --git a/c11/c11_key01/rtems_config.c b/c11/c11_key01/rtems_config.c
new file mode 100644
index 0000000..b8fd346
--- /dev/null
+++ b/c11/c11_key01/rtems_config.c
@@ -0,0 +1,53 @@
+/**
+ * @brief RTEMS Configuration for C11 Threads Example
+ */
+
+/*
+ * This file's license is 2-clause BSD as in this distribution's
+ * LICENSE.2 file.
+ */
+
+#include <stdlib.h>
+
+int main(int argc, char **argv);
+
+static char *argv_list[] = {
+ "c11-key01",
+ ""
+};
+
+static void *POSIX_Init(void *arg)
+{
+ int rc;
+
+ (void) arg; /* deliberately ignored */
+
+ /*
+ * Initialize optional services
+ */
+
+ /*
+ * Could get arguments from command line or have a static set.
+ */
+ rc = main(1, argv_list);
+
+ exit(rc);
+ return NULL;
+}
+
+#include <bsp.h> /* for device driver prototypes */
+
+/* NOTICE: the clock driver is explicitly disabled */
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+#define CONFIGURE_UNLIMITED_OBJECTS
+#define CONFIGURE_UNIFIED_WORK_AREAS
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (64 * 1024)
+
+#define CONFIGURE_INIT
+#include <rtems/confdefs.h>
diff --git a/c11/c11_key01/test.c b/c11/c11_key01/test.c
new file mode 100644
index 0000000..126d444
--- /dev/null
+++ b/c11/c11_key01/test.c
@@ -0,0 +1,123 @@
+/**
+ * @brief C11 Threads Example
+ */
+
+/*
+ * This file's license is 2-clause BSD as in this distribution's
+ * LICENSE.2 file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <threads.h>
+#include <assert.h>
+
+static thrd_t thread1;
+static thrd_t thread2;
+static tss_t tss1;
+
+typedef struct {
+ int thread_specific_value;
+} tss_data_t;
+
+void *tss_alloc(int value)
+{
+ void *p;
+ tss_data_t *k;
+
+ p = malloc(sizeof(tss_data_t));
+ k = (tss_data_t *)p;
+ k->thread_specific_value = value;
+ return p;
+}
+
+void tss_free(void *p)
+{
+ free(p);
+}
+
+int Thread1_Body(void *arg)
+{
+ thrd_t *t = (thrd_t *) arg;
+ int rc;
+ tss_data_t *td;
+
+ printf("Thread1(0x%08lx)\n", *t);
+ assert(thrd_current() == thread1);
+
+ puts("Thread1 - Assign TSS value for self");
+ rc = tss_set(tss1, tss_alloc(1));
+ assert(rc == thrd_success);
+
+ puts("Thread1 - yield" );
+ thrd_yield();
+
+ td = (tss_data_t *) tss_get(tss1);
+ printf("Thread1 - tss value = %d\n", td->thread_specific_value);
+
+ puts("Thread1 - exit" );
+ thrd_exit(0);
+ return 0;
+}
+
+int Thread2_Body(void *arg)
+{
+ thrd_t *t = (thrd_t *) arg;
+ int rc;
+ tss_data_t *td;
+
+ printf("Thread2(0x%08lx)\n", *t);
+ assert(thrd_current() == thread2);
+
+ puts("Thread2 - Assign TSS value for self");
+ rc = tss_set(tss1, tss_alloc(2));
+ assert(rc == thrd_success);
+
+ puts("Thread2 - yield" );
+ thrd_yield();
+
+ td = (tss_data_t *) tss_get(tss1);
+ printf("Thread2 - tss value = %d\n", td->thread_specific_value);
+
+ puts("Thread2 - exit" );
+ thrd_exit(128);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ struct timespec delay = {1, 0};
+ tss_data_t *td;
+
+ puts("*** START OF C11 KEY EXAMPLE ***");
+
+ puts("main - Create Thread1");
+ rc = thrd_create(&thread1, Thread1_Body, &thread1);
+ assert(rc == thrd_success);
+
+ puts("main - Create Thread2");
+ rc = thrd_create(&thread2, Thread2_Body, &thread2);
+ assert(rc == thrd_success);
+
+ puts("main - Create TSS instance");
+ rc = tss_create(&tss1, tss_free);
+ assert(rc == thrd_success);
+
+ puts("main - Assign TSS value for self");
+ rc = tss_set(tss1, tss_alloc(128));
+ assert(rc == thrd_success);
+
+ puts("main - sleep and let threads run");
+ rc = thrd_sleep(&delay, NULL);
+ assert(rc == 0);
+
+ td = (tss_data_t *) tss_get(tss1);
+ printf("main - tss value = %d\n", td->thread_specific_value);
+
+ puts("main - Delete TSS instance");
+ tss_delete(tss1);
+
+ puts("*** END OF C11 KEY EXAMPLE ***");
+ return 0;
+}
diff --git a/c11/c11_key01/wscript b/c11/c11_key01/wscript
new file mode 100644
index 0000000..1816774
--- /dev/null
+++ b/c11/c11_key01/wscript
@@ -0,0 +1,14 @@
+# Copyright 2017 Joel Sherrill (joel.sherrill@oarcorp.com)
+#
+# This file's license is 2-clause BSD as in this distribution's LICENSE.2 file.
+#
+
+# Waf build script for an RTEMS Hello
+import rtems_waf.rtems as rtems
+
+def build(bld):
+ rtems.build(bld)
+
+ bld(features = 'c cprogram',
+ target = 'c11_key01.exe',
+ source = ['rtems_config.c', 'test.c'])
diff --git a/c11/c11_mutex01/Makefile b/c11/c11_mutex01/Makefile
new file mode 100644
index 0000000..e6ca010
--- /dev/null
+++ b/c11/c11_mutex01/Makefile
@@ -0,0 +1,20 @@
+#
+# RTEMS_MAKEFILE_PATH is typically set in an environment variable
+#
+
+PGM=${ARCH}/c11_mutex01.exe
+
+# C source names
+CSRCS = rtems_config.c test.c
+COBJS = $(CSRCS:%.c=${ARCH}/%.o)
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)
+
+all: ${ARCH} $(PGM)
+
+$(PGM): $(OBJS)
+ $(make-exe)
diff --git a/c11/c11_mutex01/rtems_config.c b/c11/c11_mutex01/rtems_config.c
new file mode 100644
index 0000000..b72f679
--- /dev/null
+++ b/c11/c11_mutex01/rtems_config.c
@@ -0,0 +1,53 @@
+/**
+ * @brief RTEMS Configuration for C11 Mutex Example
+ */
+
+/*
+ * This file's license is 2-clause BSD as in this distribution's
+ * LICENSE.2 file.
+ */
+
+#include <stdlib.h>
+
+int main(int argc, char **argv);
+
+static char *argv_list[] = {
+ "c11-mutex01",
+ ""
+};
+
+static void *POSIX_Init(void *arg)
+{
+ int rc;
+
+ (void) arg; /* deliberately ignored */
+
+ /*
+ * Initialize optional services
+ */
+
+ /*
+ * Could get arguments from command line or have a static set.
+ */
+ rc = main(1, argv_list);
+
+ exit(rc);
+ return NULL;
+}
+
+#include <bsp.h> /* for device driver prototypes */
+
+/* NOTICE: the clock driver is explicitly disabled */
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+#define CONFIGURE_UNLIMITED_OBJECTS
+#define CONFIGURE_UNIFIED_WORK_AREAS
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (64 * 1024)
+
+#define CONFIGURE_INIT
+#include <rtems/confdefs.h>
diff --git a/c11/c11_mutex01/test.c b/c11/c11_mutex01/test.c
new file mode 100644
index 0000000..ab4622a
--- /dev/null
+++ b/c11/c11_mutex01/test.c
@@ -0,0 +1,85 @@
+/**
+ * @brief C11 Threads Example
+ */
+
+/*
+ * This file's license is 2-clause BSD as in this distribution's
+ * LICENSE.2 file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <threads.h>
+#include <assert.h>
+
+static thrd_t thread1;
+static mtx_t mutex1;
+
+int Thread1_Body(void *arg)
+{
+ int rc;
+ struct timespec delay;
+
+ (void) arg;
+
+ puts("Thread1 - mtx_trylock(mutex1) -> thrd_busy");
+ rc = mtx_trylock(&mutex1);
+ assert(rc == thrd_busy);
+
+ puts("Thread1 - mtx_timedlock(mutex1, 2 second) - thrd_timeout");
+ delay.tv_sec = time(NULL) + 1;
+ delay.tv_nsec = 0;
+ rc = mtx_timedlock(&mutex1, &delay);
+ assert(rc == thrd_timedout);
+
+ puts("Thread1 - mtx_lock(mutex1)");
+ rc = mtx_lock(&mutex1);
+ assert(rc == thrd_success);
+
+ puts("Thread1 - yield" );
+ thrd_yield();
+
+ puts("Thread1 - exit" );
+ thrd_exit(0);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ struct timespec delay = {5, 0};
+
+ puts("*** START OF C11 MUTEX EXAMPLE ***");
+
+ puts("main - Create Thread1");
+ rc = thrd_create(&thread1, Thread1_Body, &thread1);
+ assert(rc == thrd_success);
+
+ puts("main - mtx_init(mutex1)");
+ rc = mtx_init(&mutex1, mtx_timed);
+ assert(rc == thrd_success);
+
+ puts("main - mtx_lock(mutex1)");
+ rc = mtx_lock(&mutex1);
+ assert(rc == thrd_success);
+
+ puts("main - yield to Thread1" );
+ thrd_yield();
+
+ puts("main - sleep to let Thread2's delay complete while locked");
+ rc = thrd_sleep(&delay, NULL);
+ assert(rc == 0);
+
+ puts("main - mtx_unlock(mutex1)" );
+ rc = mtx_unlock(&mutex1);
+ assert(rc == thrd_success);
+
+ puts("main - yield to Thread1" );
+ thrd_yield();
+
+ puts("main - mtx_destroy(mutex1)" );
+ mtx_destroy(&mutex1);
+
+ puts("*** END OF C11 MUTEX EXAMPLE ***");
+ return 0;
+}
diff --git a/c11/c11_mutex01/wscript b/c11/c11_mutex01/wscript
new file mode 100644
index 0000000..661c754
--- /dev/null
+++ b/c11/c11_mutex01/wscript
@@ -0,0 +1,14 @@
+# Copyright 2017 Joel Sherrill (joel.sherrill@oarcorp.com)
+#
+# This file's license is 2-clause BSD as in this distribution's LICENSE.2 file.
+#
+
+# Waf build script for an RTEMS Hello
+import rtems_waf.rtems as rtems
+
+def build(bld):
+ rtems.build(bld)
+
+ bld(features = 'c cprogram',
+ target = 'c11_mutex01.exe',
+ source = ['rtems_config.c', 'test.c'])
diff --git a/c11/c11_thread01/Makefile b/c11/c11_thread01/Makefile
new file mode 100644
index 0000000..83900d0
--- /dev/null
+++ b/c11/c11_thread01/Makefile
@@ -0,0 +1,20 @@
+#
+# RTEMS_MAKEFILE_PATH is typically set in an environment variable
+#
+
+PGM=${ARCH}/c11_thread01.exe
+
+# C source names
+CSRCS = rtems_config.c test.c
+COBJS = $(CSRCS:%.c=${ARCH}/%.o)
+
+include $(RTEMS_MAKEFILE_PATH)/Makefile.inc
+include $(RTEMS_CUSTOM)
+include $(PROJECT_ROOT)/make/leaf.cfg
+
+OBJS= $(COBJS) $(CXXOBJS) $(ASOBJS)
+
+all: ${ARCH} $(PGM)
+
+$(PGM): $(OBJS)
+ $(make-exe)
diff --git a/c11/c11_thread01/rtems_config.c b/c11/c11_thread01/rtems_config.c
new file mode 100644
index 0000000..43c8e07
--- /dev/null
+++ b/c11/c11_thread01/rtems_config.c
@@ -0,0 +1,53 @@
+/**
+ * @brief RTEMS Configuration for C11 Threads Example
+ */
+
+/*
+ * This file's license is 2-clause BSD as in this distribution's
+ * LICENSE.2 file.
+ */
+
+#include <stdlib.h>
+
+int main(int argc, char **argv);
+
+static char *argv_list[] = {
+ "c11-thread01",
+ ""
+};
+
+static void *POSIX_Init(void *arg)
+{
+ int rc;
+
+ (void) arg; /* deliberately ignored */
+
+ /*
+ * Initialize optional services
+ */
+
+ /*
+ * Could get arguments from command line or have a static set.
+ */
+ rc = main(1, argv_list);
+
+ exit(rc);
+ return NULL;
+}
+
+#include <bsp.h> /* for device driver prototypes */
+
+/* NOTICE: the clock driver is explicitly disabled */
+#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
+#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
+
+#define CONFIGURE_POSIX_INIT_THREAD_TABLE
+
+#define CONFIGURE_UNLIMITED_OBJECTS
+#define CONFIGURE_UNIFIED_WORK_AREAS
+#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 32
+
+#define CONFIGURE_MINIMUM_TASK_STACK_SIZE (64 * 1024)
+
+#define CONFIGURE_INIT
+#include <rtems/confdefs.h>
diff --git a/c11/c11_thread01/test.c b/c11/c11_thread01/test.c
new file mode 100644
index 0000000..831bcc7
--- /dev/null
+++ b/c11/c11_thread01/test.c
@@ -0,0 +1,103 @@
+/**
+ * @brief C11 Threads Example
+ */
+
+/*
+ * This file's license is 2-clause BSD as in this distribution's
+ * LICENSE.2 file.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <threads.h>
+#include <assert.h>
+
+static thrd_t thread1;
+static thrd_t thread2;
+
+void initialize_subsystem_once(void)
+{
+ printf("*** Subsystem initialization should only happen once\n");
+}
+void initialize_subsystem(void)
+{
+ static once_flag initialize_subsystem_only_once= ONCE_FLAG_INIT;
+
+ call_once(&initialize_subsystem_only_once, initialize_subsystem_once);
+}
+int Thread1_Body(void *arg)
+{
+ thrd_t *t = (thrd_t *) arg;
+ int rc;
+ int result;
+
+ initialize_subsystem();
+
+ printf("Thread1(0x%08lx)\n", *t);
+ assert(thrd_current() == thread1);
+
+ puts("Thread1 - yield" );
+ thrd_yield();
+
+ puts("Thread1 - join Thread2" );
+ rc = thrd_join(thread2, &result);
+ assert(rc == thrd_success);
+ printf("Thread1 - thread1 exited with %d\n", result);
+
+ puts("Thread1 - exit" );
+ thrd_exit(0);
+ return 0;
+}
+
+int Thread2_Body(void *arg)
+{
+ thrd_t *t = (thrd_t *) arg;
+
+ initialize_subsystem();
+
+ printf("Thread2(0x%08lx)\n", *t);
+ assert(thrd_current() == thread2);
+
+ puts("Thread2 - exit" );
+ thrd_exit(128);
+ return 0;
+}
+
+int main(int argc, char **argv)
+{
+ int rc;
+ struct timespec delay = {1, 0};
+
+ puts("*** START OF C11 THREAD EXAMPLE ***");
+
+ initialize_subsystem();
+
+ puts("main - Create Thread1");
+ rc = thrd_create(&thread1, Thread1_Body, &thread1);
+ assert(rc == thrd_success);
+
+ puts("main - Detach Thread1");
+ rc = thrd_detach(thread1);
+ assert(rc == thrd_success);
+
+ puts("main - yield to Thread1" );
+ thrd_yield();
+
+ puts("main - Create Thread2");
+ rc = thrd_create(&thread2, Thread2_Body, &thread2);
+ assert(rc == thrd_success);
+
+ puts("Exercise thrd_equal");
+ rc = thrd_equal(thread1, thread2);
+ assert(rc == 0);
+
+ rc = thrd_equal(thread1, thread1);
+ assert(rc != 0);
+
+ puts("main - sleep and let Thread2 run");
+ rc = thrd_sleep(&delay, NULL);
+ assert(rc == 0);
+
+ puts("*** END OF C11 THREAD EXAMPLE ***");
+ return 0;
+}
diff --git a/c11/c11_thread01/wscript b/c11/c11_thread01/wscript
new file mode 100644
index 0000000..aa192af
--- /dev/null
+++ b/c11/c11_thread01/wscript
@@ -0,0 +1,14 @@
+# Copyright 2017 Joel Sherrill (joel.sherrill@oarcorp.com)
+#
+# This file's license is 2-clause BSD as in this distribution's LICENSE.2 file.
+#
+
+# Waf build script for an RTEMS Hello
+import rtems_waf.rtems as rtems
+
+def build(bld):
+ rtems.build(bld)
+
+ bld(features = 'c cprogram',
+ target = 'c11_thread01.exe',
+ source = ['rtems_config.c', 'test.c'])
diff --git a/c11/wscript b/c11/wscript
new file mode 100644
index 0000000..151c591
--- /dev/null
+++ b/c11/wscript
@@ -0,0 +1,13 @@
+# Copyright 2013 Gedare Bloom (gedare@rtems.org)
+#
+# This file's license is 2-clause BSD as in this distribution's LICENSE.2 file.
+#
+
+import rtems_waf.rtems as rtems
+
+def build(bld):
+ if rtems.check_posix(bld):
+ bld.recurse('c11_thread01 ')
+ bld.recurse('c11_mutex01 ')
+ bld.recurse('c11_cndvar01 ')
+ bld.recurse('c11_key01 ')
diff --git a/wscript b/wscript
index 9345d97..f3c8304 100644
--- a/wscript
+++ b/wscript
@@ -50,6 +50,7 @@ def build(bld):
bld.recurse('micromonitor')
bld.recurse('posix_api')
bld.recurse('cxx')
+ bld.recurse('c11')
def rebuild(ctx):
import waflib.Options