[examples-v2 commit] Add C11 Threading Examples

Joel Sherrill joel at rtems.org
Thu Oct 12 19:23:22 UTC 2017


Module:    examples-v2
Branch:    master
Commit:    45bf0f4be0f73506b8abe6d092ac6f5b84c3d9fc
Changeset: http://git.rtems.org/examples-v2/commit/?id=45bf0f4be0f73506b8abe6d092ac6f5b84c3d9fc

Author:    Joel Sherrill <joel at rtems.org>
Date:      Thu Oct  5 08:59:43 2017 -0500

Add C11 Threading Examples

---

 c11/c11_cndvar01/Makefile       |  20 ++++++
 c11/c11_cndvar01/rtems_config.c |  53 +++++++++++++++
 c11/c11_cndvar01/test.c         | 141 ++++++++++++++++++++++++++++++++++++++++
 c11/c11_cndvar01/wscript        |  14 ++++
 c11/c11_key01/Makefile          |  20 ++++++
 c11/c11_key01/rtems_config.c    |  53 +++++++++++++++
 c11/c11_key01/test.c            | 123 +++++++++++++++++++++++++++++++++++
 c11/c11_key01/wscript           |  14 ++++
 c11/c11_mutex01/Makefile        |  20 ++++++
 c11/c11_mutex01/rtems_config.c  |  53 +++++++++++++++
 c11/c11_mutex01/test.c          |  85 ++++++++++++++++++++++++
 c11/c11_mutex01/wscript         |  14 ++++
 c11/c11_thread01/Makefile       |  20 ++++++
 c11/c11_thread01/rtems_config.c |  53 +++++++++++++++
 c11/c11_thread01/test.c         | 103 +++++++++++++++++++++++++++++
 c11/c11_thread01/wscript        |  14 ++++
 c11/wscript                     |  13 ++++
 wscript                         |   1 +
 18 files changed, 814 insertions(+)

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 at 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 at 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 at 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 at 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 at 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




More information about the vc mailing list