summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorRobert Mustacchi <rm@joyent.com>2016-03-28 19:43:25 -0700
committerRobert Mustacchi <rm@joyent.com>2016-05-19 07:45:52 -0700
commitfc2512cfb727d49529d8ed99164db871f4829b73 (patch)
tree89ea56b5a9833e92795bf45c723c6de65b7490f2 /usr/src
parentea4a67f462de0a39a9adea8197bcdef849de5371 (diff)
downloadillumos-gate-fc2512cfb727d49529d8ed99164db871f4829b73.tar.gz
6951 Initial c11 support
6952 gets should not be visible in C11 6953 add support for c11 threads api 6954 Symbols test should support validating pre-processor symbols Reviewed by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net> Reviewed by: Dan McDonald <danmcd@omniti.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/mdb/common/modules/libc/libc.c11
-rw-r--r--usr/src/head/Makefile4
-rw-r--r--usr/src/head/assert.h8
-rw-r--r--usr/src/head/iso/stddef_iso.h9
-rw-r--r--usr/src/head/iso/stdio_iso.h7
-rw-r--r--usr/src/head/iso/stdlib_c11.h73
-rw-r--r--usr/src/head/iso/stdlib_c99.h12
-rw-r--r--usr/src/head/iso/stdlib_iso.h12
-rw-r--r--usr/src/head/stdalign.h42
-rw-r--r--usr/src/head/stdlib.h1
-rw-r--r--usr/src/head/stdnoreturn.h38
-rw-r--r--usr/src/head/threads.h104
-rw-r--r--usr/src/head/time.h17
-rw-r--r--usr/src/lib/libc/amd64/Makefile4
-rw-r--r--usr/src/lib/libc/i386/Makefile.com4
-rw-r--r--usr/src/lib/libc/inc/thr_uberdata.h26
-rw-r--r--usr/src/lib/libc/port/gen/atexit.c53
-rw-r--r--usr/src/lib/libc/port/gen/memalign.c15
-rw-r--r--usr/src/lib/libc/port/gen/timespec_get.c33
-rw-r--r--usr/src/lib/libc/port/mapfile-vers35
-rw-r--r--usr/src/lib/libc/port/threads/c11_thr.c293
-rw-r--r--usr/src/lib/libc/port/threads/thr.c7
-rw-r--r--usr/src/lib/libc/sparc/Makefile.com4
-rw-r--r--usr/src/lib/libc/sparcv9/Makefile.com2
-rw-r--r--usr/src/lib/libcmdutils/common/custr.c98
-rw-r--r--usr/src/lib/libcmdutils/common/mapfile-vers3
-rw-r--r--usr/src/lib/libcmdutils/libcmdutils.h17
-rw-r--r--usr/src/man/man3c/Makefile57
-rw-r--r--usr/src/man/man3c/aligned_alloc.3c74
-rw-r--r--usr/src/man/man3c/call_once.3c89
-rw-r--r--usr/src/man/man3c/cnd.3c183
-rw-r--r--usr/src/man/man3c/mtx.3c216
-rw-r--r--usr/src/man/man3c/nanosleep.3c57
-rw-r--r--usr/src/man/man3c/quick_exit.3c92
-rw-r--r--usr/src/man/man3c/thrd_create.3c90
-rw-r--r--usr/src/man/man3c/thrd_current.3c46
-rw-r--r--usr/src/man/man3c/thrd_detach.3c56
-rw-r--r--usr/src/man/man3c/thrd_equal.3c56
-rw-r--r--usr/src/man/man3c/thrd_exit.3c64
-rw-r--r--usr/src/man/man3c/thrd_join.3c81
-rw-r--r--usr/src/man/man3c/thrd_yield.3c38
-rw-r--r--usr/src/man/man3c/timespec_get.3c81
-rw-r--r--usr/src/man/man3c/tss.3c151
-rw-r--r--usr/src/man/man3head/assert.h.3head12
-rw-r--r--usr/src/man/man3head/stddef.h.3head18
-rw-r--r--usr/src/man/man3head/time.h.3head24
-rw-r--r--usr/src/man/man5/standards.516
-rw-r--r--usr/src/man/man5/threads.5434
-rw-r--r--usr/src/pkg/manifests/system-header.mf4
-rw-r--r--usr/src/pkg/manifests/system-library.man3c.inc32
-rw-r--r--usr/src/pkg/manifests/system-test-libctest.mf27
-rw-r--r--usr/src/test/libc-tests/cfg/Makefile6
-rw-r--r--usr/src/test/libc-tests/cfg/compilation.cfg6
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/README13
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/assert_h.cfg23
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/stdalign_h.cfg26
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/stddef_h.cfg31
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg6
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg19
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/stdnoreturn_h.cfg23
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/threads_h.cfg176
-rw-r--r--usr/src/test/libc-tests/cfg/symbols/time_h.cfg40
-rw-r--r--usr/src/test/libc-tests/runfiles/default.run17
-rw-r--r--usr/src/test/libc-tests/tests/Makefile70
-rw-r--r--usr/src/test/libc-tests/tests/aligned_alloc.c77
-rw-r--r--usr/src/test/libc-tests/tests/c11_threads.c385
-rw-r--r--usr/src/test/libc-tests/tests/c11_tss.c87
-rw-r--r--usr/src/test/libc-tests/tests/call_once.c78
-rw-r--r--usr/src/test/libc-tests/tests/common/test_common.c2
-rw-r--r--usr/src/test/libc-tests/tests/quick_exit.ksh67
-rw-r--r--usr/src/test/libc-tests/tests/quick_exit_order.c80
-rw-r--r--usr/src/test/libc-tests/tests/quick_exit_status.c33
-rw-r--r--usr/src/test/libc-tests/tests/symbols/Makefile15
-rw-r--r--usr/src/test/libc-tests/tests/symbols/symbols_test.c145
-rw-r--r--usr/src/test/libc-tests/tests/timespec_get.c59
-rw-r--r--usr/src/uts/common/sys/feature_tests.h35
-rw-r--r--usr/src/uts/common/sys/isa_defs.h8
-rw-r--r--usr/src/uts/common/sys/time_impl.h2
78 files changed, 4124 insertions, 335 deletions
diff --git a/usr/src/cmd/mdb/common/modules/libc/libc.c b/usr/src/cmd/mdb/common/modules/libc/libc.c
index 967198e40b..a10e7f5ef8 100644
--- a/usr/src/cmd/mdb/common/modules/libc/libc.c
+++ b/usr/src/cmd/mdb/common/modules/libc/libc.c
@@ -22,9 +22,7 @@
/*
* Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2012 by Delphix. All rights reserved.
- */
-/*
- * Copyright (c) 2015, Joyent, Inc.
+ * Copyright 2016, Joyent, Inc.
*/
#include <sys/mdb_modapi.h>
@@ -794,6 +792,13 @@ d_uberdata(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
prt_addr(uberdata.atexit_root.head, 1),
prt_addr(uberdata.atexit_root.exit_frame_monitor, 0));
+ HD("&quickexit_root head");
+ mdb_printf(OFFSTR "%s %s\n",
+ OFFSET(quickexit_root),
+ prt_addr((void *)(addr + OFFSET(quickexit_root.exitfns_lock)), 1),
+ prt_addr(uberdata.quickexit_root.head, 0));
+
+
HD("&tsd_metadata tsdm_nkeys tsdm_nused tsdm_destro");
mdb_printf(OFFSTR "%s %-10d %-10d %s\n",
OFFSET(tsd_metadata),
diff --git a/usr/src/head/Makefile b/usr/src/head/Makefile
index 61e63fed38..7b83f1ee75 100644
--- a/usr/src/head/Makefile
+++ b/usr/src/head/Makefile
@@ -169,6 +169,7 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) \
siginfo.h \
signal.h \
spawn.h \
+ stdalign.h \
stdarg.h \
stdbool.h \
stddef.h \
@@ -178,6 +179,7 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) \
stdio_tag.h \
stdio_impl.h \
stdlib.h \
+ stdnoreturn.h \
storclass.h \
string.h \
strings.h \
@@ -192,6 +194,7 @@ HDRS= $($(MACH)_HDRS) $(ATTRDB_HDRS) \
tgmath.h \
thread.h \
thread_db.h \
+ threads.h \
time.h \
tiuser.h \
tzfile.h \
@@ -232,6 +235,7 @@ ISOHDRS = \
stdio_c99.h \
stdio_iso.h \
stdlib_c99.h \
+ stdlib_c11.h \
stdlib_iso.h \
string_iso.h \
time_iso.h \
diff --git a/usr/src/head/assert.h b/usr/src/head/assert.h
index 4a8d36a282..d29450416c 100644
--- a/usr/src/head/assert.h
+++ b/usr/src/head/assert.h
@@ -24,6 +24,7 @@
/*
* Copyright 2014 Garrett D'Amore <garrett@damore.org>
+ * Copyright 2016 Joyent, Inc.
*
* Copyright 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -42,6 +43,13 @@ extern void __assert_c99(const char *, const char *, int, const char *);
extern void __assert(const char *, const char *, int);
#endif /* __STDC_VERSION__ - 0 >= 199901L */
+/*
+ * In C11 the static_assert macro is always defined, unlike the assert macro.
+ */
+#if __STDC_VERSION__ - 0 >= 201112L
+#define static_assert _Static_assert
+#endif /* __STDC_VERSION - 0 >= 201112L */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/head/iso/stddef_iso.h b/usr/src/head/iso/stddef_iso.h
index c0034576b9..b94960793c 100644
--- a/usr/src/head/iso/stddef_iso.h
+++ b/usr/src/head/iso/stddef_iso.h
@@ -30,6 +30,7 @@
/*
* Copyright 2014 PALO, Richard.
+ * Copyright 2016 Joyent, Inc.
*/
/*
@@ -48,6 +49,7 @@
#define _ISO_STDDEF_ISO_H
#include <sys/isa_defs.h>
+#include <sys/feature_tests.h>
#include <sys/null.h>
#ifdef __cplusplus
@@ -90,6 +92,13 @@ typedef unsigned int size_t; /* (historical version) */
#endif
#endif /* GNUC, etc. */
+#if !defined(_MAX_ALIGN_T)
+#if !defined(_STRICT_SYMBOLS) || defined(_STDC_C11)
+#define _MAX_ALIGN_T
+typedef _MAX_ALIGNMENT_TYPE max_align_t;
+#endif /* !_STRICT_SYMBOLS || _STDC_C11 */
+#endif /* _MAX_ALIGN_T */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/head/iso/stdio_iso.h b/usr/src/head/iso/stdio_iso.h
index d09c982a9c..cea7b1ff6d 100644
--- a/usr/src/head/iso/stdio_iso.h
+++ b/usr/src/head/iso/stdio_iso.h
@@ -232,7 +232,14 @@ extern int putc(int, FILE *);
extern int getchar(void);
extern int putchar(int);
#endif
+
+/*
+ * ISO/IEC C11 removed gets from the standard library. Therefore if a strict C11
+ * environment has been requested, we remove it.
+ */
+#if !defined(_STDC_C11) || defined(__EXTENSIONS__)
extern char *gets(char *);
+#endif
extern int puts(const char *);
extern int ungetc(int, FILE *);
extern size_t fread(void *_RESTRICT_KYWD, size_t, size_t,
diff --git a/usr/src/head/iso/stdlib_c11.h b/usr/src/head/iso/stdlib_c11.h
new file mode 100644
index 0000000000..69334f5985
--- /dev/null
+++ b/usr/src/head/iso/stdlib_c11.h
@@ -0,0 +1,73 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+/*
+ * An application should not include this header directly. Instead it
+ * should be included only through the inclusion of other illumos headers.
+ *
+ * The contents of this header is limited to identifiers specified in
+ * the C11 standard and in conflict with the C++ implementation of the
+ * standard header. The C++ standard may adopt the C11 standard at
+ * which point it is expected that the symbols included here will
+ * become part of the C++ std namespace.
+ */
+
+#ifndef _ISO_STDLIB_C11_H
+#define _ISO_STDLIB_C11_H
+
+#include <sys/feature_tests.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if __cplusplus >= 199711L
+namespace std {
+#endif
+
+/*
+ * The following have been added as a result of the ISO/IEC 9899:2011
+ * standard. For a strictly conforming C application, visibility is
+ * contingent on the value of __STDC_VERSION__ (see sys/feature_tests.h).
+ * For non-strictly conforming C applications, there are no restrictions
+ * on the C namespace.
+ */
+
+/*
+ * Work around fix-includes and other bad actors with using multiple headers.
+ */
+#if !defined(_NORETURN_KYWD)
+#if __STDC_VERSION__ - 0 >= 201112L
+#define _NORETURN_KYWD _Noreturn
+#else
+#define _NORETURN_KYWD
+#endif /* __STDC_VERSION__ - 0 >= 201112L */
+#endif /* !defined(_NORETURN_KYWD) */
+
+#if !defined(_STRICT_SYMBOLS) || defined(_STDC_C11)
+extern void *aligned_alloc(size_t, size_t);
+extern int at_quick_exit(void (*)(void));
+extern _NORETURN_KYWD void quick_exit(int);
+#endif /* !_STRICT_SYMBOLS || _STDC_C11 */
+
+#if __cplusplus >= 199711L
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ISO_STDLIB_C11_H */
diff --git a/usr/src/head/iso/stdlib_c99.h b/usr/src/head/iso/stdlib_c99.h
index 29aafa3ec0..59f2600292 100644
--- a/usr/src/head/iso/stdlib_c99.h
+++ b/usr/src/head/iso/stdlib_c99.h
@@ -40,6 +40,8 @@
#ifndef _ISO_STDLIB_C99_H
#define _ISO_STDLIB_C99_H
+#include <sys/feature_tests.h>
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -62,7 +64,15 @@ typedef struct {
#if (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
defined(_STDC_C99) || defined(__EXTENSIONS__)
-extern void _Exit(int);
+#if !defined(_NORETURN_KYWD)
+#if __STDC_VERSION__ - 0 >= 201112L
+#define _NORETURN_KYWD _Noreturn
+#else
+#define _NORETURN_KYWD
+#endif /* __STDC_VERSION__ - 0 >= 201112L */
+#endif /* !defined(_NORETURN_KYWD) */
+
+extern _NORETURN_KYWD void _Exit(int);
extern float strtof(const char *_RESTRICT_KYWD, char **_RESTRICT_KYWD);
extern long double strtold(const char *_RESTRICT_KYWD, char **_RESTRICT_KYWD);
diff --git a/usr/src/head/iso/stdlib_iso.h b/usr/src/head/iso/stdlib_iso.h
index 2caa289e35..90af2ded91 100644
--- a/usr/src/head/iso/stdlib_iso.h
+++ b/usr/src/head/iso/stdlib_iso.h
@@ -109,7 +109,15 @@ typedef long wchar_t;
#endif /* !_WCHAR_T */
#endif /* !defined(__cplusplus) ... */
-extern void abort(void) __NORETURN;
+#if !defined(_NORETURN_KYWD)
+#if __STDC_VERSION__ - 0 >= 201112L
+#define _NORETURN_KYWD _Noreturn
+#else
+#define _NORETURN_KYWD
+#endif /* __STDC_VERSION__ - 0 >= 201112L */
+#endif /* !defined(_NORETURN_KYWD) */
+
+extern _NORETURN_KYWD void abort(void) __NORETURN;
extern int abs(int);
extern int atexit(void (*)(void));
extern double atof(const char *);
@@ -125,7 +133,7 @@ extern "C++" {
#endif /* __cplusplus >= 199711L && defined(__SUNPRO_CC) */
extern void *calloc(size_t, size_t);
extern div_t div(int, int);
-extern void exit(int)
+extern _NORETURN_KYWD void exit(int)
__NORETURN;
extern void free(void *);
extern char *getenv(const char *);
diff --git a/usr/src/head/stdalign.h b/usr/src/head/stdalign.h
new file mode 100644
index 0000000000..2577a8de92
--- /dev/null
+++ b/usr/src/head/stdalign.h
@@ -0,0 +1,42 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+#ifndef _STDALIGN_H
+#define _STDALIGN_H
+
+/*
+ * ISO/IEC C11 stdalign.h
+ */
+#include <sys/feature_tests.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_STRICT_SYMBOLS) || defined(_STDC_C11)
+
+#define alignas _Alignas
+#define alignof _Alignof
+
+#define __alignas_is_defined 1
+#define __alignof_is_defined 1
+
+#endif /* !_STRICT_SYMBOLS || _STDC_C11 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STDALIGN_H */
diff --git a/usr/src/head/stdlib.h b/usr/src/head/stdlib.h
index 4387c566c5..94eaab38fa 100644
--- a/usr/src/head/stdlib.h
+++ b/usr/src/head/stdlib.h
@@ -36,6 +36,7 @@
#include <iso/stdlib_iso.h>
#include <iso/stdlib_c99.h>
+#include <iso/stdlib_c11.h>
#if defined(__EXTENSIONS__) || defined(_XPG4)
#include <sys/wait.h>
diff --git a/usr/src/head/stdnoreturn.h b/usr/src/head/stdnoreturn.h
new file mode 100644
index 0000000000..429cb0f079
--- /dev/null
+++ b/usr/src/head/stdnoreturn.h
@@ -0,0 +1,38 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+#ifndef _STDNORETURN_H
+#define _STDNORETURN_H
+
+/*
+ * ISO/IEC C11 stdnoreturn.h
+ */
+#include <sys/feature_tests.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_STRICT_SYMBOLS) || defined(_STDC_C11)
+
+#define noreturn _Noreturn
+
+#endif /* !_STRICT_SYMBOLS || _STDC_C11 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _STDNORETURN_H */
diff --git a/usr/src/head/threads.h b/usr/src/head/threads.h
new file mode 100644
index 0000000000..86e0164f84
--- /dev/null
+++ b/usr/src/head/threads.h
@@ -0,0 +1,104 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+#ifndef _THREADS_H
+#define _THREADS_H
+
+/*
+ * ISO/IEC C11 threads.h support
+ */
+
+#include <sys/feature_tests.h>
+
+#include <sys/types.h>
+#include <limits.h>
+#include <time.h>
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_STRICT_SYMBOLS) || defined(_STDC_C11)
+
+#if !defined(_NORETURN_KYWD)
+#if __STDC_VERSION__ - 0 >= 201112L
+#define _NORETURN_KYWD _Noreturn
+#else
+#define _NORETURN_KYWD
+#endif /* __STDC_VERSION__ - 0 >= 201112L */
+#endif /* !defined(_NORETURN_KYWD) */
+
+#define thread_local _Thread_local
+#define ONCE_FLAG_INIT PTHREAD_ONCE_INIT
+#define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS
+
+typedef pthread_cond_t cnd_t;
+typedef pthread_t thrd_t;
+typedef pthread_key_t tss_t;
+typedef pthread_mutex_t mtx_t;
+typedef void (*tss_dtor_t)(void *);
+typedef int (*thrd_start_t)(void *);
+typedef pthread_once_t once_flag;
+
+enum {
+ mtx_plain = 0x1,
+ mtx_recursive = 0x2,
+ mtx_timed = 0x4
+};
+
+enum {
+ thrd_success = 0,
+ thrd_error = 1,
+ thrd_busy = 2,
+ thrd_timedout = 3,
+ thrd_nomem = 4
+};
+
+extern void call_once(once_flag *, void (*)(void));
+extern int cnd_broadcast(cnd_t *);
+extern void cnd_destroy(cnd_t *);
+extern int cnd_init(cnd_t *);
+extern int cnd_signal(cnd_t *);
+extern int cnd_timedwait(cnd_t *_RESTRICT_KYWD, mtx_t *_RESTRICT_KYWD,
+ const struct timespec *_RESTRICT_KYWD);
+extern int cnd_wait(cnd_t *, mtx_t *);
+extern void mtx_destroy(mtx_t *);
+extern int mtx_init(mtx_t *, int);
+extern int mtx_lock(mtx_t *);
+extern int mtx_timedlock(mtx_t *_RESTRICT_KYWD,
+ const struct timespec *_RESTRICT_KYWD);
+extern int mtx_trylock(mtx_t *);
+extern int mtx_unlock(mtx_t *);
+extern int thrd_create(thrd_t *, thrd_start_t, void *);
+extern thrd_t thrd_current(void);
+extern int thrd_detach(thrd_t);
+extern int thrd_equal(thrd_t, thrd_t);
+extern _NORETURN_KYWD void thrd_exit(int) __NORETURN;
+extern int thrd_join(thrd_t, int *);
+extern int thrd_sleep(const struct timespec *, struct timespec *);
+extern void thrd_yield(void);
+extern int tss_create(tss_t *, tss_dtor_t);
+extern void tss_delete(tss_t);
+extern void *tss_get(tss_t);
+extern int tss_set(tss_t, void *);
+
+#endif /* !_STRICT_SYMBOLS | _STDC_C11 */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _THREADS_H */
diff --git a/usr/src/head/time.h b/usr/src/head/time.h
index c61115f36f..bf27e0f0ce 100644
--- a/usr/src/head/time.h
+++ b/usr/src/head/time.h
@@ -30,6 +30,7 @@
*/
/*
* Copyright 2010 Nexenta Systems, Inc. Al rights reserved.
+ * Copyright 2016 Joyent, Inc.
*/
#ifndef _TIME_H
@@ -37,8 +38,11 @@
#include <sys/feature_tests.h>
#include <iso/time_iso.h>
+/*
+ * C11 requires sys/time_impl.h for the definition of the struct timespec.
+ */
#if (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) || \
- (_POSIX_C_SOURCE > 2) || defined(__EXTENSIONS__)
+ (_POSIX_C_SOURCE > 2) || defined(__EXTENSIONS__) || defined(_STDC_C11)
#include <sys/types.h>
#include <sys/time_impl.h>
#endif /* (!defined(_STRICT_STDC) && !defined(__XOPEN_OR_POSIX)) ... */
@@ -293,6 +297,17 @@ extern size_t strftime_l(char *_RESTRICT_KYWD, size_t,
#endif /* defined(_XPG7) || !defined(_STRICT_SYMBOLS) */
+#if !defined(_STRICT_SYMBOLS) || defined(_STDC_C11)
+
+/*
+ * Note, the C11 standard requires that all the various base values that are
+ * passed into timespec_get() be non-zero. Hence why TIME_UTC starts at one.
+ */
+#define TIME_UTC 0x1 /* timespec_get base */
+
+extern int timespec_get(struct timespec *, int);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/libc/amd64/Makefile b/usr/src/lib/libc/amd64/Makefile
index 9da581df4e..0a55bf964f 100644
--- a/usr/src/lib/libc/amd64/Makefile
+++ b/usr/src/lib/libc/amd64/Makefile
@@ -20,7 +20,7 @@
#
#
# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright (c) 2015, Joyent, Inc. All rights reserved.
+# Copyright 2016 Joyent, Inc.
#
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2013 Garrett D'Amore <garrett@damore.org>
@@ -565,6 +565,7 @@ PORTGEN= \
tfind.o \
time_data.o \
time_gdata.o \
+ timespec_get.o \
tls_data.o \
truncate.o \
tsdalloc.o \
@@ -810,6 +811,7 @@ TPOOLOBJS= \
THREADSOBJS= \
alloc.o \
assfail.o \
+ c11_thr.o \
cancel.o \
door_calls.o \
tmem.o \
diff --git a/usr/src/lib/libc/i386/Makefile.com b/usr/src/lib/libc/i386/Makefile.com
index 62e6fe5d5e..21adf0d5a1 100644
--- a/usr/src/lib/libc/i386/Makefile.com
+++ b/usr/src/lib/libc/i386/Makefile.com
@@ -20,7 +20,7 @@
#
#
# Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright (c) 2015, Joyent, Inc. All rights reserved.
+# Copyright 2016 Joyent, Inc.
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2013 Garrett D'Amore <garrett@damore.org>
#
@@ -595,6 +595,7 @@ PORTGEN= \
tfind.o \
time_data.o \
time_gdata.o \
+ timespec_get.o \
tls_data.o \
truncate.o \
tsdalloc.o \
@@ -855,6 +856,7 @@ THREADSOBJS= \
alloc.o \
assfail.o \
cancel.o \
+ c11_thr.o \
door_calls.o \
tmem.o \
pthr_attr.o \
diff --git a/usr/src/lib/libc/inc/thr_uberdata.h b/usr/src/lib/libc/inc/thr_uberdata.h
index 4815d11486..0cf92cf499 100644
--- a/usr/src/lib/libc/inc/thr_uberdata.h
+++ b/usr/src/lib/libc/inc/thr_uberdata.h
@@ -23,7 +23,7 @@
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright (c) 2015, Joyent, Inc.
+ * Copyright 2016 Joyent, Inc.
*/
#ifndef _THR_UBERDATA_H
@@ -893,6 +893,28 @@ typedef struct {
} atexit_root32_t;
#endif /* _SYSCALL32 */
+/*
+ * at_quick_exit() and quick_exit() data structures. The ISO/IEC C11 odd
+ * siblings of atexit()
+ */
+typedef void (*_quick_exithdlr_func_t)(void);
+
+typedef struct _qexthdlr {
+ struct _qexthdlr *next; /* next in handler list */
+ _quick_exithdlr_func_t hdlr; /* handler itself */
+} _qexthdlr_t;
+
+typedef struct {
+ mutex_t exitfns_lock;
+ _qexthdlr_t *head;
+} quickexit_root_t;
+
+#ifdef _SYSCALL32
+typedef struct {
+ mutex_t exitfns_lock;
+ caddr32_t head;
+} quickexit_root32_t;
+#endif /* _SYSCALL32 */
/*
* This is data that is global to all link maps (uberdata, aka super-global).
@@ -910,6 +932,7 @@ typedef struct uberdata {
siguaction_t siguaction[NSIG];
bucket_t bucket[NBUCKETS];
atexit_root_t atexit_root;
+ quickexit_root_t quickexit_root;
tsd_metadata_t tsd_metadata;
tls_metadata_t tls_metadata;
/*
@@ -1126,6 +1149,7 @@ typedef struct uberdata32 {
siguaction32_t siguaction[NSIG];
bucket32_t bucket[NBUCKETS];
atexit_root32_t atexit_root;
+ quickexit_root32_t quickexit_root;
tsd_metadata32_t tsd_metadata;
tls_metadata32_t tls_metadata;
char primary_map;
diff --git a/usr/src/lib/libc/port/gen/atexit.c b/usr/src/lib/libc/port/gen/atexit.c
index 32e54fae11..e2882afdd4 100644
--- a/usr/src/lib/libc/port/gen/atexit.c
+++ b/usr/src/lib/libc/port/gen/atexit.c
@@ -22,6 +22,8 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2016 Joyent, Inc.
*/
/* Copyright (c) 1988 AT&T */
@@ -80,11 +82,13 @@ void
atexit_locks()
{
(void) mutex_lock(&__uberdata.atexit_root.exitfns_lock);
+ (void) mutex_lock(&__uberdata.quickexit_root.exitfns_lock);
}
void
atexit_unlocks()
{
+ (void) mutex_unlock(&__uberdata.quickexit_root.exitfns_lock);
(void) mutex_unlock(&__uberdata.atexit_root.exitfns_lock);
}
@@ -382,3 +386,52 @@ in_range(void *addr, Lc_addr_range_t ranges[], uint_t count)
return (0);
}
+
+int
+at_quick_exit(void (*func)(void))
+{
+ ulwp_t *self;
+ quickexit_root_t *arp;
+ _qexthdlr_t *p;
+
+ if ((p = lmalloc(sizeof (_qexthdlr_t))) == NULL)
+ return (-1);
+
+ if ((self = __curthread()) == NULL) {
+ arp = &__uberdata.quickexit_root;
+ } else {
+ arp = &self->ul_uberdata->quickexit_root;
+ (void) mutex_lock(&arp->exitfns_lock);
+ }
+ p->hdlr = func;
+ p->next = arp->head;
+ arp->head = p;
+
+ if (self != NULL)
+ (void) mutex_unlock(&arp->exitfns_lock);
+ return (0);
+
+}
+
+void
+quick_exit(int status)
+{
+ quickexit_root_t *qrp = &curthread->ul_uberdata->quickexit_root;
+ _qexthdlr_t *p;
+ int cancel_state;
+
+ (void) pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cancel_state);
+ (void) mutex_lock(&qrp->exitfns_lock);
+
+ p = qrp->head;
+ while (p != NULL) {
+ qrp->head = p->next;
+ p->hdlr();
+ lfree(p, sizeof (_qexthdlr_t));
+ p = qrp->head;
+ }
+
+ (void) mutex_unlock(&qrp->exitfns_lock);
+ (void) pthread_setcancelstate(cancel_state, NULL);
+ _Exit(status);
+}
diff --git a/usr/src/lib/libc/port/gen/memalign.c b/usr/src/lib/libc/port/gen/memalign.c
index a54a10868f..a6320a7a0b 100644
--- a/usr/src/lib/libc/port/gen/memalign.c
+++ b/usr/src/lib/libc/port/gen/memalign.c
@@ -22,13 +22,12 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2016 Joyent, Inc.
*/
/* Copyright (c) 1988 AT&T */
/* All Rights Reserved */
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "lint.h"
#include "mallint.h"
#include "mtlib.h"
@@ -183,3 +182,15 @@ memalign(size_t align, size_t nbytes)
(void) mutex_unlock(&libc_malloc_lock);
return (DATA(aligned_blk));
}
+
+/*
+ * This is the ISO/IEC C11 version of memalign. We have kept it as a separate
+ * function, but it is basically the same thing. Note that this is implemented
+ * this way to make life easier to libraries which already interpose on
+ * memalign.
+ */
+void *
+aligned_alloc(size_t align, size_t size)
+{
+ return (memalign(align, size));
+}
diff --git a/usr/src/lib/libc/port/gen/timespec_get.c b/usr/src/lib/libc/port/gen/timespec_get.c
new file mode 100644
index 0000000000..e16f6acf28
--- /dev/null
+++ b/usr/src/lib/libc/port/gen/timespec_get.c
@@ -0,0 +1,33 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright (c) 2015 Joyent, Inc.
+ */
+
+/*
+ * C11 timespec_get(3C). Note the standard does not want us mucking about with
+ * errno, but at least we don't have to preserve it.
+ */
+
+#include <time.h>
+
+int
+timespec_get(struct timespec *ts, int base)
+{
+ if (base != TIME_UTC)
+ return (0);
+
+ if (clock_gettime(CLOCK_REALTIME, ts) != 0)
+ return (0);
+
+ return (TIME_UTC);
+}
diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers
index 2e51bc8f54..fa9931c23b 100644
--- a/usr/src/lib/libc/port/mapfile-vers
+++ b/usr/src/lib/libc/port/mapfile-vers
@@ -25,7 +25,7 @@
# Use is subject to license terms.
#
# Copyright (c) 2012 by Delphix. All rights reserved.
-# Copyright (c) 2015, Joyent, Inc. All rights reserved.
+# Copyright 2016 Joyent, Inc.
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright (c) 2013 Gary Mills
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
@@ -93,6 +93,39 @@ $if _x86 && _ELF64
$add amd64
$endif
+SYMBOL_VERSION ILLUMOS_0.20 { # C11
+ protected:
+ aligned_alloc;
+ at_quick_exit;
+ call_once;
+ cnd_broadcast;
+ cnd_destroy;
+ cnd_init;
+ cnd_signal;
+ cnd_timedwait;
+ cnd_wait;
+ mtx_destroy;
+ mtx_init;
+ mtx_lock;
+ mtx_timedlock;
+ mtx_trylock;
+ mtx_unlock;
+ quick_exit;
+ thrd_create;
+ thrd_current;
+ thrd_detach;
+ thrd_equal;
+ thrd_exit;
+ thrd_join;
+ thrd_sleep;
+ thrd_yield;
+ timespec_get;
+ tss_create;
+ tss_delete;
+ tss_get;
+ tss_set;
+} ILLUMOS_0.19;
+
SYMBOL_VERSION ILLUMOS_0.19 { # flock
protected:
flock;
diff --git a/usr/src/lib/libc/port/threads/c11_thr.c b/usr/src/lib/libc/port/threads/c11_thr.c
new file mode 100644
index 0000000000..6a8c6d157e
--- /dev/null
+++ b/usr/src/lib/libc/port/threads/c11_thr.c
@@ -0,0 +1,293 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+#include <pthread.h>
+#include <thread.h>
+#include <synch.h>
+#include <threads.h>
+#include <errno.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+/*
+ * ISO/IEC C11 thread support.
+ *
+ * In illumos, the underlying implementation of lock related routines is the
+ * same between pthreads and traditional SunOS routines. The same is true with
+ * the C11 routines. Their types are actually just typedef's to other things.
+ * Thus in the implementation here, we treat this as a wrapper around existing
+ * thread related routines and don't sweet the extra indirection.
+ *
+ * Note that in many places the C standard doesn't allow for errors to be
+ * returned. In those cases, if we have an instance of programmer error
+ * (something resulting in EINVAL), we opt to abort the program as we don't have
+ * much other recourse available.
+ */
+
+void
+call_once(once_flag *flag, void (*func)(void))
+{
+ if (pthread_once(flag, func) != 0)
+ abort();
+}
+
+int
+cnd_broadcast(cnd_t *cnd)
+{
+ int ret;
+
+ ret = pthread_cond_broadcast(cnd);
+ if (ret == 0)
+ return (thrd_success);
+ else
+ return (thrd_error);
+}
+
+void
+cnd_destroy(cnd_t *cnd)
+{
+ if (pthread_cond_destroy(cnd) != 0)
+ abort();
+}
+
+int
+cnd_init(cnd_t *cnd)
+{
+ int ret;
+
+ ret = pthread_cond_init(cnd, NULL);
+ if (ret == 0)
+ return (thrd_success);
+ return (thrd_error);
+}
+
+int
+cnd_signal(cnd_t *cnd)
+{
+ int ret;
+
+ ret = pthread_cond_signal(cnd);
+ if (ret == 0)
+ return (thrd_success);
+ else
+ return (thrd_error);
+}
+
+/* ARGSUSED */
+int
+cnd_timedwait(cnd_t *_RESTRICT_KYWD cnd, mtx_t *_RESTRICT_KYWD mtx,
+ const struct timespec *_RESTRICT_KYWD ts)
+{
+ int ret;
+
+ ret = pthread_cond_timedwait(cnd, mtx, ts);
+ if (ret == 0)
+ return (thrd_success);
+ if (ret == ETIMEDOUT)
+ return (thrd_timedout);
+ return (thrd_error);
+}
+
+/* ARGSUSED */
+int
+cnd_wait(cnd_t *cnd, mtx_t *mtx)
+{
+ int ret;
+
+ ret = pthread_cond_wait(cnd, mtx);
+ if (ret == 0)
+ return (thrd_success);
+ return (thrd_error);
+}
+
+void
+mtx_destroy(mtx_t *mtx)
+{
+ if (pthread_mutex_destroy(mtx) != 0)
+ abort();
+}
+
+int
+mtx_init(mtx_t *mtx, int type)
+{
+ int mtype;
+
+ switch (type) {
+ case mtx_plain:
+ case mtx_timed:
+ mtype = USYNC_THREAD;
+ break;
+ case mtx_plain | mtx_recursive:
+ case mtx_timed | mtx_recursive:
+ mtype = USYNC_THREAD | LOCK_RECURSIVE;
+ break;
+ default:
+ return (thrd_error);
+ }
+
+ /*
+ * Here, we buck the trend and use the traditional SunOS routine. It's
+ * much simpler than fighting with pthread attributes.
+ */
+ if (mutex_init((mutex_t *)mtx, mtype, NULL) == 0)
+ return (thrd_success);
+ return (thrd_error);
+}
+
+int
+mtx_lock(mtx_t *mtx)
+{
+ if (pthread_mutex_lock(mtx) == 0)
+ return (thrd_success);
+ return (thrd_error);
+}
+
+int
+mtx_timedlock(mtx_t *_RESTRICT_KYWD mtx,
+ const struct timespec *_RESTRICT_KYWD abstime)
+{
+ int ret;
+
+ ret = pthread_mutex_timedlock(mtx, abstime);
+ if (ret == ETIMEDOUT)
+ return (thrd_timedout);
+ else if (ret != 0)
+ return (thrd_error);
+ return (thrd_success);
+}
+
+int
+mtx_trylock(mtx_t *mtx)
+{
+ int ret;
+
+ ret = pthread_mutex_trylock(mtx);
+ if (ret == 0)
+ return (thrd_success);
+ else if (ret == EBUSY)
+ return (thrd_busy);
+ else
+ return (thrd_error);
+}
+
+int
+mtx_unlock(mtx_t *mtx)
+{
+ if (pthread_mutex_unlock(mtx) == 0)
+ return (thrd_success);
+ return (thrd_error);
+}
+
+int
+thrd_create(thrd_t *thr, thrd_start_t func, void *arg)
+{
+ int ret;
+
+ ret = pthread_create(thr, NULL, (void *(*)(void *))func, arg);
+ if (ret == 0)
+ return (thrd_success);
+ else if (ret == -1 && errno == EAGAIN)
+ return (thrd_nomem);
+ else
+ return (thrd_error);
+}
+
+thrd_t
+thrd_current(void)
+{
+ return (pthread_self());
+}
+
+int
+thrd_detach(thrd_t thr)
+{
+ if (pthread_detach(thr) == 0)
+ return (thrd_success);
+ return (thrd_error);
+}
+
+int
+thrd_equal(thrd_t t1, thrd_t t2)
+{
+ return (!pthread_equal(t1, t2));
+}
+
+_NORETURN_KYWD void
+thrd_exit(int res)
+{
+ pthread_exit((void *)(uintptr_t)res);
+}
+
+int
+thrd_join(thrd_t thrd, int *res)
+{
+ void *es;
+
+ if (pthread_join(thrd, &es) != 0)
+ return (thrd_error);
+ if (res != NULL)
+ *res = (uintptr_t)es;
+ return (thrd_success);
+}
+
+/*
+ * thrd_sleep has somewhat odd standardized return values. It doesn't use the
+ * same returns values as the thrd_* family of functions at all.
+ */
+int
+thrd_sleep(const struct timespec *rqtp, struct timespec *rmtp)
+{
+ int ret;
+ if ((ret = nanosleep(rqtp, rmtp)) == 0)
+ return (0);
+ if (ret == -1 && errno == EINTR)
+ return (-1);
+ return (-2);
+}
+
+void
+thrd_yield(void)
+{
+ thr_yield();
+}
+
+int
+tss_create(tss_t *key, tss_dtor_t dtor)
+{
+ if (pthread_key_create(key, dtor) == 0)
+ return (thrd_success);
+ return (thrd_error);
+}
+
+void
+tss_delete(tss_t key)
+{
+ if (pthread_key_delete(key) != 0)
+ abort();
+}
+
+void *
+tss_get(tss_t key)
+{
+ return (pthread_getspecific(key));
+}
+
+int
+tss_set(tss_t key, void *val)
+{
+ if (pthread_setspecific(key, val) == 0)
+ return (thrd_success);
+ return (thrd_error);
+}
diff --git a/usr/src/lib/libc/port/threads/thr.c b/usr/src/lib/libc/port/threads/thr.c
index b5d848449d..88ce377f21 100644
--- a/usr/src/lib/libc/port/threads/thr.c
+++ b/usr/src/lib/libc/port/threads/thr.c
@@ -23,7 +23,7 @@
* Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
*/
/*
- * Copyright (c) 2012, Joyent, Inc. All rights reserved.
+ * Copyright 2016 Joyent, Inc.
*/
#include "lint.h"
@@ -105,6 +105,7 @@ uberdata_t __uberdata = {
{ DEFAULTMUTEX, NULL, 0 },
{ DEFAULTMUTEX, NULL, 0 }},
{ RECURSIVEMUTEX, NULL, NULL }, /* atexit_root */
+ { RECURSIVEMUTEX, NULL }, /* quickexit_root */
{ DEFAULTMUTEX, 0, 0, NULL }, /* tsd_metadata */
{ DEFAULTMUTEX, {0, 0}, {0, 0} }, /* tls_metadata */
0, /* primary_map */
@@ -556,7 +557,7 @@ find_lwp(thread_t tid)
int
_thrp_create(void *stk, size_t stksize, void *(*func)(void *), void *arg,
- long flags, thread_t *new_thread, size_t guardsize)
+ long flags, thread_t *new_thread, size_t guardsize)
{
ulwp_t *self = curthread;
uberdata_t *udp = self->ul_uberdata;
@@ -719,7 +720,7 @@ _thrp_create(void *stk, size_t stksize, void *(*func)(void *), void *arg,
int
thr_create(void *stk, size_t stksize, void *(*func)(void *), void *arg,
- long flags, thread_t *new_thread)
+ long flags, thread_t *new_thread)
{
return (_thrp_create(stk, stksize, func, arg, flags, new_thread, 0));
}
diff --git a/usr/src/lib/libc/sparc/Makefile.com b/usr/src/lib/libc/sparc/Makefile.com
index 6a0f6b6fe4..5302bb8ebd 100644
--- a/usr/src/lib/libc/sparc/Makefile.com
+++ b/usr/src/lib/libc/sparc/Makefile.com
@@ -20,7 +20,7 @@
#
#
# Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
-# Copyright (c) 2015, Joyent, Inc. All rights reserved.
+# Copyright 2016 Joyent, Inc.
# Copyright (c) 2013, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2013 Garrett D'Amore <garrett@damore.org>
#
@@ -629,6 +629,7 @@ PORTGEN= \
tfind.o \
time_data.o \
time_gdata.o \
+ timespec_get.o \
tls_data.o \
truncate.o \
tsdalloc.o \
@@ -889,6 +890,7 @@ THREADSOBJS= \
alloc.o \
assfail.o \
cancel.o \
+ c11_thr.o \
door_calls.o \
tmem.o \
pthr_attr.o \
diff --git a/usr/src/lib/libc/sparcv9/Makefile.com b/usr/src/lib/libc/sparcv9/Makefile.com
index 71d5b604b3..d323044aff 100644
--- a/usr/src/lib/libc/sparcv9/Makefile.com
+++ b/usr/src/lib/libc/sparcv9/Makefile.com
@@ -589,6 +589,7 @@ PORTGEN= \
tfind.o \
time_data.o \
time_gdata.o \
+ timespec_get.o \
tls_data.o \
truncate.o \
tsdalloc.o \
@@ -834,6 +835,7 @@ TPOOLOBJS= \
THREADSOBJS= \
alloc.o \
assfail.o \
+ c11_thr.o \
cancel.o \
door_calls.o \
tmem.o \
diff --git a/usr/src/lib/libcmdutils/common/custr.c b/usr/src/lib/libcmdutils/common/custr.c
index 1ec72de9dd..95d44e431f 100644
--- a/usr/src/lib/libcmdutils/common/custr.c
+++ b/usr/src/lib/libcmdutils/common/custr.c
@@ -14,19 +14,27 @@
*/
/*
- * Copyright 2014, Joyent, Inc.
+ * Copyright 2016 Joyent, Inc.
*/
#include <stdlib.h>
#include <err.h>
#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <sys/debug.h>
#include "libcmdutils.h"
+typedef enum {
+ CUSTR_FIXEDBUF = 0x01
+} custr_flags_t;
+
struct custr {
size_t cus_strlen;
size_t cus_datalen;
char *cus_data;
+ custr_flags_t cus_flags;
};
#define STRING_CHUNK_SIZE 64
@@ -50,26 +58,28 @@ custr_len(custr_t *cus)
const char *
custr_cstr(custr_t *cus)
{
- return (cus->cus_data);
-}
+ if (cus->cus_data == NULL) {
+ VERIFY(cus->cus_strlen == 0);
+ VERIFY(cus->cus_datalen == 0);
-int
-custr_appendc(custr_t *cus, char newc)
-{
- char news[2];
-
- news[0] = newc;
- news[1] = '\0';
-
- return (custr_append(cus, news));
+ /*
+ * This function should never return NULL. If no buffer has
+ * been allocated, return a pointer to a zero-length string.
+ */
+ return ("");
+ }
+ return (cus->cus_data);
}
int
-custr_append(custr_t *cus, const char *news)
+custr_append_vprintf(custr_t *cus, const char *fmt, va_list ap)
{
- size_t len = strlen(news);
+ int len = vsnprintf(NULL, 0, fmt, ap);
size_t chunksz = STRING_CHUNK_SIZE;
+ if (len == -1)
+ return (len);
+
while (chunksz < len) {
chunksz *= 2;
}
@@ -78,6 +88,11 @@ custr_append(custr_t *cus, const char *news)
char *new_data;
size_t new_datalen = cus->cus_datalen + chunksz;
+ if (cus->cus_flags & CUSTR_FIXEDBUF) {
+ errno = EOVERFLOW;
+ return (-1);
+ }
+
/*
* Allocate replacement memory:
*/
@@ -104,13 +119,41 @@ custr_append(custr_t *cus, const char *news)
/*
* Append new string to existing string:
*/
- (void) memcpy(cus->cus_data + cus->cus_strlen, news, len + 1);
+ len = vsnprintf(cus->cus_data + cus->cus_strlen,
+ (uintptr_t)cus->cus_data - (uintptr_t)cus->cus_strlen, fmt, ap);
+ if (len == -1)
+ return (len);
cus->cus_strlen += len;
return (0);
}
int
+custr_appendc(custr_t *cus, char newc)
+{
+ return (custr_append_printf(cus, "%c", newc));
+}
+
+int
+custr_append_printf(custr_t *cus, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ va_start(ap, fmt);
+ ret = custr_append_vprintf(cus, fmt, ap);
+ va_end(ap);
+
+ return (ret);
+}
+
+int
+custr_append(custr_t *cus, const char *name)
+{
+ return (custr_append_printf(cus, "%s", name));
+}
+
+int
custr_alloc(custr_t **cus)
{
custr_t *t;
@@ -124,12 +167,35 @@ custr_alloc(custr_t **cus)
return (0);
}
+int
+custr_alloc_buf(custr_t **cus, void *buf, size_t buflen)
+{
+ int ret;
+
+ if (buflen == 0 || buf == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+
+ if ((ret = custr_alloc(cus)) != 0)
+ return (ret);
+
+ (*cus)->cus_data = buf;
+ (*cus)->cus_datalen = buflen;
+ (*cus)->cus_strlen = 0;
+ (*cus)->cus_flags = CUSTR_FIXEDBUF;
+ (*cus)->cus_data[0] = '\0';
+
+ return (0);
+}
+
void
custr_free(custr_t *cus)
{
if (cus == NULL)
return;
- free(cus->cus_data);
+ if ((cus->cus_flags & CUSTR_FIXEDBUF) == 0)
+ free(cus->cus_data);
free(cus);
}
diff --git a/usr/src/lib/libcmdutils/common/mapfile-vers b/usr/src/lib/libcmdutils/common/mapfile-vers
index 640959e4b5..1f63d4eee0 100644
--- a/usr/src/lib/libcmdutils/common/mapfile-vers
+++ b/usr/src/lib/libcmdutils/common/mapfile-vers
@@ -43,8 +43,11 @@ SYMBOL_VERSION SUNWprivate_1.1 {
global:
add_tnode;
custr_alloc;
+ custr_alloc_buf;
custr_append;
custr_appendc;
+ custr_append_printf;
+ custr_append_vprintf;
custr_cstr;
custr_free;
custr_len;
diff --git a/usr/src/lib/libcmdutils/libcmdutils.h b/usr/src/lib/libcmdutils/libcmdutils.h
index bbc03475dc..7c3d0ebbc1 100644
--- a/usr/src/lib/libcmdutils/libcmdutils.h
+++ b/usr/src/lib/libcmdutils/libcmdutils.h
@@ -26,7 +26,7 @@
* Copyright (c) 2013 RackTop Systems.
*/
/*
- * Copyright 2014 Joyent, Inc.
+ * Copyright 2016 Joyent, Inc.
*/
/*
@@ -44,6 +44,7 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
+#include <stdarg.h>
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
@@ -156,6 +157,12 @@ extern int custr_alloc(custr_t **);
extern void custr_free(custr_t *);
/*
+ * Allocate a "custr_t" dynamic string object that operates on a fixed external
+ * buffer.
+ */
+extern int custr_alloc_buf(custr_t **, void *, size_t);
+
+/*
* Append a single character, or a NUL-terminated string of characters, to a
* dynamic string. Returns 0 on success and -1 otherwise. The dynamic string
* will be unmodified if the function returns -1.
@@ -164,6 +171,14 @@ extern int custr_appendc(custr_t *, char);
extern int custr_append(custr_t *, const char *);
/*
+ * Append a format string and arguments as though the contents were being parsed
+ * through snprintf. Returns 0 on success and -1 otherwise. The dynamic string
+ * will be unmodified if the function returns -1.
+ */
+extern int custr_append_printf(custr_t *, const char *, ...);
+extern int custr_append_vprintf(custr_t *, const char *, va_list);
+
+/*
* Determine the length in bytes, not including the NUL terminator, of the
* dynamic string.
*/
diff --git a/usr/src/man/man3c/Makefile b/usr/src/man/man3c/Makefile
index 5348d83bf8..67861882e4 100644
--- a/usr/src/man/man3c/Makefile
+++ b/usr/src/man/man3c/Makefile
@@ -14,7 +14,7 @@
# Copyright 2013 Nexenta Systems, Inc. All rights reserved.
# Copyright 2013, OmniTI Computer Consulting, Inc. All rights reserved.
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
-# Copyright (c) 2015, Joyent, Inc. All rights reserved.
+# Copyright 2016 Joyent, Inc.
#
include $(SRC)/Makefile.master
@@ -40,6 +40,7 @@ MANFILES= __fbufsize.3c \
aiocancel.3c \
aioread.3c \
aiowait.3c \
+ aligned_alloc.3c \
arc4random.3c \
assert.3c \
atexit.3c \
@@ -58,6 +59,7 @@ MANFILES= __fbufsize.3c \
bsearch.3c \
bstring.3c \
btowc.3c \
+ call_once.3c \
catgets.3c \
catopen.3c \
cfgetispeed.3c \
@@ -68,6 +70,7 @@ MANFILES= __fbufsize.3c \
clock_settime.3c \
closedir.3c \
closefrom.3c \
+ cnd.3c \
cond_init.3c \
confstr.3c \
crypt.3c \
@@ -249,6 +252,7 @@ MANFILES= __fbufsize.3c \
mq_setattr.3c \
mq_unlink.3c \
msync.3c \
+ mtx.3c \
mutex_init.3c \
nanosleep.3c \
ndbm.3c \
@@ -362,6 +366,7 @@ MANFILES= __fbufsize.3c \
putspent.3c \
putws.3c \
qsort.3c \
+ quick_exit.3c \
raise.3c \
rand.3c \
random.3c \
@@ -471,11 +476,19 @@ MANFILES= __fbufsize.3c \
thr_stksegment.3c \
thr_suspend.3c \
thr_yield.3c \
+ thrd_create.3c \
+ thrd_current.3c \
+ thrd_detach.3c \
+ thrd_equal.3c \
+ thrd_exit.3c \
+ thrd_join.3c \
+ thrd_yield.3c \
timer_create.3c \
timer_delete.3c \
timer_settime.3c \
timeradd.3c \
timerfd_create.3c \
+ timespec_get.3c \
tmpfile.3c \
tmpnam.3c \
toascii.3c \
@@ -485,6 +498,7 @@ MANFILES= __fbufsize.3c \
towupper.3c \
truncate.3c \
tsearch.3c \
+ tss.3c \
ttyname.3c \
ttyslot.3c \
u8_strcmp.3c \
@@ -565,6 +579,7 @@ MANLINKS= FD_CLR.3c \
asctime.3c \
asctime_r.3c \
asprintf.3c \
+ at_quick_exit.3c \
atof.3c \
atoi.3c \
atol.3c \
@@ -696,6 +711,12 @@ MANLINKS= FD_CLR.3c \
clock_getres.3c \
clock_gettime.3c \
closelog.3c \
+ cnd_broadcast.3c \
+ cnd_destroy.3c \
+ cnd_init.3c \
+ cnd_signal.3c \
+ cnd_timedwait.3c \
+ cnd_wait.3c \
cond_broadcast.3c \
cond_destroy.3c \
cond_reltimedwait.3c \
@@ -954,6 +975,12 @@ MANLINKS= FD_CLR.3c \
mq_timedreceive.3c \
mq_timedsend.3c \
mrand48.3c \
+ mtx_destroy.3c \
+ mtx_init.3c \
+ mtx_lock.3c \
+ mtx_timedlock.3c \
+ mtx_trylock.3c \
+ mtx_unlock.3c \
munlock.3c \
munlockall.3c \
mutex_consistent.3c \
@@ -1210,6 +1237,7 @@ MANLINKS= FD_CLR.3c \
thr_setconcurrency.3c \
thr_setprio.3c \
thr_setspecific.3c \
+ thrd_sleep.3c \
timegm.3c \
timer_getoverrun.3c \
timer_gettime.3c \
@@ -1226,6 +1254,10 @@ MANLINKS= FD_CLR.3c \
towctrans_l.3c \
towlower_l.3c \
towupper_l.3c \
+ tss_create.3c \
+ tss_delete.3c \
+ tss_get.3c \
+ tss_set.3c \
ttyname_r.3c \
twalk.3c \
tzset.3c \
@@ -1366,6 +1398,8 @@ aiowrite.3c := LINKSRC = aioread.3c
arc4random_buf.3c := LINKSRC = arc4random.3c
arc4random_uniform.3c := LINKSRC = arc4random.3c
+at_quick_exit.3c := LINKSRC = quick_exit.3c
+
atomic_add_16.3c := LINKSRC = atomic_add.3c
atomic_add_16_nv.3c := LINKSRC = atomic_add.3c
atomic_add_32.3c := LINKSRC = atomic_add.3c
@@ -1499,6 +1533,13 @@ clock_gettime.3c := LINKSRC = clock_settime.3c
fdwalk.3c := LINKSRC = closefrom.3c
+cnd_broadcast.3c := LINKSRC = cnd.3c
+cnd_destroy.3c := LINKSRC = cnd.3c
+cnd_init.3c := LINKSRC = cnd.3c
+cnd_signal.3c := LINKSRC = cnd.3c
+cnd_timedwait.3c := LINKSRC = cnd.3c
+cnd_wait.3c := LINKSRC = cnd.3c
+
cond_broadcast.3c := LINKSRC = cond_init.3c
cond_destroy.3c := LINKSRC = cond_init.3c
cond_reltimedwait.3c := LINKSRC = cond_init.3c
@@ -1891,12 +1932,21 @@ mq_timedreceive.3c := LINKSRC = mq_receive.3c
mq_reltimedsend_np.3c := LINKSRC = mq_send.3c
mq_timedsend.3c := LINKSRC = mq_send.3c
+mtx_destroy.3c := LINKSRC = mtx.3c
+mtx_init.3c := LINKSRC = mtx.3c
+mtx_lock.3c := LINKSRC = mtx.3c
+mtx_timedlock.3c := LINKSRC = mtx.3c
+mtx_trylock.3c := LINKSRC = mtx.3c
+mtx_unlock.3c := LINKSRC = mtx.3c
+
mutex_consistent.3c := LINKSRC = mutex_init.3c
mutex_destroy.3c := LINKSRC = mutex_init.3c
mutex_lock.3c := LINKSRC = mutex_init.3c
mutex_trylock.3c := LINKSRC = mutex_init.3c
mutex_unlock.3c := LINKSRC = mutex_init.3c
+thrd_sleep.3c := LINKSRC = nanosleep.3c
+
dbm_clearerr.3c := LINKSRC = ndbm.3c
dbm_close.3c := LINKSRC = ndbm.3c
dbm_delete.3c := LINKSRC = ndbm.3c
@@ -2278,6 +2328,11 @@ tdelete.3c := LINKSRC = tsearch.3c
tfind.3c := LINKSRC = tsearch.3c
twalk.3c := LINKSRC = tsearch.3c
+tss_create.3c := LINKSRC = tss.3c
+tss_delete.3c := LINKSRC = tss.3c
+tss_get.3c := LINKSRC = tss.3c
+tss_set.3c := LINKSRC = tss.3c
+
ttyname_r.3c := LINKSRC = ttyname.3c
uconv_u16tou8.3c := LINKSRC = uconv_u16tou32.3c
diff --git a/usr/src/man/man3c/aligned_alloc.3c b/usr/src/man/man3c/aligned_alloc.3c
new file mode 100644
index 0000000000..d3c6f43c32
--- /dev/null
+++ b/usr/src/man/man3c/aligned_alloc.3c
@@ -0,0 +1,74 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Mar 26, 2016"
+.Dt ALIGNED_ALLOC 3C
+.Os
+.Sh NAME
+.Nm aligned_alloc
+.Nd aligned memory allocation
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft "void *"
+.Fo aligned_alloc
+.Fa "size_t alignment"
+.Fa "size_t size"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn aligned_alloc
+function allocates
+.Fa size
+bytes aligned on the specified alignment boundary
+.Fa alignment .
+The value of
+.Fa alignment
+is constrained, it must be a power of two and it must be greater than or
+equal to the size of a word on the platform.
+.Sh RETURN VALUES
+Upon successful completion, the
+.Fn aligned_alloc
+function returns a pointer to suitably aligned memory at least
+.Fa size
+bytes large. Otherwise, a
+.Sy NULL
+pointer is returned and
+.Sy errno
+is set to indicate the error.
+.Sh ERRORS
+The
+.Fn aligned_alloc
+function will fail if:
+.Bl -tag -width Er
+.It Er ENOMEM
+The physical limits of the system are exceeded by
+.Fa size
+bytes of memory which cannot be allocated.
+.It Er EAGAIN
+There is not enough memory available to allocate
+.Fa size
+bytes of memory; but the application could try again later.
+.It Er EINVAL
+An invalid value for
+.Fa alignment
+was passed in. It is not a power of two multiple of the word size.
+.El
+.Sh INTERFACE STABILITY
+.Sy STANDARD
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr malloc 3C ,
+.Xr memalgin 3C ,
+.Xr posix_memalign 3C ,
+.Xr attributes 5
diff --git a/usr/src/man/man3c/call_once.3c b/usr/src/man/man3c/call_once.3c
new file mode 100644
index 0000000000..5cc1ba56a9
--- /dev/null
+++ b/usr/src/man/man3c/call_once.3c
@@ -0,0 +1,89 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 11, 2015"
+.Dt CALL_ONCE 3C
+.Os
+.Sh NAME
+.Nm call_once
+.Nd ensure function is only called once
+.Sh SYNOPSIS
+.In treads.h
+.Vt "once_flag once = ONCE_FLAG_INIT;"
+.Ft void
+.Fo call_once
+.Fa "once_flag *once"
+.Fa "void (*func)(void)"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn call_once
+function is used to ensure that an operation occurs only once, even
+across multiple threads. Each instance of a properly initialized
+.Ft once_flag
+can be pased to the
+.Ft call_once
+function; however, only a single caller will successfully execute the
+specified function,
+.Fa func .
+This ensures that the argument
+.Fa func
+is called only once. Note, the argument
+.Fa once
+is the only thing used as a point of synchronization. If multiple
+callers use the same pointer for
+.Fa once ,
+but use different values for
+.Fa func ,
+then only one of the functions will be successfully called.
+.Pp
+The argument
+.Fn once
+should always be initialized to the symbol
+.Sy ONCE_FLAG_INIT
+before calling
+.Fn call_once .
+Failure to do so will result in undefined behavior.
+.Pp
+Like
+.Xr pthread_once 3C ,
+the
+.Fn call_once
+function is not itself a cancellation point; however, if the thread
+calling
+.Fn func
+encounters a cancellation point and is cancelled, then the value pointed
+to by
+.Fa once
+will be as though
+.Fn call_once
+had not been called, as
+.Fn func
+had not completed successfully.
+.Sh RETURN VALUES
+The
+.Fn call_once
+function does not return any values. Upon its completion, it is guaranteed that
+.Fa func
+will have been called at most once across the liftime of the
+.Fa once
+argument .
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr pthread_once 3C ,
+.Xr threads.h 3HEAD ,
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/cnd.3c b/usr/src/man/man3c/cnd.3c
new file mode 100644
index 0000000000..7e2ce29d66
--- /dev/null
+++ b/usr/src/man/man3c/cnd.3c
@@ -0,0 +1,183 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 11, 2015"
+.Dt CND 3C
+.Os
+.Sh NAME
+.Nm cnd
+.Nm cnd_broadcast ,
+.Nm cnd_destroy ,
+.Nm cnd_init ,
+.Nm cnd_signal ,
+.Nm cnd_timedwait ,
+.Nm cnd_wait
+.Nd C11 condition variable functions
+.Sh SYNOPSIS
+.In threads.h
+.Ft int
+.Fo cnd_init
+.Fa "cnd_t *cnd"
+.Fc
+.Ft void
+.Fo cnd_destroy
+.Fa "cnd_t *cnd"
+.Fc
+.Ft int
+.Fo cnd_broadcast
+.Fa "cnd_t *cnd"
+.Fc
+.Ft int
+.Fo cnd_signal
+.Fa "cnd_t *cnd"
+.Fc
+.Ft int
+.Fo cnd_timedwait
+.Fa "cnd_t *restrict cnd"
+.Fa "mtx_t *restrict mtx"
+.Fa "const struct timespec *abstime"
+.Fc
+.Ft int
+.Fo cnd_wait
+.Fa "cnd_t *restrict cnd"
+.Fa "mtx_t *restrict mtx"
+.Fc
+.Sh DESCRIPTION
+The
+.Sy cnd
+family of functions implement condition variables which allow threads
+within a process to wait until a condition occurs and be signaled when
+it does. These functions behave similar to both the POSIX threads and
+illumos threads; however, they have slightly different call signatures
+and return values. For more information, see
+.Xr threads 5 .
+Importantly, they do not allow for inter-process synchronization.
+.Ss Creating and Destroy Condition Variables
+The function
+.Fn cnd_init
+initializes the condition variable referred to by
+.Fa cnd .
+The condition variable is suitable for intra-process use. Initializing
+an already initialized condition variable results in undefined behavior.
+.Pp
+The function
+.Fn cnd_destroy
+destroys an initialized condition variable at which point it is illegal
+to use it, though it may be initialized again.
+.Ss Condition Waiting
+The function
+.Fn cond_wait
+can be used to wait on a condition variable. A thread that waits on a
+condition variable blocks until another thread signals that the
+condition has changed, generally after making the condition that was
+false, true.
+.Pp
+The function
+.Fn cond_wait
+atomically release the mutex pointed to by
+.Fa mtx
+and blocks on the condition variable
+.Fa cond .
+When the thread returns, it will once again be holding
+.Fa mtx
+and must check the current state of the condition. There is no
+guarantee that another thread has not gotten in and changed the value
+before being woken. In addition, a thread blocking on a condition
+variable, may be woken spuriously, such as when a signal is received or
+.Fn fork
+is called .
+.Pp
+The function
+.Fn cond_timedwait
+allows a thread to block in a similar fashion to
+.Fn cond_wait ,
+except that when the absolute time specified in seconds since the epoch
+(based on
+.Sy CLOCK_REALTIME )
+in UTC, expires, then the thread will be woken up. The timeout is
+specified in
+.Fa abstime .
+.Ss Conditional Signaling
+The
+.Fn cnd_signal
+and
+.Fn cnd_broadcast
+functions can be used to signal threads waiting on the condition variable
+.Fa cnd
+that they should be woken up and check the variable again. The
+.Fn cnd_signal
+function will only wake a single thread that is blocked on the
+condition variable
+.Fa cnd ;
+while
+.Fn cnd_broadcast
+will wake up every thread waiting on the condition variable
+.Fa cnd .
+.Pp
+A thread calling either
+.Fn cnd_signal
+or
+.Fn cnd_broadcast
+is not required to hold any of the mutexes that are associated with the
+condition variable.
+.Pp
+If there are no threads currently blocked in the condition variable
+.Fa cnd
+then neither function has an effect.
+.Sh RETURN VALUES
+Upon successful completion, the
+.Fn cond_init
+function returns
+.Sy thrd_success.
+If insufficient memory was available, then
+.Sy thrd_nomem
+is returned; otherwise, if any other error occurred,
+.Sy thrd_error
+is returned.
+.Pp
+Upon successful completion, the
+.Fn cond_broadcast ,
+.Fn cond_signal ,
+and
+.Fn cond_wait
+functions return
+.Sy thrd_success .
+Otherwise, they return
+.Sy thrd_error
+to indicate that an error occurred and they were unable to complete.
+.Pp
+Upon successful completion, the
+.Fn cond_timedwait
+function returns
+.Sy thrd_success .
+If
+.Fa abstime
+expires without being signaled, it instead returns
+.Sy thrd_timedout .
+Otherwise,
+.Sy thrd_error
+is returned to indicate an error.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr cond_braodcast 3C ,
+.Xr cond_destroy 3C ,
+.Xr cond_init 3C ,
+.Xr cond_signal 3C ,
+.Xr cond_timedwait 3C ,
+.Xr cond_wait 3C ,
+.Xr threads 3HEAD ,
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/mtx.3c b/usr/src/man/man3c/mtx.3c
new file mode 100644
index 0000000000..7a2a89b11e
--- /dev/null
+++ b/usr/src/man/man3c/mtx.3c
@@ -0,0 +1,216 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 11, 2015"
+.Dt MTX 3C
+.Os
+.Sh NAME
+.Nm mtx ,
+.Nm mtx_destroy ,
+.Nm mtx_init ,
+.Nm mtx_lock ,
+.Nm mtx_timedlock ,
+.Nm mtx_trylock ,
+.Nm mtx_unlock
+.Nd C11 mutex operations
+.Sh SYNOPSIS
+.In threads.h
+.Ft int
+.Fo mtx_init
+.Fa "mtx_t *mtx"
+.Fa "int type"
+.Fc
+.Ft void
+.Fo mtx_destroy
+.Fa "mtx_t *mtx"
+.Fc
+.Ft int
+.Fo mtx_lock
+.Fa "mtx_t *mtx"
+.Fc
+.Ft int
+.Fo mtx_timedlock
+.Fa "mtx_t *mtx"
+.Fa "const struct timespec *restrict ts"
+.Fc
+.Ft int
+.Fo mtx_trylock
+.Fa "mtx_t *mtx"
+.Fc
+.Ft int
+.Fo mtx_unlock
+.Fa "mtx_t *mtx"
+.Fc
+.Sh DESCRIPTION
+The
+.Sy mtx
+family of functions implement mutual exclusion locks (mutexes) and behave
+similarly to both POSIX threads and illumos threads; however, they have
+slightly different call signatures and return values. For more
+information, see
+.Xr threads 5 .
+Importantly, they do not allow for inter-process synchronization.
+.Ss Creating and Destroying Mutexes
+The
+.Fn mtx_init
+function initializes the mutex specified by
+.Fa mtx .
+The following types of mutexes are valid and may be specified by the
+.Fa type
+argument:
+.Bl -tag -width Dv
+.It Sy mtx_plain
+A simple, intra-process mutex.
+.It Sy mtx_timed
+A simple, intra-process mutex, which allows timed locking operations.
+.It Sy mtx_plain | mtx_recursive
+An intra-process mutex that may be acquired recursively by the same
+thread. It must be unlocked an equal number of times that it is locked.
+.It Sy mtx_timed | mtx_recursive
+An intra-process mutex that supports timed locking operations and may be
+acquired recursively by the same thread. It must be unlocked an equal
+number of times that it is locked.
+.El
+For more information on the different kind of mutexes, see
+.Xr mutex_init 3C .
+.Pp
+The
+.Fn mtx_destroy
+function destroys the mutex pointed to by
+.Fa mtx .
+It is illegal for threads to be blocked waiting for
+.Fa mtx
+when
+.Fn mtx_destroy
+is called .
+.Ss Locking and Unlocking Mutexes
+The
+.Fn mtx_lock
+function attempts to lock the mutex
+.Fa mtx .
+When the function returns, it will be the sole owner of the mutex and
+must call
+.Fn mtx_unlock
+when it is done, or risk inducing a deadlock in the process. Other
+threads that make calls to
+.Fn mtx_lock
+after another thread has successfully completed its call to
+.Fn mtx_lock
+will block.
+When they finally return, then they will have obtained the mutex
+.Fa mtx .
+.Pp
+Unless a lock of type
+.Sy mtx_recursive
+was created, a thread calling
+.Fn mtx_lock
+when it already holds
+.Fa mtx
+will cause the thread to deadlock. Othewrise, the lock will be
+successfully taken again. However, a thread must call
+.Fn mtx_unlock
+for each time that it has acquried
+.Fa mtx .
+.Pp
+The
+.Fn mtx_trylock
+function will attempt to obtain the mutex pointed to by
+.Fa mtx .
+However, unlike
+.Fn mtx_lock ,
+if
+.Fa mtx
+is locked, then it will not block and wait for
+.Fa mtx
+and instead return
+.Sy thrd_busy
+to indicate that the lock is currently held.
+.Pp
+The
+.Fn mtx_timedlock
+function attempts to obtain the mutex pointed to by
+.Fa mtx .
+If it is unable to obtain it, then it will block for a set amount of
+time dictated by
+.Fa ts .
+The timeout in
+.Fa ts
+is treated as an absolute time in UTC to block until, measured based on
+the
+.Sy CLOCK_REALTIME
+clock.
+.Pp
+The
+.Fn mtx_unlock
+function unlocks the mutex pointed to by
+.Fa mtx ,
+which allows another thread the opportunity to obtain it. If any threads
+are actively blocking on the mutex, one of them will obtain it and be
+woken up. It is an error to call
+.Fn mtx_unlock
+on a mutex which the calling thread does not currently own.
+.Sh RETURN VALUES
+Upon successful completion, the function
+.Fn mtx_init returns
+.Sy thrd_success.
+If there was insufficient memory to create the thread,
+it instead returns
+.Sy thrd_nomem .
+If any other error occurred, it returns
+.Sy thrd_error .
+.Pp
+The functions
+.Fn mtx_lock ,
+and
+.Fn mtx_unlock
+return
+.Sy thrd_success .
+If they were unable to successfully complete the operation, they instead
+return
+.Sy thrd_error .
+.Pp
+Upon sucessful completion, the
+.Fn mtx_timedlock
+function returns
+.Sy thrd_success .
+If the timeout is reached and the calling thread is unable to obtain the
+mutex, then
+.Sy thrd_timedout
+is returned .
+If any other error occurs, then
+.Sy thrd_error is returned.
+.Pp
+Upon successful completion, the
+.Fn mtx_trylock
+function returns
+.Sy thrd_success .
+If the thread was unable to obtain the mutex because another thread owns
+it, then it returns
+.Sy thrd_busy .
+Otherwise, an error will have occurred and
+.Sy thrd_error
+is returned.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr mutex_init 3C ,
+.Xr pthread_mutex_destroy 3C ,
+.Xr pthread_mutex_init 3C ,
+.Xr pthread_mutex_lock 3C ,
+.Xr pthread_mutex_timedlock 3C ,
+.Xr pthread_mutex_trylock 3C ,
+.Xr pthread_mutex_unlock 3C ,
+.Xr threads.h 3HEAD ,
+.Xr attributes 5
diff --git a/usr/src/man/man3c/nanosleep.3c b/usr/src/man/man3c/nanosleep.3c
index fbfc47dd45..617cc35555 100644
--- a/usr/src/man/man3c/nanosleep.3c
+++ b/usr/src/man/man3c/nanosleep.3c
@@ -1,5 +1,6 @@
'\" te
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2016 Joyent, Inc.
.\" Copyright 1989 AT&T
.\" Portions Copyright (c) 1992, X/Open Company Limited All Rights Reserved
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
@@ -9,9 +10,9 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH NANOSLEEP 3C "Feb 5, 2008"
+.TH NANOSLEEP 3C "Mar 27, 2016"
.SH NAME
-nanosleep \- high resolution sleep
+nanosleep, thrd_sleep \- high resolution sleep
.SH SYNOPSIS
.LP
.nf
@@ -21,27 +22,32 @@ nanosleep \- high resolution sleep
\fBstruct timespec *\fR\fIrmtp\fR);
.fi
+.nf
+#include <threads.h>
+
+\fBint\fR \fBthrd_sleep\fR(\fBconst struct timespec *\fR\fIrqtp\fR,
+ \fBstruct timespec *\fR\fIrmtp\fR);
+
.SH DESCRIPTION
-.sp
.LP
-The \fBnanosleep()\fR function causes the current thread to be suspended from
-execution until either the time interval specified by the \fIrqtp\fR argument
-has elapsed or a signal is delivered to the calling thread and its action is to
-invoke a signal-catching function or to terminate the process. The suspension
-time may be longer than requested because the argument value is rounded up to
-an integer multiple of the sleep resolution or because of the scheduling of
-other activity by the system. But, except for the case of being interrupted by
-a signal, the suspension time will not be less than the time specified by
-\fIrqtp\fR, as measured by the system clock, \fBCLOCK_REALTIME\fR.
+The \fBnanosleep()\fR and \fBthrd_sleep()\fR functions cause the current thread
+to be suspended from execution until either the time interval specified by the
+\fIrqtp\fR argument has elapsed or a signal is delivered to the calling thread
+and its action is to invoke a signal-catching function or to terminate the
+process. The suspension time may be longer than requested because the argument
+value is rounded up to an integer multiple of the sleep resolution or because of
+the scheduling of other activity by the system. But, except for the case of
+being interrupted by a signal, the suspension time will not be less than the
+time specified by \fIrqtp\fR, as measured by the system clock,
+\fBCLOCK_REALTIME\fR.
.sp
.LP
-The use of the \fBnanosleep()\fR function has no effect on the action or
-blockage of any signal.
+The use of the \fBnanosleep()\fR and \fBthrd_sleep()\fR functions has no effect
+on the action or blockage of any signal.
.SH RETURN VALUES
-.sp
.LP
-If the \fBnanosleep()\fR function returns because the requested time has
-elapsed, its return value is \fB0\fR.
+If the \fBnanosleep()\fR or \fBthrd_sleep()\fR function returns because the
+requested time has elapsed, its return value is \fB0\fR.
.sp
.LP
If the \fBnanosleep()\fR function returns because it has been interrupted by a
@@ -55,9 +61,22 @@ returned.
.LP
If \fBnanosleep()\fR fails, it returns \fB\(mi1\fR and sets \fBerrno\fR to
indicate the error.
-.SH ERRORS
.sp
.LP
+
+The
+.B thrd_sleep()
+function may fail for identical reasons as the
+.B nanosleep()
+function and returns \(mi1; however, the C11 standard does not define that
+.B errno
+should be set, therefore callers of \fBthrd_sleep()\fR cannot rely on
+.B errno
+being set or staying the same across a call to
+.B thrd_sleep() .
+
+.SH ERRORS
+.LP
The \fBnanosleep()\fR function will fail if:
.sp
.ne 2
@@ -88,7 +107,6 @@ The \fBnanosleep()\fR function is not supported by this implementation.
.RE
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -108,6 +126,5 @@ Standard See \fBstandards\fR(5).
.TE
.SH SEE ALSO
-.sp
.LP
\fBsleep\fR(3C), \fBtime.h\fR(3HEAD), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3c/quick_exit.3c b/usr/src/man/man3c/quick_exit.3c
new file mode 100644
index 0000000000..e3e17603b4
--- /dev/null
+++ b/usr/src/man/man3c/quick_exit.3c
@@ -0,0 +1,92 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Mar 26, 2016"
+.Dt QUICK_EXIT 3C
+.Os
+.Sh NAME
+.Nm at_quick_exit ,
+.Nm quick_exit
+.Nd terminate a running process with minimal teardown
+.Sh SYNOPSIS
+.In stdlib.h
+.Ft int
+.Fo at_quick_exit
+.Fa "void (*func)(void)"
+.Fc
+.Ft _Noreturn void
+.Fo quick_exit
+.Fa "int status"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn quick_exit
+and
+.Fn at_quick_exit
+functions provide a veneer around
+.Xr _Exit 3C
+that allows for registered functions to be called before terminating.
+Like
+.Xr _Exit 3C ,
+standard library termination is not done.
+.Xr atexit 3C
+functions are not called and various standard termination that occurs
+when calling
+.Xr exit 3C
+may not occur.
+.Pp
+Functions that are registered with
+.Fn at_quick_exit
+will be called in reverse order upon calling
+.Fn quick_exit .
+Functions registered with
+.Fn at_quick_exit
+will not be called at any other time. Functions that are registered with
+.Fn at_quick_exit
+should not make use of
+.Xr longjump 3C
+and related functions.
+.Pp
+After calling all registered functions, the
+.Fn quick_exit
+function will terminate the calling program and its exit status will be
+.Fa status .
+.Sh RETURN VALUES
+The
+.Fn quick_exit
+function does not return.
+.Pp
+The
+.Fn at_quick_exit
+function returns
+.Sy 0
+on success. Otherwise, a non-zero error value is returned to indicate
+failure.
+.Sh ERRORS
+The
+.Fn at_quick_exit
+function may fail if:
+.Bl -tag -width Er
+.It Er ENOMEM
+Insufficient storage space is available.
+.El
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy Safe
+.Sh SEE ALSO
+.Xr _Exit 3C ,
+.Xr atexit 3C ,
+.Xr exit 3C ,
+.Xr attributes 5 ,
+.Xr standards 5
diff --git a/usr/src/man/man3c/thrd_create.3c b/usr/src/man/man3c/thrd_create.3c
new file mode 100644
index 0000000000..ffaf9bf11c
--- /dev/null
+++ b/usr/src/man/man3c/thrd_create.3c
@@ -0,0 +1,90 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 13, 2015"
+.Dt THRD_CREATE 3C
+.Os
+.Sh NAME
+.Nm thrd_create
+.Nd create a thread
+.Sh SYNOPSIS
+.In threads.h
+.Vt "typedef int (*thrd_start_t)(void *);"
+.Ft int
+.Fo thrd_create
+.Fa "thrd_t *thrdp"
+.Fa "thrd_start_t func"
+.Fa "void *arg"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn thrd_create
+function creates a new thread of execution inside of the current
+process and stores its identifier in
+.Fa thrdp .
+Each thread operates concurrently within the process.
+.Pp
+When a thread is created, it begins its execution at the function
+.Fa func
+with the argument
+.Fa arg .
+A created thread has access to all global data within a process;
+however, it has its own private stack. Currently 32-bit processes have a
+default stack of 1 megabyte, while 64-bit systems have a default stack
+size of 2 megabytes. In addition, newly created threads inherit the
+signal mask of the thread which created them; however, they do not
+inherit any pending signals.
+.Pp
+Once created, a thread will continue to execute until either, it returns
+from its initial function, the thread explicitly calls
+.Xr thrd_exit 3C ,
+or the process itself terminates, such as with a call to
+.Xr exit 2 .
+When the initial function returns, it behaves as though a call to
+.Xr thrd_exit
+was made, and, if the thread has not been detached with a call to
+.Xr thrd_detach,
+the exit status remains available and the corresponding thread ID will
+not be reused until a process calls
+.Xr thrd_join 3C .
+This is similar to how a parent must call
+.Xr wait 2 ,
+to clean up a child process that has terminated.
+.Pp
+For a richer interface interface with more control over aspects of the
+newly created thread, such as stack size, stack placement, and the like,
+see
+.Xr thr_create 3C
+and
+.Xr pthread_create 3C .
+.Sh RETURN VALUES
+Upon successful completion, the
+.Fn thrd_create
+function returns
+.Sy thrd_success .
+If insufficient memory was available, then
+.Sy thrd_nomem
+is returned. Otherwise,
+.Sy thrd_error
+is returned, indicating that a non-memory related error.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr pthread_create 3C ,
+.Xr thr_create 3C ,
+.Xr thrd_detach 3C ,
+.Xr thrd_join 3C ,
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/thrd_current.3c b/usr/src/man/man3c/thrd_current.3c
new file mode 100644
index 0000000000..9cc41795ab
--- /dev/null
+++ b/usr/src/man/man3c/thrd_current.3c
@@ -0,0 +1,46 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 11, 2015"
+.Dt THRD_CURRENT 3C
+.Os
+.Sh NAME
+.Nm thrd_current
+.Nd obtain current thread's ID
+.Sh SYNOPSIS
+.In threads.h
+.Ft thrd_t
+.Fo thrd_current
+.Fa void
+.Fc
+.Sh DESCRIPTION
+The
+.Fn thrd_current
+function returns the thread ID of the current calling thread. Note, this
+ID may be different from the thread ID returned when using
+.Xr thr_self 3C
+or
+.Xr pthread_self 3C ;
+however, it still uniquely identifies the thread.
+.Sh ERRORS
+No errors are defined.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-Level
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr pthread_self 3C ,
+.Xr thr_self 3C ,
+.Xr thrd_create 3C ,
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/thrd_detach.3c b/usr/src/man/man3c/thrd_detach.3c
new file mode 100644
index 0000000000..8749b53c1b
--- /dev/null
+++ b/usr/src/man/man3c/thrd_detach.3c
@@ -0,0 +1,56 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright (c) 2015, Joyent, Inc.
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 13, 2015"
+.Dt THRD_DETACH 3C
+.Os
+.Sh NAME
+.Nm thrd_detach
+.Nd detach a thread
+.Sh SYNOPSIS
+.In threads.h
+.Ft int
+.Fo thrd_detach
+.Fa "thrd_t thrd"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn thrd_detach
+function causes a thread to be considered detached from the rest of the
+execution environment. While detached threads are still fully
+observable, they cannot be joined with, calls to
+.Fn thrd_join
+will fail. In addition, if all non-detached
+threads have terminated, the program will terminate; detached threads
+cannot keep a program running. The act of calling
+.Fn thrd_detach
+on a thread does not cause it to terminate.
+.Sh RETURN VALUES
+Upon successful completion, the
+.Xr thrd_detach
+function returns
+.Sy thrd_success .
+Otherwise, it returns
+.Sy thrd_error ,
+indicating that an error has occurred.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-safe
+.Sh SEE ALSO
+.Xr pthread_detach 3C ,
+.Xr thrd_create 3C ,
+.Xr thrd_join 3C ,
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/thrd_equal.3c b/usr/src/man/man3c/thrd_equal.3c
new file mode 100644
index 0000000000..6c77a72138
--- /dev/null
+++ b/usr/src/man/man3c/thrd_equal.3c
@@ -0,0 +1,56 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 11, 2015"
+.Dt THRD_EQUAL 3C
+.Os
+.Sh NAME
+.Nm thrd_equal
+.Nd determine if threads are equal
+.Sh SYNOPSIS
+.In threads.h
+.Ft int
+.Fo thrd_equal
+.Fa "thrd_t thrd0"
+.Fa "thrd_t thrd1"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn thrd_equal
+function compares
+.Fa thrd0
+and
+.Fa thrd1
+and determines whether or not they refer to the same thread.
+.Sh RETURN VALUES
+The
+.Fn thrd_equal
+function returns
+.Sy 0
+if
+.Fa thrd0
+and
+.Fa thrd1
+refer to the same thread. Otherwise, a non-zero value is returned,
+indicating that
+.Fa thrd0
+and
+.Fa thrd1
+are different threads.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/thrd_exit.3c b/usr/src/man/man3c/thrd_exit.3c
new file mode 100644
index 0000000000..3dcf682cd9
--- /dev/null
+++ b/usr/src/man/man3c/thrd_exit.3c
@@ -0,0 +1,64 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 13, 2015"
+.Dt THRD_EXIT 3C
+.Os
+.Sh NAME
+.Nm thrd_exit
+.Nd terminate a thread
+.Sh SYNOPSIS
+.In threads.h
+.Ft "_Noreturn void"
+.Fo thrd_exit
+.Fa "int res"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn thrd_exit
+function terminates the calling thread, in a similar way that
+.Xr exit 3C
+terminates the calling process. If the calling thread has not been
+detached, then the exit status information provided in
+.Fa res
+is saved and can be retrieved by the use of the
+.Xr thrd_join 3C
+function.
+.Pp
+When the thread exits, all signals will be blocked and various
+destructors and clean up handlers will be called, such as those
+registered with
+.Xr tss_create 3C .
+The act of thread termination does not cause any process-wide resources,
+such as mutexes and file descriptors to be released.
+.Pp
+If a thread, other than the thread in which
+.Fn main
+was first invoked returns from its starting routine, it will implicitly
+call
+.Fn thrd_exit
+and set the return value to be its exit status.
+.Sh RETURN VALUES
+The
+.Fn thrd_exit
+function does not return, the calling thread is terminated.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr pthread_exit 3C ,
+.Xr thr_exit 3C ,
+.Xr attributes 5 ,
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/thrd_join.3c b/usr/src/man/man3c/thrd_join.3c
new file mode 100644
index 0000000000..d2cb8c83ea
--- /dev/null
+++ b/usr/src/man/man3c/thrd_join.3c
@@ -0,0 +1,81 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 13, 2015"
+.Dt THRD_JOIN 3C
+.Os
+.Sh NAME
+.Nm thrd_join
+.Nd wait for thread termination
+.Sh SYNOPSIS
+.In threads.h
+.Ft int
+.Fo thrd_join
+.Fa "thrd_t thrd"
+.Fa "int *res"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn thrd_join
+function suspends the exection of the current thread and waits for the
+thread indicated by
+.Fa thrd
+to terminate and stores the exit status, as set by a call to
+.Xr thrd_exit 3C ,
+for that thread in
+.Fa res ,
+if
+.Fa res
+is non-null. The
+.Fa thrd
+argument must be a member of the current process and it cannot be
+detached. If
+.Fa thrd
+has already terminated and another caller has not called
+.Fn thrd_join
+then the exit status will be returned to the caller without blocking
+execution of the thread.
+.Pp
+If multiple threads call
+.Fn thrd_join
+on the same thread, then both will be suspended until that thread
+terminates; however, only one thread will return successfully and obtain
+the actual status and the other will instead return with an error.
+.Pp
+For additional information on the thread joining interfaces supported by
+the system, see
+.Xr pthread_join 3C
+and
+.Xr thr_join 3C .
+.Sh RETURN_VALUES
+Upon successful completion, the
+.Fn thrd_join
+function returns
+.Sy thrd_success
+and if
+.Fa res
+is a non-null pointer, it will be filled in with the exit status of
+.Xr thrd .
+If an error occurs,
+.Sy thrd_error
+will be returned.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr pthread_join 3C ,
+.Xr thrd_create 3C ,
+.Xr thrd_detach 3C ,
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/thrd_yield.3c b/usr/src/man/man3c/thrd_yield.3c
new file mode 100644
index 0000000000..a37ca39007
--- /dev/null
+++ b/usr/src/man/man3c/thrd_yield.3c
@@ -0,0 +1,38 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 11, 2015"
+.Dt THRD_YIELD 3C
+.Os
+.Sh NAME
+.Nm thrd_yield
+.Nd yield the CPU to another thread
+.Sh SYNOPSIS
+.In threads.h
+.Ft void
+.Fo thrd_yield
+.Fa void
+.Fc
+.Sh DESCRIPTION
+The
+.Fn thrd_yield
+function causes the current thread to yield the CPU and allow other
+threads with the same or greater priority to run.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-Level
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr yield 2 ,
+.Xr attributes 5 ,
+.Xr threads 5
diff --git a/usr/src/man/man3c/timespec_get.3c b/usr/src/man/man3c/timespec_get.3c
new file mode 100644
index 0000000000..7ae55f7b55
--- /dev/null
+++ b/usr/src/man/man3c/timespec_get.3c
@@ -0,0 +1,81 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Mar 25, 2016"
+.Dt TIMESPEC_GET 3C
+.Os
+.Sh NAME
+.Nm timespec_get
+.Nd get time information
+.Sh SYNOPSIS
+.In time.h
+.Ft int
+.Fo timespec_get
+.Fa "struct timespec *ts"
+.Fa "int base"
+.Fc
+.Sh DESCRIPTION
+The
+.Fn timespec_get
+function provides access nanosecond resolution time. The
+meaning and source of time is defined by the
+.Fa base
+argument. The following values are defined for
+.Fa base :
+.Bl -tag -width Ds
+.It Sy TIME_UTC
+Obtain the current time of day from the realtime clock on the system. It
+represents the amount of time in second and nanoseconds since the Epoch.
+This is logically equivalent to calling
+.Xr clock_gettime 3C
+with
+.Sy CLOCK_REALTIME .
+.El
+.Pp
+For the definition of the
+.Sy timespec
+structure, see
+.Xr time.h 3HEAD .
+.Sh RETURN VALUES
+Upon successful completion, the
+.Fn timespec_get
+function returns the passed in value of
+.Fa base .
+Otherwise,
+.Sy 0
+is returned to represent an error.
+.Sh ERRORS
+Unlike other functions, the
+.Fn timespec_get
+function is not defined to set
+.Sy errno .
+However, the
+.Fn timespec_get
+function will fail if:
+.Bl -bullet -offset indent
+.It
+The value of
+.Fa base
+does not refer to a known time specification.
+.It
+There was an error obtaining the time for
+.Fa base .
+.El
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr clock_gettime 3C ,
+.Xr time.h 3HEAD ,
+.Xr attributes 5
diff --git a/usr/src/man/man3c/tss.3c b/usr/src/man/man3c/tss.3c
new file mode 100644
index 0000000000..37ae52bd97
--- /dev/null
+++ b/usr/src/man/man3c/tss.3c
@@ -0,0 +1,151 @@
+.\"
+.\" This file and its contents are supplied under the terms of the
+.\" Common Development and Distribution License ("CDDL"), version 1.0.
+.\" You may only use this file in accordance with the terms of version
+.\" 1.0 of the CDDL.
+.\"
+.\" A full copy of the text of the CDDL should have accompanied this
+.\" source. A copy of the CDDL is also available via the Internet at
+.\" http://www.illumos.org/license/CDDL.
+.\"
+.\"
+.\" Copyright 2016 Joyent, Inc.
+.\"
+.Dd "Jan 11, 2015"
+.Dt TSS 3C
+.Os
+.Sh NAME
+.Nm tss ,
+.Nm tss_create ,
+.Nm tss_destroy ,
+.Nm tss_get ,
+.Nm tss_set
+.Nd thread-specific storage
+.Sh SYNOPSIS
+.In threads.h
+.Vt "typedef void (*tss_dtor_t)(void *);"
+.Ft int
+.Fo tss_create
+.Fa "tss_t *key"
+.Fa "tss_dtor_t dtor"
+.Fc
+.Ft void
+.Fo tss_delete
+.Fa "tss_t key"
+.Fc
+.Ft void *
+.Fo tss_get
+.Fa "tss_t key"
+.Fc
+.Ft int
+.Fo tss_set
+.Fa "tss_t key"
+.Fa "void *val"
+.Fc
+.Sh DESCRIPTION
+The
+.Sy tss
+family of functions create, get, set, and destroy thread-specific
+storage.
+.Ss Creating and Destorying Thread-Specific Storage
+The
+.Fn tss_create
+function creates a new thread-specific data key. The key space is opaque
+and global to all threads in the process. Each thread has its own
+value-space which can be mainpulated with the
+.Fn tss_get
+and
+.Fn tss_set
+functions. A given key persists until
+.Fn tss_destroy
+is called.
+.Pp
+When a key is created, the value
+.Dv NULL
+is associated with all current threads. When a thread is created, the
+value
+.Dv NULL
+is assigned as the value for the entire key-space.
+.Pp
+A key may optionally be created with a destructor function
+.Fa dtor .
+The function
+.Fa dtor
+will run when the thread exits (see
+.Xr thrd_exit 3C )
+if the value for the key is not
+.Dv NULL .
+The key space's destructors may be run in any order. When the destructor
+is run due to a thread exiting, all signals will be blocked.
+.Pp
+The
+.Fn tss_delete
+function deletes the key identify by
+.Fa key
+from the global name-space. When a key is deleted, no registered
+destructor is called, it is up to the calling program to free any
+storage that was associated with
+.Fa key
+across all threads. Because of this propety, it is legal to call
+.Fn tss_delete
+from inside a destructor. Any destructors that had been assocaited with
+.Fa key
+will no longer be called when a thread terminates.
+.Ss Obtaining Values
+The
+.Fn tss_get
+function may be used to obtain the value associated with
+.Fa key
+for the calling thread. Note that if the calling thread has never set a
+value, then it will receive the default value,
+.Dv NULL .
+.Fn tss_get
+may be called from a tss destructor.
+.Ss Setting Values
+The
+.Fn tss_set
+function sets the value of the key
+.Fa key
+for the callling thread to
+.Fa value ,
+which may be obtained by subsequent calls to
+.Fa tss_get .
+To remove a value for a specific thread, one may pass
+.Dv NULL
+in as
+.Fa value .
+Changing the value of a key with
+.Fn tss_set
+does not cause any destructors to be invoked. This means that
+.Fn tss_set
+may be used in the context of a destructor, but special care must be
+taken to avoid leaking storage or causing an infinite loop.
+.Sh RETURN VALUES
+Upon successful completion, the
+.Fn tss_create
+and
+.Fn tss_set
+functions return
+.Sy thrd_success .
+Otherwise, they return
+.Sy thrd_error
+to indicate that an error occurred.
+.Pp
+Upon successful completion, the
+.Fn tss_get
+function returns the thread-specific value associated with the given
+.Fa key .
+If no thread-specific value is associated with the key or an invalid key
+was passed in, then
+.Dv NULL
+is returned.
+.Sh INTERFACE STABILITY
+.Sy Standard
+.Sh MT-LEVEL
+.Sy MT-Safe
+.Sh SEE ALSO
+.Xr pthread_getspecific 3C ,
+.Xr pthread_key_create 3C ,
+.Xr pthread_key_delete 3C ,
+.Xr pthread_setspecific 3C ,
+.Xr attributes 5
diff --git a/usr/src/man/man3head/assert.h.3head b/usr/src/man/man3head/assert.h.3head
index 864cb09e4f..3f8c8e68c6 100644
--- a/usr/src/man/man3head/assert.h.3head
+++ b/usr/src/man/man3head/assert.h.3head
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2016 Joyent, Inc.
.\" Copyright (c) 2001, The IEEE and The Open Group. All Rights Reserved. Portions Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved.>
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,7 +8,7 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH ASSERT.H 3HEAD "Sep 10, 2004"
+.TH ASSERT.H 3HEAD "Jan 14, 2015"
.SH NAME
assert.h, assert \- verify program assertion
.SH SYNOPSIS
@@ -17,7 +18,6 @@ assert.h, assert \- verify program assertion
.fi
.SH DESCRIPTION
-.sp
.LP
The <\fBassert.h\fR> header defines the \fBassert()\fR macro. It refers to the
macro \fBNDEBUG\fR which is not defined in the header. If \fBNDEBUG\fR is
@@ -42,9 +42,14 @@ The \fBassert()\fR macro is redefined according to the current state of
The \fBassert()\fR macro is implemented as a macro, not as a function. If the
macro definition is suppressed in order to access an actual function, the
behavior is undefined.
-.SH ATTRIBUTES
.sp
.LP
+The <\fBassert.h\fR> header also defines the \fBstatic_assert()\fR macro. This
+macros is similar to \fBassert()\fR; however, while \fBassert()\fR is used at
+program execution time, \fBstatic_assert()\fR is evaluated and checked by the
+compiler at compilation-time.
+.SH ATTRIBUTES
+.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -59,6 +64,5 @@ Interface Stability Standard
.TE
.SH SEE ALSO
-.sp
.LP
\fBassert\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3head/stddef.h.3head b/usr/src/man/man3head/stddef.h.3head
index 96d56558d3..a06493bf39 100644
--- a/usr/src/man/man3head/stddef.h.3head
+++ b/usr/src/man/man3head/stddef.h.3head
@@ -1,4 +1,5 @@
'\" te
+.\" Copyright 2016, Joyent, Inc.
.\" Copyright (c) 2001, The IEEE and The Open Group. All Rights Reserved. Portions Copyright (c) 2004, Sun Microsystems, Inc. All Rights Reserved.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
@@ -7,7 +8,7 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH STDDEF.H 3HEAD "Sep 10, 2004"
+.TH STDDEF.H 3HEAD "Jan 14, 2015"
.SH NAME
stddef.h, stddef \- standard type definitions
.SH SYNOPSIS
@@ -17,7 +18,6 @@ stddef.h, stddef \- standard type definitions
.fi
.SH DESCRIPTION
-.sp
.LP
The <\fBstddef.h\fR> header defines the following macros:
.sp
@@ -77,6 +77,18 @@ Unsigned integer type of the result of the \fBsizeof\fR operator.
.RE
.sp
+.ne 2
+.na
+.B max_align_t
+.ad
+.RS 13n
+A type that represents the maximum alignment supported by the platform.
+The type may or may not be an integer type, it may or may not be signed,
+no assumptions should be made, other than that it has the maximum
+fundamental alignment of the platform.
+.RE
+
+.sp
.LP
The implementation supports one or more programming environments in which the
widths of \fBptrdiff_t\fR, \fBsize_t\fR, and \fBwchar_t\fR are no greater than
@@ -84,7 +96,6 @@ the width of type \fBlong\fR. The names of these programming environments can
be obtained using the \fBconfstr\fR(3C) function or the \fBgetconf\fR(1)
utility.
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -100,7 +111,6 @@ Interface Stability Standard
.TE
.SH SEE ALSO
-.sp
.LP
\fBgetconf\fR(1), \fBconfstr\fR(3C), \fBtypes.h\fR(3HEAD),
\fBwchar.h\fR(3HEAD), \fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man3head/time.h.3head b/usr/src/man/man3head/time.h.3head
index b739369f1e..47c349e280 100644
--- a/usr/src/man/man3head/time.h.3head
+++ b/usr/src/man/man3head/time.h.3head
@@ -1,6 +1,7 @@
'\" te
.\" Copyright (c) 2001, The IEEE and The Open Group. All Rights Reserved.
.\" Portions Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2016 Joyent, Inc.
.\" Sun Microsystems, Inc. gratefully acknowledges The Open Group for permission to reproduce portions of its copyrighted documentation. Original documentation from The Open Group can be obtained online at
.\" http://www.opengroup.org/bookstore/.
.\" The Institute of Electrical and Electronics Engineers and The Open Group, have given us permission to reprint portions of their documentation. In the following statement, the phrase "this text" refers to portions of the system documentation. Portions of this text are reprinted and reproduced in electronic form in the Sun OS Reference Manual, from IEEE Std 1003.1, 2004 Edition, Standard for Information Technology -- Portable Operating System Interface (POSIX), The Open Group Base Specifications Issue 6, Copyright (C) 2001-2004 by the Institute of Electrical and Electronics Engineers, Inc and The Open Group. In the event of any discrepancy between these versions and the original IEEE and The Open Group Standard, the original IEEE and The Open Group Standard is the referee document. The original Standard can be obtained online at http://www.opengroup.org/unix/online.html.
@@ -18,7 +19,6 @@ time.h, time \- time types
.fi
.SH DESCRIPTION
-.sp
.LP
The <\fBtime.h\fR> header declares the structure \fBtm\fR, which includes the
following members:
@@ -143,6 +143,16 @@ implementation-defined. See \fBclock_settime\fR(3C).
.RE
.sp
+.ne 2
+.na
+\fB\fBTIME_UTC\fR\fR
+.ad
+.RS 19n
+The identifier for the system-wide realtime clock with no time zone
+translation. Used in \fBtimespec_get\fR().
+.RE
+
+.sp
.LP
The \fBclock_t\fR, \fBsize_t\fR, \fBtime_t\fR, \fBclockid_t\fR, and
\fBtimer_t\fR types are defined as described in <\fBsys/types.h\fR>. See
@@ -172,7 +182,6 @@ extern char *tzname[];
Inclusion of the <\fBtime.h\fR> header can make visible all symbols from the
<\fBsignal.h\fR> header.
.SH USAGE
-.sp
.LP
The range [0,60] for \fBtm_sec\fR allows for the occasional leap second.
.sp
@@ -185,7 +194,6 @@ To obtain the number of clock ticks per second returned by the \fBtimes()\fR
function, applications should call \fBsysconf(_SC_CLK_TCK)\fR. See
\fBtimes\fR(2) and \fBsysconf\fR(3C).
.SH ATTRIBUTES
-.sp
.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -203,10 +211,10 @@ Standard See \fBstandards\fR(5).
.TE
.SH SEE ALSO
-.sp
.LP
\fBtime\fR(2), \fButime\fR(2), \fBclock\fR(3C), \fBctime\fR(3C),
-\fBdifftime\fR(3C), \fBgetdate\fR(3C), \fBmktime\fR(3C), \fBstrftime\fR(3C),
-\fBstrptime\fR(3C), \fBtypes.h\fR(3HEAD), \fBclock_settime\fR(3C),
-\fBnanosleep\fR(3C), \fBtimer_create\fR(3C), \fBtimer_delete\fR(3C),
-\fBtimer_settime\fR(3C), \fBattributes\fR(5), \fBstandards\fR(5)
+\fBdifftime\fR(3C), \fBgetdate\fR(3C), \fBmktime\fR(3C),
+\fBstrftime\fR(3C), \fBstrptime\fR(3C), \fBtypes.h\fR(3HEAD),
+\fBclock_settime\fR(3C), \fBnanosleep\fR(3C), \fBtimer_create\fR(3C),
+\fBtimer_delete\fR(3C), \fBtimer_settime\fR(3C), \fBtimespec_get\fR(3C),
+\fBattributes\fR(5), \fBstandards\fR(5)
diff --git a/usr/src/man/man5/standards.5 b/usr/src/man/man5/standards.5
index b1b1e2a730..766890ea52 100644
--- a/usr/src/man/man5/standards.5
+++ b/usr/src/man/man5/standards.5
@@ -3,13 +3,12 @@
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH STANDARDS 5 "Nov 08, 2014"
+.TH STANDARDS 5 "Jan 11, 2015"
.SH NAME
standards, ANSI, C, C++, ISO, POSIX, POSIX.1, POSIX.2, SUS, SUSv2, SUSv3, SVID,
SVID3, XNS, XNS4, XNS5, XPG, XPG3, XPG4, XPG4v2 \- standards and specifications
supported by Solaris
.SH DESCRIPTION
-.sp
.LP
Solaris 10 supports IEEE Std 1003.1 and IEEE Std 1003.2, commonly known as
POSIX.1 and POSIX.2, respectively. The following table lists each version of
@@ -126,7 +125,6 @@ When \fBSun Studio C++ Compiler 5.6\fR is installed, Solaris releases 2.5.1
through 10 support ISO/IEC 14882:1998 Programming Languages - C++. Unsupported
features of that standard are described in the compiler README file.
.SS "Utilities"
-.sp
.LP
If the behavior required by POSIX.2, POSIX.2a, XPG4, SUS, or SUSv2 conflicts
with historical Solaris utility behavior, the original Solaris version of the
@@ -246,7 +244,6 @@ other directories containing binaries needed by the application
.RE
.SS "Feature Test Macros"
-.sp
.LP
Feature test macros are used by applications to indicate additional sets of
features that are desired beyond those specified by the C standard. If an
@@ -260,12 +257,10 @@ with access to all interfaces and headers not in conflict with the specified
standard. The application must define \fB__EXTENSIONS__\fR either on the
compile command line or within the application source files.
.SS "1989 ANSI C, 1990 ISO C, 1999 ISO C"
-.sp
.LP
No feature test macros need to be defined to indicate that an application is a
conforming C application.
.SS "ANSI/ISO C++"
-.sp
.LP
ANSI/ISO C++ does not define any feature test macros. If the standard C++
announcement macro \fB__cplusplus\fR is predefined to value 199711 or greater,
@@ -281,7 +276,6 @@ test macros such as \fB_POSIX_SOURCE\fR, \fB_POSIX_C_SOURCE\fR, and
\fB_XOPEN_SOURCE\fR can result in compilation errors due to conflicting
requirements of standard C++ and those specifications.
.SS "POSIX"
-.sp
.LP
Applications that are intended to be conforming POSIX.1 applications must
define the feature test macros specified by the standard before including any
@@ -310,13 +304,11 @@ POSIX.1-2001 \fB_POSIX_C_SOURCE=200112L\fR
.TE
.SS "SVID3"
-.sp
.LP
The SVID3 specification does not specify any feature test macros to indicate
that an application is written to meet SVID3 requirements. The SVID3
specification was written before the C standard was completed.
.SS "X/Open CAE"
-.sp
.LP
To build or compile an application that conforms to one of the X/Open CAE
specifications, use the following guidelines. Applications need not set the
@@ -372,7 +364,6 @@ The application must define \fB_XOPEN_SOURCE=600\fR.
.RE
.SS "Compilation"
-.sp
.LP
A POSIX.1 (1988-1996)-, XPG4-, SUS-, or SUSv2-conforming implementation must
include an ANSI X3.159-1989 (ANSI C Language) standard-conforming compilation
@@ -423,6 +414,9 @@ _________________________________________________________________________
_________________________________________________________________________
1999 ISO C c99 none
_________________________________________________________________________
+2011 ISO C c11 none
+ gcc -stdc=c11
+_________________________________________________________________________
SVID3 cc -Xt -xc99=none none
_________________________________________________________________________
POSIX.1-1990 c89 _POSIX_SOURCE
@@ -479,7 +473,6 @@ c99 $(getconf POSIX_V6_LP64_OFF64_CFLAGS) -D_XOPEN_SOURCE=600 \e
.in -2
.SS "SUSv3"
-.sp
.ne 2
.na
\fB\fBc99\fR\fR
@@ -489,7 +482,6 @@ c99 $(getconf POSIX_V6_LP64_OFF64_CFLAGS) -D_XOPEN_SOURCE=600 \e
.RE
.SH SEE ALSO
-.sp
.LP
\fBcsh\fR(1), \fBksh\fR(1), \fBsh\fR(1), \fBexec\fR(2), \fBsysconf\fR(3C),
\fBsystem\fR(3C), \fBenviron\fR(5), \fBlf64\fR(5)
diff --git a/usr/src/man/man5/threads.5 b/usr/src/man/man5/threads.5
index d60037ca9a..5d882e7d45 100644
--- a/usr/src/man/man5/threads.5
+++ b/usr/src/man/man5/threads.5
@@ -1,16 +1,17 @@
'\" te
.\" Copyright (c) 2008, Sun Microsystems, Inc. All Rights Reserved.
+.\" Copyright 2016 Joyent, Inc.
.\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License"). You may not use this file except in compliance with the License.
.\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing. See the License for the specific language governing permissions and limitations under the License.
.\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
-.TH THREADS 5 "Nov 11, 2008"
+.TH THREADS 5 "Mar 27, 2016"
.SH NAME
-threads, pthreads \- POSIX pthreads and Solaris threads concepts
+threads, pthreads \- POSIX pthreads, c11, and illumos threads concepts
.SH SYNOPSIS
.SS "POSIX"
.LP
.nf
-cc -mt [ \fIflag\fR... ] \fIfile\fR... [ -lrt \fIlibrary\fR... ]
+gcc -D_REENTRANT [ \fIflag\fR... ] \fIfile\fR... [ \fIlibrary\fR... ]
.fi
.LP
@@ -18,10 +19,21 @@ cc -mt [ \fIflag\fR... ] \fIfile\fR... [ -lrt \fIlibrary\fR... ]
#include <pthread.h>
.fi
-.SS "Solaris"
+.SS "C11"
.LP
.nf
-cc -mt [ \fIflag\fR... ] \fIfile\fR... [ \fIlibrary\fR... ]
+gcc -std=c11 -D_REENTRANT [ \fIflag\fR... ] \fIfile\fR... [ \fIlibrary\fR... ]
+.fi
+
+.LP
+.nf
+#include <threads.h>
+.fi
+
+.SS "illumos"
+.LP
+.nf
+gcc -D_REENTRANT [ \fIflag\fR... ] \fIfile\fR... [ \fIlibrary\fR... ]
.fi
.LP
@@ -35,26 +47,52 @@ cc -mt [ \fIflag\fR... ] \fIfile\fR... [ \fIlibrary\fR... ]
.fi
.SH DESCRIPTION
+.LP
+A thread is an independent source of execution within a process. Every process
+is created with a single thread, which calls the
+.B main
+function. A process may have multiple threads, all of which are scheduled
+independently by the system and may run concurrently. Threads within a process
+all use the same address space and as a result can access all data in the
+process; however, each thread is created with its own attributes and its own
+stack. When a thread is created, it inherits the signal mask of the thread which
+created it, but it has no pending signals.
+.sp
+.LP
+All threads of execution have their own, independent life time, though it is
+ultimately bounded by the life time of the process. If the process terminates
+for any reason, whether due to a call to \fBexit\fR(3C), the receipt of a fatal
+signal, or some other reason, then all threads within the process are
+terminated. Threads may themselves exit and status information of them may be
+obtained, for more information, see the \fBpthread_detach\fR(3C),
+\fBpthread_join\fR(3C), and \fBpthread_exit\fR(3C) functions, and their
+equivalents as described in the tables later on in the manual.
.sp
.LP
-POSIX and Solaris threads each have their own implementation within
-\fBlibc\fR(3LIB). Both implementations are interoperable, their functionality
+Most hardware platforms do not have any special synchronization for data objects
+which may be accessed concurrently from multiple threads of execution. To avoid
+such problems, programs may use atomic operations (see \fBatomic_ops\fR(3C)) and
+locking primitives, such as mutexes, readers/writer locks, condition variables,
+and semaphores. Note, that depending on the hardware platform, memory
+synchronization may be necesary, for more information, see \fBmembar_ops\fR(3C).
+.LP
+POSIX, C11, and illumos threads each have their own implementation within
+\fBlibc\fR(3LIB). All implementations are interoperable, their functionality
similar, and can be used within the same application. Only POSIX threads are
-guaranteed to be fully portable to other POSIX-compliant environments. POSIX
-and Solaris threads require different source, include files and linking
-libraries. See \fBSYNOPSIS\fR.
+guaranteed to be fully portable to other POSIX-compliant environments. C11
+threads are an optional part of ISO C11 and may not exist on every ISO C11
+platform. POSIX, C11, and illumos threads require different source and include
+files. See \fBSYNOPSIS\fR.
.SS "Similarities"
-.sp
.LP
-Most of the POSIX and Solaris threading functions have counterparts with each
+Most of the POSIX and illumos threading functions have counterparts with each
other. POSIX function names, with the exception of the semaphore names, have a
-"\fBpthread\fR" prefix. Function names for similar POSIX and Solaris functions
-have similar endings. Typically, similar POSIX and Solaris functions have the
+"\fBpthread\fR" prefix. Function names for similar POSIX and illumos functions
+have similar endings. Typically, similar POSIX and illumos functions have the
same number and use of arguments.
.SS "Differences"
-.sp
.LP
-POSIX pthreads and Solaris threads differ in the following ways:
+POSIX pthreads and illumos threads differ in the following ways:
.RS +4
.TP
.ie t \(bu
@@ -90,278 +128,267 @@ POSIX pthreads allow for clean-up handlers for \fBfork\fR(2) calls.
.TP
.ie t \(bu
.el o
-Solaris threads can be suspended and continued.
+illumos threads can be suspended and continued.
.RE
.RS +4
.TP
.ie t \(bu
.el o
-Solaris threads implement daemon threads, for whose demise the process does not
+illumos threads implement daemon threads, for whose demise the process does not
wait.
.RE
-.SH FUNCTION COMPARISON
+.SS "Comparison to C11 Threads"
+.LP
+C11 threads are not as functional as either POSIX or illumos threads. C11
+threads only support intra-process locking and do not have any form of
+readers/writer locking or semaphores. In general, POSIX threads will be more
+portable than C11 threads, all POSIX-compliant systems support pthreads;
+however, not all C environments support C11 Threads.
.sp
.LP
-The following table compares the POSIX pthreads and Solaris threads functions.
-When a comparable interface is not available either in POSIX pthreads or
-Solaris threads, a hyphen (\fB-\fR) appears in the column.
+In addition to lacking other common synchronization primitives, the ISO/IEC
+standard for C11 threads does not have rich error semantics. In an effort to not
+extend the set of error numbers standardized in ISO/IEC C11, none of the
+routines set errno and instead multiple distinguishable errors, aside from the
+equivalent to ENOMEM and EBUSY, are all squashed into one. As such, users of the
+platform are encouraged to use POSIX threads, unless a portability concern
+dictates otherwise.
+
+.SH FUNCTION COMPARISON
+.LP
+The following table compares the POSIX pthreads, C11 threads, and illumos
+threads functions. When a comparable interface is not available either in POSIX
+pthreads, C11 threads or illumos threads, a hyphen (\fB-\fR) appears in the
+column.
.SS "Functions Related to Creation"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_create()\fR \fBthr_create()\fR
-\fBpthread_attr_init()\fR \fB-\fR
-\fBpthread_attr_setdetachstate()\fR \fB-\fR
-\fBpthread_attr_getdetachstate()\fR \fB-\fR
-\fBpthread_attr_setinheritsched()\fR \fB-\fR
-\fBpthread_attr_getinheritsched()\fR \fB-\fR
-\fBpthread_attr_setschedparam()\fR \fB-\fR
-\fBpthread_attr_getschedparam()\fR \fB-\fR
-\fBpthread_attr_setschedpolicy()\fR \fB-\fR
-\fBpthread_attr_getschedpolicy()\fR \fB-\fR
-\fBpthread_attr_setscope()\fR \fB-\fR
-\fBpthread_attr_getscope()\fR \fB-\fR
-\fBpthread_attr_setstackaddr()\fR \fB-\fR
-\fBpthread_attr_getstackaddr()\fR \fB-\fR
-\fBpthread_attr_setstacksize()\fR \fB-\fR
-\fBpthread_attr_getstacksize()\fR \fB-\fR
-\fBpthread_attr_getguardsize()\fR \fB-\fR
-\fBpthread_attr_setguardsize()\fR \fB-\fR
-\fBpthread_attr_destroy()\fR \fB-\fR
-\fB-\fR \fBthr_min_stack()\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_create()\fR \fBthr_create()\fR \fBthrd_create()\fR
+\fBpthread_attr_init()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_setdetachstate()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_getdetachstate()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_setinheritsched()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_getinheritsched()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_setschedparam()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_getschedparam()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_setschedpolicy()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_getschedpolicy()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_setscope()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_getscope()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_setstackaddr()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_getstackaddr()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_setstacksize()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_getstacksize()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_getguardsize()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_setguardsize()\fR \fB-\fR \fB-\fR
+\fBpthread_attr_destroy()\fR \fB-\fR \fB-\fR
+\fB-\fR \fBthr_min_stack()\fR \fB-\fR
.TE
.SS "Functions Related to Exit"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_exit()\fR \fBthr_exit()\fR
-\fBpthread_join()\fR \fBthr_join()\fR
-\fBpthread_detach()\fR \fB-\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_exit()\fR \fBthr_exit()\fR \fBthrd_exit()\fR
+\fBpthread_join()\fR \fBthr_join()\fR \fBthrd_join()\fR
+\fBpthread_detach()\fR \fB-\fR \fBthrd_detach()\fR
.TE
.SS "Functions Related to Thread Specific Data"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_key_create()\fR \fBthr_keycreate()\fR
-\fBpthread_setspecific()\fR \fBthr_setspecific()\fR
-\fBpthread_getspecific()\fR \fBthr_getspecific()\fR
-\fBpthread_key_delete()\fR \fB-\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_key_create()\fR \fBthr_keycreate()\fR \fBtss_create()\fR
+\fBpthread_setspecific()\fR \fBthr_setspecific()\fR \fBtss_set()\fR
+\fBpthread_getspecific()\fR \fBthr_getspecific()\fR \fBtss_get()\fR
+\fBpthread_key_delete()\fR \fB-\fR \fBtss_delete()\fR
.TE
.SS "Functions Related to Signals"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_sigmask()\fR \fBthr_sigsetmask()\fR
-\fBpthread_kill()\fR \fBthr_kill()\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_sigmask()\fR \fBthr_sigsetmask()\fR \fB-\fR
+\fBpthread_kill()\fR \fBthr_kill()\fR \fB-\fR
.TE
.SS "Functions Related to IDs"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_self()\fR \fBthr_self()\fR
-\fBpthread_equal()\fR \fB-\fR
-\fB-\fR \fBthr_main()\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBc11\fR
+\fBpthread_self()\fR \fBthr_self()\fR \fBthrd_current()\fR
+\fBpthread_equal()\fR \fB-\fR \fBthrd_equal()\fR
+\fB-\fR \fBthr_main()\fR \fB-\fR
.TE
.SS "Functions Related to Scheduling"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fB-\fR \fBthr_yield()\fR
-\fB-\fR \fBthr_suspend()\fR
-\fB-\fR \fBthr_continue()\fR
-\fBpthread_setconcurrency()\fR \fBthr_setconcurrency()\fR
-\fBpthread_getconcurrency()\fR \fBthr_getconcurrency()\fR
-\fBpthread_setschedparam()\fR \fBthr_setprio()\fR
-\fBpthread_setschedprio()\fR \fBthr_setprio()\fR
-\fBpthread_getschedparam()\fR \fBthr_getprio()\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fB-\fR \fBthr_yield()\fR \fBthrd_yield()\fR
+\fB-\fR \fBthr_suspend()\fR \fB-\fR
+\fB-\fR \fBthr_continue()\fR \fB-\fR
+\fBpthread_setconcurrency()\fR \fBthr_setconcurrency()\fR \fB-\fR
+\fBpthread_getconcurrency()\fR \fBthr_getconcurrency()\fR \fB-\fR
+\fBpthread_setschedparam()\fR \fBthr_setprio()\fR \fB-\fR
+\fBpthread_setschedprio()\fR \fBthr_setprio()\fR \fB-\fR
+\fBpthread_getschedparam()\fR \fBthr_getprio()\fR \fB-\fR
.TE
.SS "Functions Related to Cancellation"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_cancel()\fR \fB-\fR
-\fBpthread_setcancelstate()\fR \fB-\fR
-\fBpthread_setcanceltype()\fR \fB-\fR
-\fBpthread_testcancel()\fR \fB-\fR
-\fBpthread_cleanup_pop()\fR \fB-\fR
-\fBpthread_cleanup_push()\fR \fB-\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_cancel()\fR \fB-\fR \fB-\fR
+\fBpthread_setcancelstate()\fR \fB-\fR \fB-\fR
+\fBpthread_setcanceltype()\fR \fB-\fR \fB-\fR
+\fBpthread_testcancel()\fR \fB-\fR \fB-\fR
+\fBpthread_cleanup_pop()\fR \fB-\fR \fB-\fR
+\fBpthread_cleanup_push()\fR \fB-\fR \fB-\fR
.TE
.SS "Functions Related to Mutexes"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_mutex_init()\fR \fBmutex_init()\fR
-\fBpthread_mutexattr_init()\fR \fB-\fR
-\fBpthread_mutexattr_setpshared()\fR \fB-\fR
-\fBpthread_mutexattr_getpshared()\fR \fB-\fR
-\fBpthread_mutexattr_setprotocol()\fR \fB-\fR
-\fBpthread_mutexattr_getprotocol()\fR \fB-\fR
-\fBpthread_mutexattr_setprioceiling()\fR \fB-\fR
-\fBpthread_mutexattr_getprioceiling()\fR \fB-\fR
-\fBpthread_mutexattr_settype()\fR \fB-\fR
-\fBpthread_mutexattr_gettype()\fR \fB-\fR
-\fBpthread_mutexattr_setrobust()\fR \fB-\fR
-\fBpthread_mutexattr_getrobust()\fR \fB-\fR
-\fBpthread_mutexattr_destroy()\fR \fB-\fR
-\fBpthread_mutex_setprioceiling()\fR \fB-\fR
-\fBpthread_mutex_getprioceiling()\fR \fB-\fR
-\fBpthread_mutex_lock()\fR \fBmutex_lock()\fR
-\fBpthread_mutex_trylock()\fR \fBmutex_trylock()\fR
-\fBpthread_mutex_unlock()\fR \fBmutex_unlock()\fR
-\fBpthread_mutex_destroy()\fR \fBmutex_destroy()\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBc11\fR
+\fBpthread_mutex_init()\fR \fBmutex_init()\fR \fBmtx_init()\fR
+\fBpthread_mutexattr_init()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_setpshared()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_getpshared()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_setprotocol()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_getprotocol()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_setprioceiling()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_getprioceiling()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_settype()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_gettype()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_setrobust()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_getrobust()\fR \fB-\fR \fB-\fR
+\fBpthread_mutexattr_destroy()\fR \fB-\fR \fBmtx_destroy()\fR
+\fBpthread_mutex_setprioceiling()\fR \fB-\fR \fB-\fR
+\fBpthread_mutex_getprioceiling()\fR \fB-\fR \fB-\fR
+\fBpthread_mutex_lock()\fR \fBmutex_lock()\fR \fBmtx_lock()\fR
+\fBpthread_mutex_timedlock()\fR \fB-\fR \fBmtx_timedlock()\fR
+\fBpthread_mutex_trylock()\fR \fBmutex_trylock()\fR \fBmtx_trylock()\fR
+\fBpthread_mutex_unlock()\fR \fBmutex_unlock()\fR \fBmtx_unlcok()\fR
+\fBpthread_mutex_destroy()\fR \fBmutex_destroy()\fR \fBmtx_destroy()\fR
.TE
.SS "Functions Related to Condition Variables"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_cond_init()\fR \fBcond_init()\fR
-\fBpthread_condattr_init()\fR \fB-\fR
-\fBpthread_condattr_setpshared()\fR \fB-\fR
-\fBpthread_condattr_getpshared()\fR \fB-\fR
-\fBpthread_condattr_destroy()\fR \fB-\fR
-\fBpthread_cond_wait()\fR \fBcond_wait()\fR
-\fBpthread_cond_timedwait()\fR \fBcond_timedwait()\fR
-\fBpthread_cond_signal()\fR \fBcond_signal()\fR
-\fBpthread_cond_broadcast()\fR \fBcond_broadcast()\fR
-\fBpthread_cond_destroy()\fR \fBcond_destroy()\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_cond_init()\fR \fBcond_init()\fR \fBcnd_init()\fR
+\fBpthread_condattr_init()\fR \fB-\fR \fB-\fR
+\fBpthread_condattr_setpshared()\fR \fB-\fR \fB-\fR
+\fBpthread_condattr_getpshared()\fR \fB-\fR \fB-\fR
+\fBpthread_condattr_destroy()\fR \fB-\fR \fB-\fR
+\fBpthread_cond_wait()\fR \fBcond_wait()\fR \fBcnd_wait()\fR
+\fBpthread_cond_timedwait()\fR \fBcond_timedwait()\fR \fBcond_timedwait()\fR
+\fBpthread_cond_signal()\fR \fBcond_signal()\fR \fBcnd_signal()\fR
+\fBpthread_cond_broadcast()\fR \fBcond_broadcast()\fR \fBcnd_broadcast()\fR
+\fBpthread_cond_destroy()\fR \fBcond_destroy()\fR \fBcnd_destroy()\fR
.TE
.SS "Functions Related to Reader/Writer Locking"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_rwlock_init()\fR \fBrwlock_init()\fR
-\fBpthread_rwlock_rdlock()\fR \fBrw_rdlock()\fR
-\fBpthread_rwlock_tryrdlock()\fR \fBrw_tryrdlock()\fR
-\fBpthread_rwlock_wrlock()\fR \fBrw_wrlock()\fR
-\fBpthread_rwlock_trywrlock()\fR \fBrw_trywrlock()\fR
-\fBpthread_rwlock_unlock()\fR \fBrw_unlock()\fR
-\fBpthread_rwlock_destroy()\fR \fBrwlock_destroy()\fR
-\fBpthread_rwlockattr_init()\fR \fB-\fR
-\fBpthread_rwlockattr_destroy()\fR \fB-\fR
-\fBpthread_rwlockattr_getpshared()\fR \fB-\fR
-\fBpthread_rwlockattr_setpshared()\fR \fB-\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_rwlock_init()\fR \fBrwlock_init()\fR \fB-\fR
+\fBpthread_rwlock_rdlock()\fR \fBrw_rdlock()\fR \fB-\fR
+\fBpthread_rwlock_tryrdlock()\fR \fBrw_tryrdlock()\fR \fB-\fR
+\fBpthread_rwlock_wrlock()\fR \fBrw_wrlock()\fR \fB-\fR
+\fBpthread_rwlock_trywrlock()\fR \fBrw_trywrlock()\fR \fB-\fR
+\fBpthread_rwlock_unlock()\fR \fBrw_unlock()\fR \fB-\fR
+\fBpthread_rwlock_destroy()\fR \fBrwlock_destroy()\fR \fB-\fR
+\fBpthread_rwlockattr_init()\fR \fB-\fR \fB-\fR
+\fBpthread_rwlockattr_destroy()\fR \fB-\fR \fB-\fR
+\fBpthread_rwlockattr_getpshared()\fR \fB-\fR \fB-\fR
+\fBpthread_rwlockattr_setpshared()\fR \fB-\fR \fB-\fR
.TE
.SS "Functions Related to Semaphores"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBsem_init()\fR \fBsema_init()\fR
-\fBsem_open()\fR \fB-\fR
-\fBsem_close()\fR \fB-\fR
-\fBsem_wait()\fR \fBsema_wait()\fR
-\fBsem_trywait()\fR \fBsema_trywait()\fR
-\fBsem_post()\fR \fBsema_post()\fR
-\fBsem_getvalue()\fR \fB-\fR
-\fBsem_unlink()\fR \fB-\fR
-\fBsem_destroy()\fR \fBsema_destroy()\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBsem_init()\fR \fBsema_init()\fR \fB-\fR
+\fBsem_open()\fR \fB-\fR \fB-\fR
+\fBsem_close()\fR \fB-\fR \fB-\fR
+\fBsem_wait()\fR \fBsema_wait()\ \fB-\fR
+\fBsem_trywait()\fR \fBsema_trywait()\fR \fB-\fR
+\fBsem_post()\fR \fBsema_post()\fR \fB-\fR
+\fBsem_getvalue()\fR \fB-\fR \fB-\fR
+\fBsem_unlink()\fR \fB-\fR \fB-\fR
+\fBsem_destroy()\fR \fBsema_destroy()\fR \fB-\fR
.TE
.SS "Functions Related to fork(\|) Clean Up"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_atfork()\fR \fB-\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_atfork()\fR \fB-\fR \fB-\fR
.TE
.SS "Functions Related to Limits"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fBpthread_once()\fR \fB-\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fBpthread_once()\fR \fB-\fR \fBcall_once()\fR
.TE
.SS "Functions Related to Debugging"
-.sp
-.sp
.TS
-l l
-l l .
-\fBPOSIX\fR \fBSolaris\fR
-\fB-\fR \fBthr_stksegment()\fR
+l l l
+l l l .
+\fBPOSIX\fR \fBillumos\fR \fBC11\fR
+\fB-\fR \fBthr_stksegment()\fR \fB-\fR
.TE
.SH LOCKING
.SS "Synchronization"
-.sp
.LP
Multithreaded behavior is asynchronous, and therefore, optimized for
concurrent and parallel processing. As threads, always from within the same
process and sometimes from multiple processes, share global data with each
other, they are not guaranteed exclusive access to the shared data at any point
in time. Securing mutually exclusive access to shared data requires
-synchronization among the threads. Both POSIX and Solaris implement four
+synchronization among the threads. Both POSIX and illumos implement four
synchronization mechanisms: mutexes, condition variables, reader/writer locking
-(\fIoptimized frequent-read occasional-write mutex\fR), and semaphores.
+(\fIoptimized frequent-read occasional-write mutex\fR), and semaphores, where as
+C11 threads only implement two mechanisms: mutexes and condition variables.
.sp
.LP
Synchronizing multiple threads diminishes their concurrency. The coarser the
grain of synchronization, that is, the larger the block of code that is locked,
the lesser the concurrency.
.SS "MT \fBfork()\fR"
-.sp
.LP
If a threads program calls \fBfork\fR(2), it implicitly calls \fBfork1\fR(2),
which replicates only the calling thread. Should there be any outstanding
@@ -370,9 +397,8 @@ mutexes throughout the process, the application should call
\fBfork()\fR.
.SH SCHEDULING
.SS "POSIX Threads"
-.sp
.LP
-Solaris supports the following three POSIX scheduling policies:
+illumos supports the following three POSIX scheduling policies:
.sp
.ne 2
.na
@@ -409,7 +435,7 @@ process must have a effective user \fBID\fR of \fB0\fR.
.sp
.LP
-In addition to the POSIX-specified scheduling policies above, Solaris also
+In addition to the POSIX-specified scheduling policies above, illumos also
supports these scheduling policies:
.sp
.ne 2
@@ -441,26 +467,27 @@ Threads are scheduled according to the Fixed-Priority Class (FX) policy as
described in \fBpriocntl\fR(2).
.RE
-.SS "Solaris Threads"
-.sp
+.SS "illumos Threads"
.LP
Only scheduling policy supported is \fBSCHED_OTHER\fR, which is timesharing,
based on the \fBTS\fR scheduling class.
.SH ERRORS
-.sp
.LP
In a multithreaded application, \fBEINTR\fR can be returned from blocking
-system calls when another thread calls \fBforkall\fR(2).
+system calls when another thread calls \fBforkall\fR(2).
.SH USAGE
.SS "\fB-mt\fR compiler option"
-.sp
.LP
The \fB-mt\fR compiler option compiles and links for multithreaded code. It
compiles source files with \(mi\fBD_REENTRANT\fR and augments the set of
support libraries properly.
-.SH ATTRIBUTES
.sp
.LP
+Users of other compilers such as gcc and clang should manually set
+\(mi\fBD_REENTRANT\fR on the compilation line. There are no other libraries or
+flags necessary.
+.SH ATTRIBUTES
+.LP
See \fBattributes\fR(5) for descriptions of the following attributes:
.sp
@@ -475,7 +502,6 @@ MT-Level MT-Safe, Fork 1-Safe
.TE
.SH SEE ALSO
-.sp
.LP
\fBcrle\fR(1), \fBfork\fR(2), \fBpriocntl\fR(2), \fBlibpthread\fR(3LIB),
\fBlibrt\fR(3LIB), \fBlibthread\fR(3LIB), \fBpthread_atfork\fR(3C),
diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf
index 1e9a01fc0b..787395c361 100644
--- a/usr/src/pkg/manifests/system-header.mf
+++ b/usr/src/pkg/manifests/system-header.mf
@@ -453,6 +453,7 @@ file path=usr/include/iso/stdarg_iso.h
file path=usr/include/iso/stddef_iso.h
file path=usr/include/iso/stdio_c99.h
file path=usr/include/iso/stdio_iso.h
+file path=usr/include/iso/stdlib_c11.h
file path=usr/include/iso/stdlib_c99.h
file path=usr/include/iso/stdlib_iso.h
file path=usr/include/iso/string_iso.h
@@ -775,6 +776,7 @@ file path=usr/include/skein.h
file path=usr/include/smbios.h
file path=usr/include/spawn.h
$(i386_ONLY)file path=usr/include/stack_unwind.h
+file path=usr/include/stdalign.h
file path=usr/include/stdarg.h
file path=usr/include/stdbool.h
file path=usr/include/stddef.h
@@ -784,6 +786,7 @@ file path=usr/include/stdio_ext.h
file path=usr/include/stdio_impl.h
file path=usr/include/stdio_tag.h
file path=usr/include/stdlib.h
+file path=usr/include/stdnoreturn.h
file path=usr/include/storclass.h
file path=usr/include/string.h
file path=usr/include/strings.h
@@ -1622,6 +1625,7 @@ file path=usr/include/termio.h
file path=usr/include/termios.h
file path=usr/include/thread.h
file path=usr/include/thread_db.h
+file path=usr/include/threads.h
file path=usr/include/time.h
file path=usr/include/tiuser.h
file path=usr/include/tsol/label.h
diff --git a/usr/src/pkg/manifests/system-library.man3c.inc b/usr/src/pkg/manifests/system-library.man3c.inc
index 0142010ccb..e9d0bda783 100644
--- a/usr/src/pkg/manifests/system-library.man3c.inc
+++ b/usr/src/pkg/manifests/system-library.man3c.inc
@@ -20,6 +20,7 @@ file path=usr/share/man/man3c/__fbufsize.3c
file path=usr/share/man/man3c/_longjmp.3c
file path=usr/share/man/man3c/_stack_grow.3c
file path=usr/share/man/man3c/a64l.3c
+file path=usr/share/man/man3c/aligned_alloc.3c
file path=usr/share/man/man3c/abort.3c
file path=usr/share/man/man3c/abs.3c
file path=usr/share/man/man3c/addsev.3c
@@ -53,6 +54,7 @@ file path=usr/share/man/man3c/bsd_signal.3c
file path=usr/share/man/man3c/bsearch.3c
file path=usr/share/man/man3c/bstring.3c
file path=usr/share/man/man3c/btowc.3c
+file path=usr/share/man/man3c/call_once.3c
file path=usr/share/man/man3c/catgets.3c
file path=usr/share/man/man3c/catopen.3c
file path=usr/share/man/man3c/cfgetispeed.3c
@@ -63,6 +65,7 @@ file path=usr/share/man/man3c/clock_nanosleep.3c
file path=usr/share/man/man3c/clock_settime.3c
file path=usr/share/man/man3c/closedir.3c
file path=usr/share/man/man3c/closefrom.3c
+file path=usr/share/man/man3c/cnd.3c
file path=usr/share/man/man3c/cond_init.3c
file path=usr/share/man/man3c/confstr.3c
file path=usr/share/man/man3c/crypt.3c
@@ -244,6 +247,7 @@ file path=usr/share/man/man3c/mq_send.3c
file path=usr/share/man/man3c/mq_setattr.3c
file path=usr/share/man/man3c/mq_unlink.3c
file path=usr/share/man/man3c/msync.3c
+file path=usr/share/man/man3c/mtx.3c
file path=usr/share/man/man3c/mutex_init.3c
file path=usr/share/man/man3c/nanosleep.3c
file path=usr/share/man/man3c/ndbm.3c
@@ -357,6 +361,7 @@ file path=usr/share/man/man3c/puts.3c
file path=usr/share/man/man3c/putspent.3c
file path=usr/share/man/man3c/putws.3c
file path=usr/share/man/man3c/qsort.3c
+file path=usr/share/man/man3c/quick_exit.3c
file path=usr/share/man/man3c/raise.3c
file path=usr/share/man/man3c/rand.3c
file path=usr/share/man/man3c/random.3c
@@ -466,11 +471,19 @@ file path=usr/share/man/man3c/thr_sigsetmask.3c
file path=usr/share/man/man3c/thr_stksegment.3c
file path=usr/share/man/man3c/thr_suspend.3c
file path=usr/share/man/man3c/thr_yield.3c
+file path=usr/share/man/man3c/thrd_create.3c
+file path=usr/share/man/man3c/thrd_current.3c
+file path=usr/share/man/man3c/thrd_detach.3c
+file path=usr/share/man/man3c/thrd_equal.3c
+file path=usr/share/man/man3c/thrd_exit.3c
+file path=usr/share/man/man3c/thrd_join.3c
+file path=usr/share/man/man3c/thrd_yield.3c
file path=usr/share/man/man3c/timer_create.3c
file path=usr/share/man/man3c/timer_delete.3c
file path=usr/share/man/man3c/timer_settime.3c
file path=usr/share/man/man3c/timeradd.3c
file path=usr/share/man/man3c/timerfd_create.3c
+file path=usr/share/man/man3c/timespec_get.3c
file path=usr/share/man/man3c/tmpfile.3c
file path=usr/share/man/man3c/tmpnam.3c
file path=usr/share/man/man3c/toascii.3c
@@ -480,6 +493,7 @@ file path=usr/share/man/man3c/towlower.3c
file path=usr/share/man/man3c/towupper.3c
file path=usr/share/man/man3c/truncate.3c
file path=usr/share/man/man3c/tsearch.3c
+file path=usr/share/man/man3c/tss.3c
file path=usr/share/man/man3c/ttyname.3c
file path=usr/share/man/man3c/ttyslot.3c
file path=usr/share/man/man3c/u8_strcmp.3c
@@ -561,6 +575,7 @@ link path=usr/share/man/man3c/ascftime.3c target=strftime.3c
link path=usr/share/man/man3c/asctime.3c target=ctime.3c
link path=usr/share/man/man3c/asctime_r.3c target=ctime.3c
link path=usr/share/man/man3c/asprintf.3c target=printf.3c
+link path=usr/share/man/man3c/at_quick_exit.3c target=quick_exit.3c
link path=usr/share/man/man3c/atof.3c target=strtod.3c
link path=usr/share/man/man3c/atoi.3c target=strtol.3c
link path=usr/share/man/man3c/atol.3c target=strtol.3c
@@ -690,6 +705,12 @@ link path=usr/share/man/man3c/clearerr.3c target=ferror.3c
link path=usr/share/man/man3c/clock_getres.3c target=clock_settime.3c
link path=usr/share/man/man3c/clock_gettime.3c target=clock_settime.3c
link path=usr/share/man/man3c/closelog.3c target=syslog.3c
+link path=usr/share/man/man3c/cnd_broadcast.3c target=cnd.3c
+link path=usr/share/man/man3c/cnd_destroy.3c target=cnd.3c
+link path=usr/share/man/man3c/cnd_init.3c target=cnd.3c
+link path=usr/share/man/man3c/cnd_signal.3c target=cnd.3c
+link path=usr/share/man/man3c/cnd_timedwait.3c target=cnd.3c
+link path=usr/share/man/man3c/cnd_wait.3c target=cnd.3c
link path=usr/share/man/man3c/cond_broadcast.3c target=cond_init.3c
link path=usr/share/man/man3c/cond_destroy.3c target=cond_init.3c
link path=usr/share/man/man3c/cond_reltimedwait.3c target=cond_init.3c
@@ -954,6 +975,12 @@ link path=usr/share/man/man3c/mq_reltimedsend_np.3c target=mq_send.3c
link path=usr/share/man/man3c/mq_timedreceive.3c target=mq_receive.3c
link path=usr/share/man/man3c/mq_timedsend.3c target=mq_send.3c
link path=usr/share/man/man3c/mrand48.3c target=drand48.3c
+link path=usr/share/man/man3c/mtx_destroy.3c target=mtx.3c
+link path=usr/share/man/man3c/mtx_init.3c target=mtx.3c
+link path=usr/share/man/man3c/mtx_lock.3c target=mtx.3c
+link path=usr/share/man/man3c/mtx_timedlock.3c target=mtx.3c
+link path=usr/share/man/man3c/mtx_trylock.3c target=mtx.3c
+link path=usr/share/man/man3c/mtx_unlock.3c target=mtx.3c
link path=usr/share/man/man3c/munlock.3c target=mlock.3c
link path=usr/share/man/man3c/munlockall.3c target=mlockall.3c
link path=usr/share/man/man3c/mutex_consistent.3c target=mutex_init.3c
@@ -1280,6 +1307,7 @@ link path=usr/share/man/man3c/thr_setconcurrency.3c \
target=thr_getconcurrency.3c
link path=usr/share/man/man3c/thr_setprio.3c target=thr_getprio.3c
link path=usr/share/man/man3c/thr_setspecific.3c target=thr_keycreate.3c
+link path=usr/share/man/man3c/thrd_sleep.3c target=nanosleep.3c
link path=usr/share/man/man3c/timegm.3c target=mktime.3c
link path=usr/share/man/man3c/timer_getoverrun.3c target=timer_settime.3c
link path=usr/share/man/man3c/timer_gettime.3c target=timer_settime.3c
@@ -1296,6 +1324,10 @@ link path=usr/share/man/man3c/towctrans.3c target=wctrans.3c
link path=usr/share/man/man3c/towctrans_l.3c target=wctrans.3c
link path=usr/share/man/man3c/towlower_l.3c target=towlower.3c
link path=usr/share/man/man3c/towupper_l.3c target=towupper.3c
+link path=usr/share/man/man3c/tss_create.3c target=tss.3c
+link path=usr/share/man/man3c/tss_delete.3c target=tss.3c
+link path=usr/share/man/man3c/tss_get.3c target=tss.3c
+link path=usr/share/man/man3c/tss_set.3c target=tss.3c
link path=usr/share/man/man3c/ttyname_r.3c target=ttyname.3c
link path=usr/share/man/man3c/twalk.3c target=tsearch.3c
link path=usr/share/man/man3c/tzset.3c target=ctime.3c
diff --git a/usr/src/pkg/manifests/system-test-libctest.mf b/usr/src/pkg/manifests/system-test-libctest.mf
index e4e043ceca..e09d18574c 100644
--- a/usr/src/pkg/manifests/system-test-libctest.mf
+++ b/usr/src/pkg/manifests/system-test-libctest.mf
@@ -44,6 +44,7 @@ file path=opt/libc-tests/bin/libctest mode=0555
file path=opt/libc-tests/cfg/README mode=0444
file path=opt/libc-tests/cfg/compilation.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/README mode=0444
+file path=opt/libc-tests/cfg/symbols/assert_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/ctype_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/dirent_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/fcntl_h.cfg mode=0444
@@ -52,18 +53,31 @@ file path=opt/libc-tests/cfg/symbols/math_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/netdb_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/pthread_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/signal_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/stdalign_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/stddef_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/stdio_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/stdlib_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/stdnoreturn_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/string_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/strings_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/sys_stat_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/sys_time_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/sys_timeb_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/threads_h.cfg mode=0444
+file path=opt/libc-tests/cfg/symbols/time_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/ucontext_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/unistd_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/wchar_h.cfg mode=0444
file path=opt/libc-tests/cfg/symbols/wctype_h.cfg mode=0444
file path=opt/libc-tests/runfiles/default.run mode=0444
+file path=opt/libc-tests/tests/aligned_alloc.32 mode=0555
+file path=opt/libc-tests/tests/aligned_alloc.64 mode=0555
+file path=opt/libc-tests/tests/c11_threads.32 mode=0555
+file path=opt/libc-tests/tests/c11_threads.64 mode=0555
+file path=opt/libc-tests/tests/c11_tss.32 mode=0555
+file path=opt/libc-tests/tests/c11_tss.64 mode=0555
+file path=opt/libc-tests/tests/call_once.32 mode=0555
+file path=opt/libc-tests/tests/call_once.64 mode=0555
file path=opt/libc-tests/tests/catopen mode=0555
file path=opt/libc-tests/tests/fpround_test mode=0555
file path=opt/libc-tests/tests/fpround_test.$(ARCH) mode=0555
@@ -75,6 +89,11 @@ file path=opt/libc-tests/tests/nl_langinfo_test mode=0555
file path=opt/libc-tests/tests/nl_langinfo_test.$(ARCH) mode=0555
file path=opt/libc-tests/tests/nl_langinfo_test.$(ARCH64) mode=0555
file path=opt/libc-tests/tests/priv_gettext mode=0555
+file path=opt/libc-tests/tests/quick_exit mode=0555
+file path=opt/libc-tests/tests/quick_exit_order.32 mode=0555
+file path=opt/libc-tests/tests/quick_exit_order.64 mode=0555
+file path=opt/libc-tests/tests/quick_exit_status.32 mode=0555
+file path=opt/libc-tests/tests/quick_exit_status.64 mode=0555
file path=opt/libc-tests/tests/random/arc4key.ksh mode=0555
file path=opt/libc-tests/tests/random/arc4random mode=0555
file path=opt/libc-tests/tests/random/arc4random_fork mode=0555
@@ -99,6 +118,8 @@ file path=opt/libc-tests/tests/strerror mode=0555
file path=opt/libc-tests/tests/symbols/setup mode=0555
file path=opt/libc-tests/tests/symbols/symbols_test.$(ARCH) mode=0555
file path=opt/libc-tests/tests/symbols/symbols_test.$(ARCH64) mode=0555
+file path=opt/libc-tests/tests/timespec_get.32 mode=0555
+file path=opt/libc-tests/tests/timespec_get.64 mode=0555
file path=opt/libc-tests/tests/wcsrtombs_test mode=0555
file path=opt/libc-tests/tests/wcsrtombs_test.$(ARCH) mode=0555
file path=opt/libc-tests/tests/wcsrtombs_test.$(ARCH64) mode=0555
@@ -113,6 +134,7 @@ file path=usr/lib/locale/zz_AA.UTF-8/LC_MESSAGES/priv_names mode=0444
file path=usr/lib/locale/zz_AA.UTF-8/LC_MONETARY/LCL_DATA mode=0444
file path=usr/lib/locale/zz_AA.UTF-8/LC_NUMERIC/LCL_DATA mode=0444
file path=usr/lib/locale/zz_AA.UTF-8/LC_TIME/LCL_DATA mode=0444
+hardlink path=opt/libc-tests/tests/symbols/assert_h target=setup
hardlink path=opt/libc-tests/tests/symbols/ctype_h target=setup
hardlink path=opt/libc-tests/tests/symbols/dirent_h target=setup
hardlink path=opt/libc-tests/tests/symbols/fcntl_h target=setup
@@ -121,13 +143,18 @@ hardlink path=opt/libc-tests/tests/symbols/math_h target=setup
hardlink path=opt/libc-tests/tests/symbols/netdb_h target=setup
hardlink path=opt/libc-tests/tests/symbols/pthread_h target=setup
hardlink path=opt/libc-tests/tests/symbols/signal_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/stdalign_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/stddef_h target=setup
hardlink path=opt/libc-tests/tests/symbols/stdio_h target=setup
hardlink path=opt/libc-tests/tests/symbols/stdlib_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/stdnoreturn_h target=setup
hardlink path=opt/libc-tests/tests/symbols/string_h target=setup
hardlink path=opt/libc-tests/tests/symbols/strings_h target=setup
hardlink path=opt/libc-tests/tests/symbols/sys_stat_h target=setup
hardlink path=opt/libc-tests/tests/symbols/sys_time_h target=setup
hardlink path=opt/libc-tests/tests/symbols/sys_timeb_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/threads_h target=setup
+hardlink path=opt/libc-tests/tests/symbols/time_h target=setup
hardlink path=opt/libc-tests/tests/symbols/ucontext_h target=setup
hardlink path=opt/libc-tests/tests/symbols/unistd_h target=setup
hardlink path=opt/libc-tests/tests/symbols/wchar_h target=setup
diff --git a/usr/src/test/libc-tests/cfg/Makefile b/usr/src/test/libc-tests/cfg/Makefile
index 37b6b53c9f..3f87dc9e9f 100644
--- a/usr/src/test/libc-tests/cfg/Makefile
+++ b/usr/src/test/libc-tests/cfg/Makefile
@@ -19,6 +19,7 @@ include $(SRC)/Makefile.master
CFGS = README \
compilation.cfg \
symbols/README \
+ symbols/assert_h.cfg \
symbols/ctype_h.cfg \
symbols/dirent_h.cfg \
symbols/fcntl_h.cfg \
@@ -27,13 +28,18 @@ CFGS = README \
symbols/netdb_h.cfg \
symbols/pthread_h.cfg \
symbols/signal_h.cfg \
+ symbols/stdalign_h.cfg \
+ symbols/stddef_h.cfg \
symbols/stdio_h.cfg \
symbols/stdlib_h.cfg \
+ symbols/stdnoreturn_h.cfg \
symbols/string_h.cfg \
symbols/strings_h.cfg \
symbols/sys_stat_h.cfg \
symbols/sys_time_h.cfg \
symbols/sys_timeb_h.cfg \
+ symbols/time_h.cfg \
+ symbols/threads_h.cfg \
symbols/ucontext_h.cfg \
symbols/unistd_h.cfg \
symbols/wchar_h.cfg \
diff --git a/usr/src/test/libc-tests/cfg/compilation.cfg b/usr/src/test/libc-tests/cfg/compilation.cfg
index e39823bf3c..1219844a0c 100644
--- a/usr/src/test/libc-tests/cfg/compilation.cfg
+++ b/usr/src/test/libc-tests/cfg/compilation.cfg
@@ -11,6 +11,7 @@
#
# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+# Copyright 2016 Joyent, Inc.
#
#
@@ -51,6 +52,7 @@ env | POSIX-2001 | c99 | -D_POSIX_C_SOURCE=200112L
env | POSIX-2008 | c99 | -D_POSIX_C_SOURCE=200809L
env | C90 | c89 |
env | C99 | c99 |
+env | C11 | c11 |
#
# These are ordered from less inclusive (most recent) to most inclusive.
@@ -70,8 +72,8 @@ env_group | SUSv1+ | SUSv1 SUSv2+
env_group | SUS+ | SUSv1+
env_group | XPG4+ | XPG4 SUSv1+
env_group | XPG3+ | XPG3 XPG4+
-env_group | C99+ | C99 POSIX-2001+ SUSv3+
-env_group | C+ | C90 C99 POSIX+ SUS+
+env_group | C99+ | C99 C11 POSIX-2001+ SUSv3+
+env_group | C+ | C90 C99 C11 POSIX+ SUS+
env_group | ALL | C+
#
diff --git a/usr/src/test/libc-tests/cfg/symbols/README b/usr/src/test/libc-tests/cfg/symbols/README
index 3d86b68d5c..41c35589e3 100644
--- a/usr/src/test/libc-tests/cfg/symbols/README
+++ b/usr/src/test/libc-tests/cfg/symbols/README
@@ -11,6 +11,7 @@
#
# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+# Copyright 2016 Joyent, Inc.
#
The configuration files in this directory are structured using the
@@ -56,6 +57,14 @@ value | <name> | <type> | <header> | <envs>
assign the given value to a scratch variable declared with the given
type. The value can be a macro or other C symbol.
+define | <name> | <value> | <header> | <envs>
+
+ Tests for a definition named <name>. The test verifies that the
+ pre-processor sees the definition. If the <value> entry is not
+ empty then the check also verifies that there is strict equality
+ between the pre-processor value and it. Only strict equality checks
+ are supported at this time.
+
func | <name> | <type> | <type> [; <type> ]... | <header> | <envs>
Tests whether a function <name>, returning the first <type>, and
@@ -69,4 +78,6 @@ Examples:
type | size_t | sys/types.h | ALL
value | NULL | void * | stdlib.h | ALL
- func strnlen | int | const char *; int | string.h | ALL
+ define | thread_local | | threads.h | -ALL +C11
+ define | __alignas_is_defined | 1 | threads.h | -ALL +C11
+ func | strnlen | int | const char *; int | string.h | ALL
diff --git a/usr/src/test/libc-tests/cfg/symbols/assert_h.cfg b/usr/src/test/libc-tests/cfg/symbols/assert_h.cfg
new file mode 100644
index 0000000000..67413e801b
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/assert_h.cfg
@@ -0,0 +1,23 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2016 Joyent, Inc.
+#
+
+#
+# Definitions found in assert.h
+#
+
+#
+# Defines
+#
+define | static_assert | | assert.h | -ALL +C11
diff --git a/usr/src/test/libc-tests/cfg/symbols/stdalign_h.cfg b/usr/src/test/libc-tests/cfg/symbols/stdalign_h.cfg
new file mode 100644
index 0000000000..81b7419e31
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/stdalign_h.cfg
@@ -0,0 +1,26 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2016 Joyent, Inc.
+#
+
+#
+# Definitions found in stdalign.h
+#
+
+#
+# Defines
+#
+define | alignas | | stdalign.h | -ALL +C11
+define | alignof | | stdalign.h | -ALL +C11
+define | __alignas_is_defined | 1 | stdalign.h | -ALL +C11
+define | __alignof_is_defined | 1 | stdalign.h | -ALL +C11
diff --git a/usr/src/test/libc-tests/cfg/symbols/stddef_h.cfg b/usr/src/test/libc-tests/cfg/symbols/stddef_h.cfg
new file mode 100644
index 0000000000..a7f2f73059
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/stddef_h.cfg
@@ -0,0 +1,31 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2016 Joyent, Inc.
+#
+
+#
+# Definitions found in stddef.h
+#
+
+#
+# Types
+#
+type | max_align_t | stddef.h | -ALL +C11
+
+#
+# Values.
+#
+
+#
+# Functions
+#
diff --git a/usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg b/usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg
index 3d624544d6..a88c8be5e4 100644
--- a/usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg
+++ b/usr/src/test/libc-tests/cfg/symbols/stdio_h.cfg
@@ -11,6 +11,7 @@
#
# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+# Copyright 2016 Joyent, Inc.
#
#
@@ -42,6 +43,11 @@ value | optopt | int | stdio.h | -ALL +XPG3+ -SUSv3+
# Functions
#
+func | gets |\
+ char * |\
+ char * |\
+ stdio.h | ALL -C11
+
func | printf |\
int |\
const char * |\
diff --git a/usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg b/usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg
index b3299474b5..745575068d 100644
--- a/usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg
+++ b/usr/src/test/libc-tests/cfg/symbols/stdlib_h.cfg
@@ -12,6 +12,7 @@
#
# Copyright 2015 Garrett D'Amore <garrett@damore.org>
# Copyright 2015, OmniTI Computer Consulting, Inc. All Rights Reserved.
+# Copyright 2016 Joyent, Inc.
#
#
@@ -33,6 +34,18 @@ value | NULL | void * | stdlib.h | ALL
#
# Functions
#
+func | aligned_alloc |\
+ void * |\
+ size_t; size_t |\
+ stdlib.h |\
+ -ALL C11
+
+func | at_quick_exit |\
+ int |\
+ void (*)(void) |\
+ stdlib.h |\
+ -ALL C11
+
func | calloc |\
void * |\
size_t; size_t |\
@@ -86,3 +99,9 @@ func | mkdtemp |\
char * |\
stdlib.h |\
-ALL SUSv4+
+
+func | quick_exit |\
+ void |\
+ int |\
+ stdlib.h |\
+ -ALL C11
diff --git a/usr/src/test/libc-tests/cfg/symbols/stdnoreturn_h.cfg b/usr/src/test/libc-tests/cfg/symbols/stdnoreturn_h.cfg
new file mode 100644
index 0000000000..418341f4f5
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/stdnoreturn_h.cfg
@@ -0,0 +1,23 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2016 Joyent, Inc.
+#
+
+#
+# Definitions found in stdnoreturn.h
+#
+
+#
+# Defines
+#
+define | noreturn | | stdnoreturn.h | -ALL +C11
diff --git a/usr/src/test/libc-tests/cfg/symbols/threads_h.cfg b/usr/src/test/libc-tests/cfg/symbols/threads_h.cfg
new file mode 100644
index 0000000000..319fa55c57
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/threads_h.cfg
@@ -0,0 +1,176 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2016 Joyent, Inc.
+#
+
+#
+# Definitions found in stddef.h
+#
+
+#
+# Types
+#
+type | cnd_t | threads.h | -ALL +C11
+type | thrd_t | threads.h | -ALL +C11
+type | tss_t | threads.h | -ALL +C11
+type | mtx_t | threads.h | -ALL +C11
+type | once_flag | threads.h | -ALL +C11
+type | tss_dtor_t | threads.h | -ALL +C11
+type | thrd_start_t | threads.h | -ALL +C11
+
+#
+# Values.
+#
+value | mtx_plain | int | threads.h | -ALL +C11
+value | mtx_recursive | int | threads.h | -ALL +C11
+value | mtx_timed | int | threads.h | -ALL +C11
+value | thrd_success | int | threads.h | -ALL +C11
+value | thrd_error | int | threads.h | -ALL +C11
+value | thrd_busy | int | threads.h | -ALL +C11
+value | thrd_timedout | int | threads.h | -ALL +C11
+value | thrd_nomem | int | threads.h | -ALL +C11
+
+#
+# Defines
+#
+define | thread_local | | threads.h | -ALL +C11
+define | ONCE_FLAG_INIT | | threads.h | -ALL +C11
+define | TSS_DTOR_ITERATIONS | | threads.h | -ALL +C11
+
+#
+# Functions
+#
+func | call_once |\
+ void |\
+ once_flag *; void (*)(void) |\
+ threads.h | -ALL +C11
+
+func | cnd_broadcast |\
+ int |\
+ cnd_t * |\
+ threads.h | -ALL +C11
+
+func | cnd_destroy |\
+ void |\
+ cnd_t * |\
+ threads.h | -ALL +C11
+
+func | cnd_init |\
+ int |\
+ cnd_t * |\
+ threads.h | -ALL +C11
+
+func | cnd_signal |\
+ int |\
+ cnd_t * |\
+ threads.h | -ALL +C11
+
+func | cnd_timedwait |\
+ int |\
+ cnd_t *; mtx_t *; const struct timespec * |\
+ threads.h | -ALL +C11
+
+func | cnd_wait |\
+ int |\
+ cnd_t *; mtx_t * |\
+ threads.h | -ALL +C11
+
+func | mtx_destroy |\
+ void |\
+ mtx_t * |\
+ threads.h | -ALL +C11
+
+func | mtx_init |\
+ int |\
+ mtx_t *; int |\
+ threads.h | -ALL +C11
+
+func | mtx_lock |\
+ int |\
+ mtx_t * |\
+ threads.h | -ALL +C11
+
+func | mtx_timedlock |\
+ int |\
+ mtx_t *; const struct timespec * |\
+ threads.h | -ALL +C11
+
+func | mtx_trylock |\
+ int |\
+ mtx_t * |\
+ threads.h | -ALL +C11
+
+func | mtx_unlock |\
+ int |\
+ mtx_t * |\
+ threads.h | -ALL +C11
+
+func | thrd_create |\
+ int |\
+ thrd_t *; thrd_start_t; void * |\
+ threads.h | -ALL +C11
+
+func | thrd_current |\
+ thrd_t |\
+ void |\
+ threads.h | -ALL +C11
+
+func | thrd_detach |\
+ int |\
+ thrd_t |\
+ threads.h | -ALL +C11
+
+func | thrd_equal |\
+ int |\
+ thrd_t; thrd_t |\
+ threads.h | -ALL +C11
+
+func | thrd_exit |\
+ void |\
+ int |\
+ threads.h | -ALL +C11
+
+func | thrd_join |\
+ int |\
+ thrd_t; int * |\
+ threads.h | -ALL +C11
+
+func | thrd_sleep |\
+ int |\
+ const struct timespec *; struct timespec * |\
+ threads.h | -ALL +C11
+
+func | thrd_yield |\
+ void |\
+ void |\
+ threads.h | -ALL +C11
+
+func | tss_create |\
+ int |\
+ tss_t *; tss_dtor_t |\
+ threads.h | -ALL +C11
+
+func | tss_delete |\
+ void |\
+ tss_t |\
+ threads.h | -ALL +C11
+
+func | tss_get |\
+ void * |\
+ tss_t |\
+ threads.h | -ALL +C11
+
+func | tss_set |\
+ int |\
+ tss_t; void * |\
+ threads.h | -ALL +C11
diff --git a/usr/src/test/libc-tests/cfg/symbols/time_h.cfg b/usr/src/test/libc-tests/cfg/symbols/time_h.cfg
new file mode 100644
index 0000000000..54116f730a
--- /dev/null
+++ b/usr/src/test/libc-tests/cfg/symbols/time_h.cfg
@@ -0,0 +1,40 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2016 Joyent, Inc.
+#
+
+#
+# Definitions found in time.h
+#
+
+#
+# Types
+#
+
+#
+# Values.
+#
+
+#
+# Defines
+#
+define | TIME_UTC | | time.h | -ALL +C11
+
+#
+# Functions
+#
+func | timespec_get |\
+ int |\
+ struct timespec *; int |\
+ time.h |\
+ -ALL C11
diff --git a/usr/src/test/libc-tests/runfiles/default.run b/usr/src/test/libc-tests/runfiles/default.run
index 1be23194df..e53831e626 100644
--- a/usr/src/test/libc-tests/runfiles/default.run
+++ b/usr/src/test/libc-tests/runfiles/default.run
@@ -51,13 +51,25 @@ outputdir = /var/tmp/test_results
[/opt/libc-tests/tests/random/arc4random_preforksig]
[/opt/libc-tests/tests/random/arc4key.ksh]
+[/opt/libc-tests/tests/aligned_alloc.32]
+[/opt/libc-tests/tests/aligned_alloc.64]
+[/opt/libc-tests/tests/c11_threads.32]
+[/opt/libc-tests/tests/c11_threads.64]
+[/opt/libc-tests/tests/c11_tss.32]
+[/opt/libc-tests/tests/c11_tss.64]
+[/opt/libc-tests/tests/call_once.32]
+[/opt/libc-tests/tests/call_once.64]
[/opt/libc-tests/tests/catopen]
+[/opt/libc-tests/tests/quick_exit]
[/opt/libc-tests/tests/priv_gettext]
[/opt/libc-tests/tests/strerror]
+[/opt/libc-tests/tests/timespec_get.32]
+[/opt/libc-tests/tests/timespec_get.64]
[/opt/libc-tests/tests/symbols]
pre = setup
tests = [
+ 'assert_h',
'ctype_h',
'dirent_h',
'fcntl_h',
@@ -66,13 +78,18 @@ tests = [
'netdb_h',
'pthread_h',
'signal_h',
+ 'stdalign_h',
+ 'stddef_h',
'stdio_h',
'stdlib_h',
+ 'stdnoreturn_h',
'string_h',
'strings_h',
'sys_stat_h',
'sys_time_h',
'sys_timeb_h',
+ 'time_h',
+ 'threads_h',
'ucontext_h',
'unistd_h',
'wchar_h',
diff --git a/usr/src/test/libc-tests/tests/Makefile b/usr/src/test/libc-tests/tests/Makefile
index 3aca9f17c1..44e6a4ffff 100644
--- a/usr/src/test/libc-tests/tests/Makefile
+++ b/usr/src/test/libc-tests/tests/Makefile
@@ -12,6 +12,7 @@
#
# Copyright (c) 2012 by Delphix. All rights reserved.
# Copyright 2015 Garrett D'Amore <garrett@damore.org>
+# Copyright 2016 Joyent, Inc.
#
SUBDIRS = \
@@ -26,5 +27,70 @@ SUBDIRS = \
wcsrtombs \
wctype
-include $(SRC)/Makefile.master
-include $(SRC)/test/Makefile.com
+PROGS = \
+ aligned_alloc \
+ c11_threads \
+ c11_tss \
+ call_once \
+ quick_exit_order \
+ quick_exit_status \
+ timespec_get
+
+SCRIPTS = \
+ quick_exit
+
+CPPFLAGS += -D_REENTRANT
+
+PROGS32 = $(PROGS:%=%.32)
+PROGS64 = $(PROGS:%=%.64)
+
+aligned_alloc.32 := LDLIBS += -lproc
+aligned_alloc.64 := LDLIBS64 += -lproc
+
+ROOTOPTDIR = $(ROOT)/opt/libc-tests/tests
+ROOTOPTPROGS = $(PROGS32:%=$(ROOTOPTDIR)/%) \
+ $(PROGS64:%=$(ROOTOPTDIR)/%) \
+ $(SCRIPTS:%=$(ROOTOPTDIR)/%)
+
+include $(SRC)/cmd/Makefile.cmd
+
+all := TARGET = all
+install := TARGET = install
+clean := TARGET = clean
+clobber := TARGET = clobber
+lint := TARGET = lint
+
+.KEEP_STATE:
+
+install: $(SUBDIRS) $(ROOTOPTPROGS)
+
+all: $(SUBDIRS) $(PROGS32) $(PROGS64)
+
+clean lint: $(SUBDIRS)
+
+$(ROOTOPTPROGS): $(PROGS32) $(PROGS64) $(ROOTOPTDIR)
+
+$(ROOTOPTDIR):
+ $(INS.dir)
+
+$(ROOTOPTDIR)/%: %
+ $(INS.file)
+
+$(ROOTOPTDIR)/%: %.ksh
+ $(INS.rename)
+
+%.64: %.c
+ $(LINK.c) -m64 -o $@ $< $(LDLIBS64)
+ $(POST_PROCESS)
+
+%.32: %.c
+ $(LINK.c) -m32 -o $@ $< $(LDLIBS)
+ $(POST_PROCESS)
+
+clobber: $(SUBDIRS)
+ $(RM) $(PROGS32) $(PROGS64)
+
+$(SUBDIRS): FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/test/libc-tests/tests/aligned_alloc.c b/usr/src/test/libc-tests/tests/aligned_alloc.c
new file mode 100644
index 0000000000..bbff168ef3
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/aligned_alloc.c
@@ -0,0 +1,77 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+/*
+ * Basic tests for aligned_alloc(3C). Note that we test ENOMEM failure by
+ * relying on the implementation of the current libc malloc. Specifically we go
+ * through and add a mapping so we can't expand the heap and then use it up. If
+ * the memory allocator is ever changed, this test will start failing, at which
+ * point, it may not be worth the cost of keeping it around.
+ */
+
+#include <stdlib.h>
+#include <errno.h>
+#include <libproc.h>
+#include <sys/sysmacros.h>
+#include <sys/mman.h>
+#include <sys/debug.h>
+
+int
+main(void)
+{
+ pstatus_t status;
+ void *buf;
+
+ /*
+ * Alignment must be sizeof (void *) (word) aligned.
+ */
+ VERIFY3P(aligned_alloc(sizeof (void *) - 1, 16), ==, NULL);
+ VERIFY3S(errno, ==, EINVAL);
+
+ VERIFY3P(aligned_alloc(sizeof (void *) + 1, 16), ==, NULL);
+ VERIFY3S(errno, ==, EINVAL);
+
+
+ VERIFY3P(aligned_alloc(23, 16), ==, NULL);
+ VERIFY3S(errno, ==, EINVAL);
+
+ buf = aligned_alloc(sizeof (void *), 16);
+ VERIFY3P(buf, !=, NULL);
+ free(buf);
+
+ /*
+ * Cause ENOMEM
+ */
+ VERIFY0(proc_get_status(getpid(), &status));
+ VERIFY3P(mmap((caddr_t)P2ROUNDUP(status.pr_brkbase +
+ status.pr_brksize, 0x1000), 0x1000,
+ PROT_READ, MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0),
+ !=, (void *)-1);
+
+ for (;;) {
+ if (malloc(16) == NULL)
+ break;
+ }
+
+ for (;;) {
+ if (aligned_alloc(sizeof (void *), 16) == NULL)
+ break;
+ }
+
+ VERIFY3P(aligned_alloc(sizeof (void *), 16), ==, NULL);
+ VERIFY3S(errno, ==, ENOMEM);
+
+ return (0);
+}
diff --git a/usr/src/test/libc-tests/tests/c11_threads.c b/usr/src/test/libc-tests/tests/c11_threads.c
new file mode 100644
index 0000000000..dffadcc2af
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/c11_threads.c
@@ -0,0 +1,385 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+/*
+ * Validate various C11 threads routines. Specifically we want to cover:
+ *
+ * o threads
+ * o mutexes
+ * o condition variables
+ */
+
+#include <threads.h>
+#include <sys/debug.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#define STRESS_NTHREADS 128
+#define STRESS_COUNT 1000
+
+static mtx_t stress_mtx;
+static int stress_count;
+
+#define BROADCAST_NTHREADS 128
+
+static mtx_t broadcast_mtx;
+static cnd_t broadcast_cnd;
+static boolean_t broadcast_done;
+
+#define SIGNAL_NTHREADS 128
+
+static mtx_t signal_mtx;
+static cnd_t signal_cnd;
+static boolean_t signal_done;
+
+/*
+ * This thread should only ever be used for detach.
+ */
+static int
+cthr_test_sleep_thr(void *arg)
+{
+ for (;;) {
+ sleep(1000);
+ }
+
+ abort();
+}
+
+static void
+cthr_test_mtx_init(void)
+{
+ mtx_t mtx;
+
+ VERIFY3S(mtx_init(&mtx, mtx_plain), ==, thrd_success);
+ mtx_destroy(&mtx);
+ VERIFY3S(mtx_init(&mtx, mtx_timed), ==, thrd_success);
+ mtx_destroy(&mtx);
+ VERIFY3S(mtx_init(&mtx, mtx_plain | mtx_recursive), ==, thrd_success);
+ mtx_destroy(&mtx);
+ VERIFY3S(mtx_init(&mtx, mtx_timed | mtx_recursive), ==, thrd_success);
+ mtx_destroy(&mtx);
+
+ VERIFY3S(mtx_init(&mtx, UINT32_MAX), ==, thrd_error);
+ VERIFY3S(mtx_init(&mtx, 42), ==, thrd_error);
+}
+
+static void
+cthr_test_mtx_lockrec(void)
+{
+ mtx_t mtx;
+
+ VERIFY3S(mtx_init(&mtx, mtx_plain | mtx_recursive), ==, thrd_success);
+ VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
+ VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
+ VERIFY3S(mtx_trylock(&mtx), ==, thrd_success);
+ VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
+ VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
+ VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
+ mtx_destroy(&mtx);
+}
+
+static void
+cthr_test_mtx_trylock(void)
+{
+ mtx_t mtx;
+
+ VERIFY3S(mtx_init(&mtx, mtx_plain), ==, thrd_success);
+ VERIFY3S(mtx_trylock(&mtx), ==, thrd_success);
+ VERIFY3S(mtx_trylock(&mtx), ==, thrd_busy);
+ VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
+ mtx_destroy(&mtx);
+}
+
+static int
+cthr_test_stress_thr(void *arg)
+{
+ int i;
+ int *ip = arg;
+
+ for (i = 0; i < STRESS_COUNT; i++) {
+ VERIFY3S(mtx_lock(&stress_mtx), ==, thrd_success);
+ *ip = *ip + 1;
+ VERIFY3S(mtx_unlock(&stress_mtx), ==, thrd_success);
+ }
+
+ return (0);
+}
+
+static void
+cthr_test_stress(void)
+{
+ int i;
+ thrd_t threads[STRESS_NTHREADS];
+
+ VERIFY3S(mtx_init(&stress_mtx, mtx_plain), ==, thrd_success);
+ for (i = 0; i < STRESS_NTHREADS; i++) {
+ VERIFY3S(thrd_create(&threads[i], cthr_test_stress_thr,
+ &stress_count), ==, thrd_success);
+ }
+
+ for (i = 0; i < STRESS_NTHREADS; i++) {
+ VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
+ }
+ mtx_destroy(&stress_mtx);
+
+ VERIFY3S(stress_count, ==, STRESS_NTHREADS * STRESS_COUNT);
+}
+
+static void
+cthr_test_equal(void)
+{
+ thrd_t self, other;
+
+ self = thrd_current();
+
+ VERIFY0(thrd_equal(self, self));
+ VERIFY3S(thrd_create(&other, cthr_test_sleep_thr, NULL), ==,
+ thrd_success);
+ VERIFY3S(thrd_equal(self, other), !=, 0);
+ VERIFY3S(thrd_equal(other, other), ==, 0);
+ VERIFY3S(thrd_detach(other), ==, thrd_success);
+}
+
+static void
+cthr_test_detach_err(void)
+{
+ thrd_t self, other;
+
+ self = thrd_current();
+
+ VERIFY0(thrd_equal(self, self));
+ VERIFY3S(thrd_create(&other, cthr_test_sleep_thr, NULL), ==,
+ thrd_success);
+ VERIFY3S(thrd_detach(other), ==, thrd_success);
+
+ VERIFY3S(thrd_join(self, NULL), ==, thrd_error);
+ VERIFY3S(thrd_join(other, NULL), ==, thrd_error);
+}
+
+static int
+cthr_test_detach_thr0(void *arg)
+{
+ thrd_exit(23);
+ abort();
+}
+
+static int
+cthr_test_detach_thr1(void *arg)
+{
+ return (42);
+}
+
+static void
+cthr_test_detach(void)
+{
+ int status;
+ thrd_t thrd;
+
+ VERIFY3S(thrd_create(&thrd, cthr_test_detach_thr0, NULL), ==,
+ thrd_success);
+ VERIFY3S(thrd_join(thrd, &status), ==, thrd_success);
+ VERIFY3S(status, ==, 23);
+
+ VERIFY3S(thrd_create(&thrd, cthr_test_detach_thr1, NULL), ==,
+ thrd_success);
+ VERIFY3S(thrd_join(thrd, &status), ==, thrd_success);
+ VERIFY3S(status, ==, 42);
+}
+
+static void
+cthr_test_sleep(void)
+{
+ struct timespec ts;
+ hrtime_t start, end;
+ long stime = 10 * NANOSEC / MILLISEC;
+
+ ts.tv_sec = 1;
+ ts.tv_nsec = -1;
+
+ VERIFY3S(thrd_sleep(&ts, NULL), <, -1);
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = stime;
+ start = gethrtime();
+ VERIFY3S(thrd_sleep(&ts, NULL), ==, 0);
+ end = gethrtime();
+
+ VERIFY3S(end - start, >, stime);
+}
+
+static int
+cthr_test_broadcast_thr(void *arg)
+{
+ VERIFY3S(mtx_lock(&broadcast_mtx), ==, thrd_success);
+ while (broadcast_done == B_FALSE)
+ VERIFY3S(cnd_wait(&broadcast_cnd, &broadcast_mtx), ==,
+ thrd_success);
+ VERIFY3S(mtx_unlock(&broadcast_mtx), ==, thrd_success);
+
+ return (0);
+}
+
+static void
+cthr_test_broadcast(void)
+{
+ int i;
+ thrd_t threads[BROADCAST_NTHREADS];
+
+ VERIFY3S(mtx_init(&broadcast_mtx, mtx_plain), ==, thrd_success);
+ VERIFY3S(cnd_init(&broadcast_cnd), ==, thrd_success);
+ for (i = 0; i < BROADCAST_NTHREADS; i++) {
+ VERIFY3S(thrd_create(&threads[i], cthr_test_broadcast_thr,
+ NULL), ==, thrd_success);
+ }
+
+ VERIFY3S(mtx_lock(&broadcast_mtx), ==, thrd_success);
+ broadcast_done = B_TRUE;
+ VERIFY3S(mtx_unlock(&broadcast_mtx), ==, thrd_success);
+ VERIFY3S(cnd_broadcast(&broadcast_cnd), ==, thrd_success);
+
+ for (i = 0; i < STRESS_NTHREADS; i++) {
+ VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
+ }
+
+ mtx_destroy(&broadcast_mtx);
+ cnd_destroy(&broadcast_cnd);
+}
+
+
+static int
+cthr_test_signal_thr(void *arg)
+{
+ VERIFY3S(mtx_lock(&signal_mtx), ==, thrd_success);
+ while (signal_done == B_FALSE)
+ VERIFY3S(cnd_wait(&signal_cnd, &signal_mtx), ==,
+ thrd_success);
+ VERIFY3S(mtx_unlock(&signal_mtx), ==, thrd_success);
+ VERIFY3S(cnd_signal(&signal_cnd), ==, thrd_success);
+
+ return (0);
+}
+
+static void
+cthr_test_signal(void)
+{
+ int i;
+ thrd_t threads[SIGNAL_NTHREADS];
+
+ VERIFY3S(mtx_init(&signal_mtx, mtx_plain), ==, thrd_success);
+ VERIFY3S(cnd_init(&signal_cnd), ==, thrd_success);
+ for (i = 0; i < SIGNAL_NTHREADS; i++) {
+ VERIFY3S(thrd_create(&threads[i], cthr_test_signal_thr, NULL),
+ ==, thrd_success);
+ }
+
+ VERIFY3S(mtx_lock(&signal_mtx), ==, thrd_success);
+ signal_done = B_TRUE;
+ VERIFY3S(mtx_unlock(&signal_mtx), ==, thrd_success);
+ VERIFY3S(cnd_signal(&signal_cnd), ==, thrd_success);
+
+ for (i = 0; i < STRESS_NTHREADS; i++) {
+ VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
+ }
+
+ mtx_destroy(&signal_mtx);
+ cnd_destroy(&signal_cnd);
+}
+
+static void
+cthr_test_cndtime(void)
+{
+ mtx_t mtx;
+ cnd_t cnd;
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1 * NANOSEC / MILLISEC;
+ VERIFY3S(mtx_init(&mtx, mtx_plain), ==, thrd_success);
+ VERIFY3S(cnd_init(&cnd), ==, thrd_success);
+
+ VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
+ VERIFY3S(cnd_timedwait(&cnd, &mtx, &ts), ==, thrd_timedout);
+ VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
+
+ mtx_destroy(&mtx);
+ cnd_destroy(&cnd);
+}
+
+static void
+cthr_test_mtx_selftime(void)
+{
+ mtx_t mtx;
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1 * NANOSEC / MILLISEC;
+ VERIFY3S(mtx_init(&mtx, mtx_timed), ==, thrd_success);
+ VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
+ VERIFY3S(mtx_timedlock(&mtx, &ts), ==, thrd_timedout);
+ VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
+ mtx_destroy(&mtx);
+}
+
+static int
+cthr_test_mtx_busy_thr(void *arg)
+{
+ mtx_t *mtx = arg;
+ struct timespec ts;
+
+ ts.tv_sec = 0;
+ ts.tv_nsec = 1 * NANOSEC / MILLISEC;
+
+ VERIFY3S(mtx_trylock(mtx), ==, thrd_busy);
+ VERIFY3S(mtx_timedlock(mtx, &ts), ==, thrd_timedout);
+
+ return (0);
+}
+
+static void
+cthr_test_mtx_busy(void)
+{
+ mtx_t mtx;
+ thrd_t thrd;
+
+ VERIFY3S(mtx_init(&mtx, mtx_timed), ==, thrd_success);
+ VERIFY3S(mtx_lock(&mtx), ==, thrd_success);
+
+ VERIFY3S(thrd_create(&thrd, cthr_test_mtx_busy_thr, &mtx), ==,
+ thrd_success);
+ VERIFY3S(thrd_join(thrd, NULL), ==, thrd_success);
+
+ VERIFY3S(mtx_unlock(&mtx), ==, thrd_success);
+ mtx_destroy(&mtx);
+}
+
+int
+main(void)
+{
+ cthr_test_mtx_init();
+ cthr_test_mtx_lockrec();
+ cthr_test_mtx_trylock();
+ cthr_test_stress();
+ cthr_test_equal();
+ cthr_test_detach_err();
+ cthr_test_detach();
+ cthr_test_sleep();
+ cthr_test_broadcast();
+ cthr_test_signal();
+ cthr_test_cndtime();
+ cthr_test_mtx_selftime();
+ cthr_test_mtx_busy();
+
+ return (0);
+}
diff --git a/usr/src/test/libc-tests/tests/c11_tss.c b/usr/src/test/libc-tests/tests/c11_tss.c
new file mode 100644
index 0000000000..b1005e7012
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/c11_tss.c
@@ -0,0 +1,87 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+/*
+ * Test various C11 thread-specific storage (tss(3C)) interfaces.
+ */
+
+#include <threads.h>
+#include <sys/debug.h>
+
+#define TSS_NTHREADS 128
+
+static tss_t ct_key;
+static int ct_count;
+static int ct_ready;
+static mtx_t ct_mtx;
+static cnd_t ct_cnd;
+
+static void
+ct_tss_dtor(void *arg)
+{
+ VERIFY3S(mtx_lock(&ct_mtx), ==, thrd_success);
+ ct_count++;
+ VERIFY3S(mtx_unlock(&ct_mtx), ==, thrd_success);
+}
+
+static int
+ct_tss_thr(void *arg)
+{
+ VERIFY3P(tss_get(ct_key), ==, NULL);
+ VERIFY3S(tss_set(ct_key, arg), ==, thrd_success);
+
+ VERIFY3S(mtx_lock(&ct_mtx), ==, thrd_success);
+ ct_ready++;
+ if (ct_ready == TSS_NTHREADS) {
+ VERIFY3S(cnd_broadcast(&ct_cnd), ==, thrd_success);
+ } else {
+ while (ct_ready != TSS_NTHREADS) {
+ VERIFY3S(cnd_wait(&ct_cnd, &ct_mtx), ==, thrd_success);
+ }
+ }
+ VERIFY3S(mtx_unlock(&ct_mtx), ==, thrd_success);
+
+ VERIFY3P(tss_get(ct_key), ==, arg);
+
+ return (0);
+}
+
+int
+main(void)
+{
+ int i;
+ thrd_t threads[TSS_NTHREADS];
+
+ VERIFY3S(tss_create(&ct_key, ct_tss_dtor), ==, thrd_success);
+ VERIFY3S(mtx_init(&ct_mtx, mtx_plain), ==, thrd_success);
+ VERIFY3S(cnd_init(&ct_cnd), ==, thrd_success);
+
+ for (i = 0; i < TSS_NTHREADS; i++) {
+ VERIFY3S(thrd_create(&threads[i], ct_tss_thr,
+ (void *)(uintptr_t)(i + 100)), ==, thrd_success);
+ }
+
+ for (i = 0; i < TSS_NTHREADS; i++) {
+ VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
+ }
+
+ VERIFY3S(ct_count, ==, TSS_NTHREADS);
+
+ mtx_destroy(&ct_mtx);
+ cnd_destroy(&ct_cnd);
+ tss_delete(ct_key);
+
+ return (0);
+}
diff --git a/usr/src/test/libc-tests/tests/call_once.c b/usr/src/test/libc-tests/tests/call_once.c
new file mode 100644
index 0000000000..8c10420bcd
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/call_once.c
@@ -0,0 +1,78 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+/*
+ * Test call_once(3C)
+ */
+
+#include <threads.h>
+#include <sys/debug.h>
+
+#define CO_NTHREADS 32
+
+static int co_val = 41;
+static mtx_t co_once_mtx;
+static mtx_t co_mtx;
+static boolean_t co_go = B_FALSE;
+static once_flag co_once = ONCE_FLAG_INIT;
+static cnd_t co_cnd;
+
+static void
+co_once_func(void)
+{
+ VERIFY3S(mtx_lock(&co_once_mtx), ==, thrd_success);
+ co_val++;
+ VERIFY3S(mtx_unlock(&co_once_mtx), ==, thrd_success);
+}
+
+/*ARGSUSED*/
+static int
+co_thr(void *arg)
+{
+ VERIFY3S(mtx_lock(&co_mtx), ==, thrd_success);
+ while (co_go == B_FALSE)
+ cnd_wait(&co_cnd, &co_mtx);
+ VERIFY3S(mtx_unlock(&co_mtx), ==, thrd_success);
+ call_once(&co_once, co_once_func);
+ return (0);
+}
+
+int
+main(void)
+{
+ int i;
+ thrd_t threads[CO_NTHREADS];
+
+ VERIFY3S(mtx_init(&co_once_mtx, mtx_plain), ==, thrd_success);
+ VERIFY3S(mtx_init(&co_mtx, mtx_plain), ==, thrd_success);
+ VERIFY3S(cnd_init(&co_cnd), ==, thrd_success);
+
+ for (i = 0; i < CO_NTHREADS; i++) {
+ VERIFY3S(thrd_create(&threads[i], co_thr, NULL), ==,
+ thrd_success);
+ }
+
+ VERIFY3S(mtx_lock(&co_mtx), ==, thrd_success);
+ co_go = B_TRUE;
+ VERIFY3S(mtx_unlock(&co_mtx), ==, thrd_success);
+ VERIFY3S(cnd_broadcast(&co_cnd), ==, thrd_success);
+
+ for (i = 0; i < CO_NTHREADS; i++) {
+ VERIFY3S(thrd_join(threads[i], NULL), ==, thrd_success);
+ }
+ VERIFY3S(co_val, ==, 42);
+
+ return (0);
+}
diff --git a/usr/src/test/libc-tests/tests/common/test_common.c b/usr/src/test/libc-tests/tests/common/test_common.c
index 973e6c6981..6a2b87de3a 100644
--- a/usr/src/test/libc-tests/tests/common/test_common.c
+++ b/usr/src/test/libc-tests/tests/common/test_common.c
@@ -253,7 +253,7 @@ test_trim(char **ptr)
*ptr = p;
p += strlen(p);
while ((--p >= *ptr) && (isspace(*p))) {
- *p = 0;
+ *p = '\0';
}
}
diff --git a/usr/src/test/libc-tests/tests/quick_exit.ksh b/usr/src/test/libc-tests/tests/quick_exit.ksh
new file mode 100644
index 0000000000..94f9509491
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/quick_exit.ksh
@@ -0,0 +1,67 @@
+#!/usr/bin/ksh
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source. A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+#
+# Copyright 2016 Joyent, Inc.
+#
+
+#
+# Test quick_exit(3C). We specifically test the following things:
+# o That we get a requested exit status
+# o That at_quick_exit() functions fire in a registered, reverse order.
+#
+# These are all done by helper programs
+#
+
+set -o errexit
+set -o pipefail
+
+qe_root=$(dirname $0)
+qe_status32=$qe_root/quick_exit_status.32
+qe_status64=$qe_root/quick_exit_status.64
+qe_order32=$qe_root/quick_exit_order.32
+qe_order64=$qe_root/quick_exit_order.64
+
+function fatal
+{
+ typeset msg="$*"
+ echo "Test Failed: $msg" >&2
+ exit 1
+}
+
+function check_status
+{
+ typeset stat=$1
+ $qe_status32 $stat
+ if [[ $? -ne $stat ]]; then
+ fatal "Test failed: Expected $qestatus32 to exit $stat " \
+ "got $?"
+ fi
+
+ $qe_status64 $stat
+ if [[ $? -ne $stat ]]; then
+ fatal "Test failed: Expected $qestatus64 to exit $stat " \
+ "got $?" >&2
+ fi
+}
+
+function check_order
+{
+ $qe_order32 || fatal "$qe_order32 returned $?"
+ $qe_order64 || fatal "$qe_order32 returned $?"
+}
+
+check_status 0
+check_status 23
+check_status 42
+check_order
+exit 0
diff --git a/usr/src/test/libc-tests/tests/quick_exit_order.c b/usr/src/test/libc-tests/tests/quick_exit_order.c
new file mode 100644
index 0000000000..2ee6ccad1d
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/quick_exit_order.c
@@ -0,0 +1,80 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+/*
+ * Register functions with quick_exit() and verify that we honor the expected
+ * function call value. We facilitate this by having a global integer and
+ * modifying it to various values in subsequent functions. If we're not called
+ * in reverse order, we should spot the differences.
+ */
+
+#include <stdlib.h>
+#include <sys/debug.h>
+
+static int qeo_val = 5;
+
+static void
+qeo_fifth(void)
+{
+ VERIFY3S(qeo_val, ==, 5);
+ qeo_val--;
+}
+
+static void
+qeo_fourth(void)
+{
+ VERIFY3S(qeo_val, ==, 4);
+ qeo_val--;
+}
+
+static void
+qeo_third(void)
+{
+ VERIFY3S(qeo_val, ==, 3);
+ qeo_val--;
+}
+
+static void
+qeo_second(void)
+{
+ VERIFY3S(qeo_val, ==, 2);
+ qeo_val--;
+}
+
+static void
+qeo_first(void)
+{
+ VERIFY3S(qeo_val, ==, 1);
+ qeo_val--;
+}
+
+static void
+qeo_zero(void)
+{
+ VERIFY3S(qeo_val, ==, 0);
+}
+
+int
+main(void)
+{
+ VERIFY0(at_quick_exit(qeo_zero));
+ VERIFY0(at_quick_exit(qeo_first));
+ VERIFY0(at_quick_exit(qeo_second));
+ VERIFY0(at_quick_exit(qeo_third));
+ VERIFY0(at_quick_exit(qeo_fourth));
+ VERIFY0(at_quick_exit(qeo_fifth));
+ quick_exit(0);
+ abort();
+}
diff --git a/usr/src/test/libc-tests/tests/quick_exit_status.c b/usr/src/test/libc-tests/tests/quick_exit_status.c
new file mode 100644
index 0000000000..a48440e964
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/quick_exit_status.c
@@ -0,0 +1,33 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+/*
+ * quick_exit() with the status code indicated in our arguments.
+ */
+
+#include <stdlib.h>
+
+int
+main(int argc, const char *argv[])
+{
+ int status;
+
+ if (argc != 2)
+ abort();
+
+ status = atoi(argv[1]);
+ quick_exit(status);
+ abort();
+}
diff --git a/usr/src/test/libc-tests/tests/symbols/Makefile b/usr/src/test/libc-tests/tests/symbols/Makefile
index 39947ee7b5..cd499add8c 100644
--- a/usr/src/test/libc-tests/tests/symbols/Makefile
+++ b/usr/src/test/libc-tests/tests/symbols/Makefile
@@ -19,6 +19,7 @@ TESTSUBDIR = symbols
PROG = symbols_test
KSHPROG = setup
SYMTESTS = \
+ assert_h \
ctype_h \
dirent_h \
fcntl_h \
@@ -26,14 +27,19 @@ SYMTESTS = \
math_h \
netdb_h \
pthread_h \
+ stdalign_h \
+ stddef_h \
signal_h \
stdio_h \
stdlib_h \
+ stdnoreturn_h \
string_h \
strings_h \
sys_stat_h \
sys_time_h \
sys_timeb_h \
+ time_h \
+ threads_h \
ucontext_h \
unistd_h \
wchar_h \
@@ -43,6 +49,15 @@ EXTRAPROG += $(SYMTESTS)
include ../Makefile.com
+#
+# Since we use libcmdutils which is LF64, we need to be LF64 even though we're
+# not using the LF64 related features at the moment, lint catches us otherwise.
+#
+CPPFLAGS += -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
+
+LDLIBS += -lcmdutils
+LDLIBS64 += -lcmdutils
+
$(SYMTESTS:%=$(TESTDIR)/%): $(TESTDIR)/setup
-$(RM) $@
$(LN) $(TESTDIR)/setup $@
diff --git a/usr/src/test/libc-tests/tests/symbols/symbols_test.c b/usr/src/test/libc-tests/tests/symbols/symbols_test.c
index a20000fcd5..53e0d015de 100644
--- a/usr/src/test/libc-tests/tests/symbols/symbols_test.c
+++ b/usr/src/test/libc-tests/tests/symbols/symbols_test.c
@@ -11,11 +11,11 @@
/*
* Copyright 2015 Garrett D'Amore <garrett@damore.org>
+ * Copyright 2016 Joyent, Inc.
*/
/*
- * This program tests symbol visibility using the /usr/bin/c89 and
- * /usr/bin/c99 programs.
+ * This program tests symbol visibility in different compilation environments.
*/
#include <stdio.h>
@@ -27,6 +27,7 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <note.h>
+#include <libcmdutils.h>
#include <sys/wait.h>
#include "test_common.h"
@@ -64,6 +65,7 @@ const char *compilers[] = {
char *compiler = NULL;
const char *c89flags = NULL;
const char *c99flags = NULL;
+const char *c11flags = NULL;
#define MAXENV 64 /* maximum number of environments (bitmask width) */
#define MAXHDR 10 /* maximum # headers to require to access symbol */
@@ -88,7 +90,12 @@ struct env_group {
struct env_group *eg_next;
};
-typedef enum { SYM_TYPE, SYM_VALUE, SYM_FUNC } sym_type_t;
+typedef enum {
+ SYM_TYPE,
+ SYM_VALUE,
+ SYM_DEFINE,
+ SYM_FUNC
+} sym_type_t;
struct sym_test {
char *st_name;
@@ -96,9 +103,10 @@ struct sym_test {
char *st_hdrs[MAXHDR];
char *st_rtype;
char *st_atypes[MAXARG];
+ char *st_defval;
uint64_t st_test_mask;
uint64_t st_need_mask;
- char *st_prog;
+ const char *st_prog;
struct sym_test *st_next;
};
@@ -284,31 +292,23 @@ do_env_group(char **fields, int nfields, char **err)
return (0);
}
-static char *progbuf = NULL;
-size_t proglen = 0;
-size_t progsiz = 0;
+static custr_t *st_custr;
static void
addprogch(char c)
{
- while (progsiz <= (proglen + 1)) {
- progbuf = realloc(progbuf, progsiz + 4096);
- if (progbuf == NULL) {
- perror("realloc");
- exit(1);
- }
- progsiz += 1024;
+ if (custr_appendc(st_custr, c) == -1) {
+ perror("custr_appendc");
+ exit(1);
}
- progbuf[proglen++] = c;
- progbuf[proglen] = 0;
}
static void
addprogstr(char *s)
{
- while (*s != NULL) {
- addprogch(*s);
- s++;
+ if (custr_append(st_custr, s) == -1) {
+ perror("custr_append");
+ exit(1);
}
}
@@ -316,38 +316,37 @@ static void
addprogfmt(const char *fmt, ...)
{
va_list va;
- char *buf = NULL;
va_start(va, fmt);
- if (vasprintf(&buf, fmt, va) < 0) {
- perror("vasprintf");
+ if (custr_append_vprintf(st_custr, fmt, va) == -1) {
+ perror("custr_append_vprintf");
exit(1);
}
va_end(va);
- addprogstr(buf);
- free(buf);
}
static void
mkprog(struct sym_test *st)
{
- char *s;
+ char *s = NULL;
- proglen = 0;
+ custr_reset(st_custr);
for (int i = 0; i < MAXHDR && st->st_hdrs[i] != NULL; i++) {
addprogfmt("#include <%s>\n", st->st_hdrs[i]);
}
- for (s = st->st_rtype; *s; s++) {
- addprogch(*s);
- if (*s == '(') {
- s++;
+ if (st->st_rtype != NULL) {
+ for (s = st->st_rtype; *s; s++) {
addprogch(*s);
- s++;
- break;
+ if (*s == '(') {
+ s++;
+ addprogch(*s);
+ s++;
+ break;
+ }
}
+ addprogch(' ');
}
- addprogch(' ');
/* for function pointers, s is closing suffix, otherwise empty */
@@ -362,6 +361,15 @@ mkprog(struct sym_test *st)
addprogfmt("\ttest_value = %s;\n}", st->st_name);
break;
+ case SYM_DEFINE:
+ addprogfmt("#if !defined(%s)", st->st_name);
+ if (st->st_defval != NULL)
+ addprogfmt("|| %s != %s", st->st_name, st->st_defval);
+ addprogfmt("\n#error %s is not defined or has the wrong value",
+ st->st_name);
+ addprogfmt("\n#endif\n");
+ break;
+
case SYM_FUNC:
addprogstr("\ntest_func(");
for (int i = 0; st->st_atypes[i] != NULL && i < MAXARG; i++) {
@@ -427,7 +435,7 @@ mkprog(struct sym_test *st)
addprogch('\n');
- st->st_prog = progbuf;
+ st->st_prog = custr_cstr(st_custr);
}
static int
@@ -539,6 +547,44 @@ do_value(char **fields, int nfields, char **err)
}
static int
+do_define(char **fields, int nfields, char **err)
+{
+ char *name, *value, *hdrs, *envs;
+ struct sym_test *st;
+
+ if (nfields != 4) {
+ myasprintf(err, "number of fields (%d) != 4", nfields);
+ return (-1);
+ }
+
+ name = fields[0];
+ value = fields[1];
+ hdrs = fields[2];
+ envs = fields[3];
+
+ st = myzalloc(sizeof (*st));
+ st->st_type = SYM_DEFINE;
+ st->st_name = mystrdup(name);
+
+ /*
+ * A value to compare against is optional. trim will leave it as a null
+ * pointer if there's nothing there.
+ */
+ test_trim(&value);
+ if (*value != '\0')
+ st->st_defval = mystrdup(value);
+
+ if ((add_envs(st, envs, err) < 0) ||
+ (add_headers(st, hdrs, err) < 0)) {
+ return (-1);
+ }
+
+ append_sym_test(st);
+
+ return (0);
+}
+
+static int
do_func(char **fields, int nfields, char **err)
{
char *name;
@@ -762,6 +808,7 @@ find_compiler(void)
test_debugf(t, "Found Studio C");
c89flags = "-Xc -errwarn=%all -v -xc99=%none " MFLAG;
c99flags = "-Xc -errwarn=%all -v -xc99=%all " MFLAG;
+ c11flags = NULL;
if (extra_debug) {
test_debugf(t, "c89flags: %s", c89flags);
test_debugf(t, "c99flags: %s", c99flags);
@@ -774,6 +821,8 @@ find_compiler(void)
"-isystem /usr/include " MFLAG;
c99flags = "-Wall -Werror -std=c99 -nostdinc "
"-isystem /usr/include " MFLAG;
+ c11flags = "-Wall -Werror -std=c11 -nostdinc "
+ "-isystem /usr/include " MFLAG;
if (extra_debug) {
test_debugf(t, "c89flags: %s", c89flags);
test_debugf(t, "c99flags: %s", c99flags);
@@ -799,7 +848,7 @@ do_compile(test_t t, struct sym_test *st, struct compile_env *cenv, int need)
char *cmd;
FILE *logf;
FILE *dotc;
- const char *prog;
+ const char *prog, *cflags, *lang;
full_count++;
@@ -820,9 +869,25 @@ do_compile(test_t t, struct sym_test *st, struct compile_env *cenv, int need)
(void) unlink(ofile);
+ if (strcmp(env_lang(cenv), "c99") == 0) {
+ lang = "c99";
+ cflags = c99flags;
+ } else if (strcmp(env_lang(cenv), "c11") == 0) {
+ lang = "c11";
+ cflags = c11flags;
+ } else {
+ lang = "c89";
+ cflags = c89flags;
+ }
+
+ if (cflags == NULL) {
+ test_failed(t, "compiler %s does not support %s", compiler,
+ lang);
+ return (-1);
+ }
+
myasprintf(&cmd, "%s %s %s -c %s -o %s >>%s 2>&1",
- compiler, strcmp(env_lang(cenv), "c99") == 0 ? c99flags : c89flags,
- env_defs(cenv), cfile, ofile, lfile);
+ compiler, cflags, env_defs(cenv), cfile, ofile, lfile);
if (extra_debug) {
test_debugf(t, "command: %s", cmd);
@@ -935,6 +1000,7 @@ main(int argc, char **argv)
if (test_load_config(NULL, argv[optind++],
"type", do_type,
"value", do_value,
+ "define", do_define,
"func", do_func,
NULL) < 0) {
exit(1);
@@ -946,6 +1012,11 @@ main(int argc, char **argv)
exit(1);
}
+ if (custr_alloc(&st_custr) == -1) {
+ perror("custr");
+ exit(1);
+ }
+
if (mkworkdir() < 0) {
perror("mkdir");
exit(1);
diff --git a/usr/src/test/libc-tests/tests/timespec_get.c b/usr/src/test/libc-tests/tests/timespec_get.c
new file mode 100644
index 0000000000..5458acdc89
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/timespec_get.c
@@ -0,0 +1,59 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2016 Joyent, Inc.
+ */
+
+/*
+ * Basic tests for timespec_get(3C).
+ */
+
+#include <time.h>
+#include <limits.h>
+#include <sys/debug.h>
+
+static int
+timespec_cmp(const struct timespec *ls, const struct timespec *rs)
+{
+ if (ls->tv_sec > rs->tv_sec)
+ return (-1);
+ if (ls->tv_sec < rs->tv_sec)
+ return (1);
+ if (ls->tv_nsec > rs->tv_nsec)
+ return (-1);
+ if (ls->tv_nsec > rs->tv_nsec)
+ return (-1);
+ if (ls->tv_nsec < rs->tv_nsec)
+ return (1);
+
+ return (0);
+}
+
+int
+main(void)
+{
+ struct timespec ts, pre, post;
+
+ VERIFY0(timespec_get(&ts, TIME_UTC + 1));
+ VERIFY0(timespec_get(&ts, TIME_UTC - 1));
+ VERIFY0(timespec_get(&ts, UINT16_MAX));
+
+ VERIFY0(clock_gettime(CLOCK_REALTIME, &pre));
+ VERIFY3S(timespec_get(&ts, TIME_UTC), ==, TIME_UTC);
+ VERIFY0(clock_gettime(CLOCK_REALTIME, &post));
+ VERIFY3S(timespec_cmp(&pre, &post), ==, 1);
+
+ VERIFY3S(timespec_cmp(&pre, &ts), ==, 1);
+ VERIFY3S(timespec_cmp(&ts, &post), ==, 1);
+
+ return (0);
+}
diff --git a/usr/src/uts/common/sys/feature_tests.h b/usr/src/uts/common/sys/feature_tests.h
index 363249722e..18b7de3f70 100644
--- a/usr/src/uts/common/sys/feature_tests.h
+++ b/usr/src/uts/common/sys/feature_tests.h
@@ -21,6 +21,7 @@
/*
* Copyright 2013 Garrett D'Amore <garrett@damore.org>
+ * Copyright 2016 Joyent, Inc.
*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
@@ -81,6 +82,10 @@ extern "C" {
* compiler that complies with ISO/IEC 9899:1999, other-
* wise known as the C99 standard.
*
+ * _STDC_C11 Like _STDC_C99 except that the value of __STDC_VERSION__
+ * is 201112L indicating a compiler that compiles with
+ * ISO/IEXC 9899:2011, otherwise known as the C11 standard.
+ *
* _STRICT_SYMBOLS Used in cases where symbol visibility is restricted
* by the standards, and the user has not explicitly
* relaxed the strictness via __EXTENSIONS__.
@@ -91,8 +96,8 @@ extern "C" {
#endif
/*
- * ISO/IEC 9899:1990 and it's revision, ISO/IEC 9899:1999 specify the
- * following predefined macro name:
+ * ISO/IEC 9899:1990 and it's revisions, ISO/IEC 9899:1999 and ISO/IEC
+ * 99899:2011 specify the following predefined macro name:
*
* __STDC__ The integer constant 1, intended to indicate a conforming
* implementation.
@@ -143,9 +148,13 @@ extern "C" {
#endif
/*
- * Compiler complies with ISO/IEC 9899:1999
+ * Compiler complies with ISO/IEC 9899:1999 or ISO/IEC 9989:2011
*/
+#if __STDC_VERSION__ - 0 >= 201112L
+#define _STDC_C11
+#endif
+
#if __STDC_VERSION__ - 0 >= 199901L
#define _STDC_C99
#endif
@@ -415,6 +424,20 @@ extern "C" {
#endif
/*
+ * The following macro defines a value for the ISO C11 _Noreturn
+ * keyword so that _NORETURN_KYWD resolves to "_Noreturn" if
+ * an ISO C11 compiler is used and "" (null string) if any other
+ * compiler is used. This allows for the use of single prototype
+ * declarations regardless of compiler version.
+ */
+#if (defined(__STDC__) && defined(_STDC_C11)) && !defined(__cplusplus)
+#define _NORETURN_KYWD _Noreturn
+#else
+#define _NORETURN_KYWD
+#endif
+
+
+/*
* The following macro indicates header support for the ANSI C++
* standard. The ISO/IEC designation for this is ISO/IEC FDIS 14882.
*/
@@ -427,6 +450,12 @@ extern "C" {
#define _ISO_C_9899_1999
/*
+ * The following macro indicates header support for the C99 standard,
+ * ISO/IEC 9899:2011, Programming Languages - C.
+ */
+#define _ISO_C_9899_2011
+
+/*
* The following macro indicates header support for DTrace. The value is an
* integer that corresponds to the major version number for DTrace.
*/
diff --git a/usr/src/uts/common/sys/isa_defs.h b/usr/src/uts/common/sys/isa_defs.h
index a7855171cd..5c32591db9 100644
--- a/usr/src/uts/common/sys/isa_defs.h
+++ b/usr/src/uts/common/sys/isa_defs.h
@@ -23,6 +23,7 @@
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ * Copyright 2016 Joyent, Inc.
*/
#ifndef _SYS_ISA_DEFS_H
@@ -79,6 +80,9 @@
* The most stringent alignment requirement as specified by the ABI.
* Equal to the maximum of all the above _XXX_ALIGNMENT values.
*
+ * _MAX_ALIGNMENT_TYPE:
+ * The name of the C type that has the value descried in _MAX_ALIGNMENT.
+ *
* _ALIGNMENT_REQUIRED:
* True or false (1 or 0) whether or not the hardware requires the ABI
* alignment.
@@ -256,6 +260,7 @@ extern "C" {
#define _POINTER_ALIGNMENT 8
#define _MAX_ALIGNMENT 16
#define _ALIGNMENT_REQUIRED 1
+#define _MAX_ALIGNMENT_TYPE long double
/*
* Different alignment constraints for the i386 ABI in compatibility mode
@@ -321,6 +326,7 @@ extern "C" {
#define _POINTER_ALIGNMENT 4
#define _MAX_ALIGNMENT 4
#define _ALIGNMENT_REQUIRED 0
+#define _MAX_ALIGNMENT_TYPE long
#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
@@ -428,6 +434,7 @@ extern "C" {
#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 8
#define _POINTER_ALIGNMENT 4
#define _MAX_ALIGNMENT 8
+#define _MAX_ALIGNMENT_TYPE long double
#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
@@ -455,6 +462,7 @@ extern "C" {
#define _LONG_DOUBLE_COMPLEX_ALIGNMENT 16
#define _POINTER_ALIGNMENT 8
#define _MAX_ALIGNMENT 16
+#define _MAX_ALIGNMENT_TYPE long double
#define _LONG_LONG_ALIGNMENT_32 _LONG_LONG_ALIGNMENT
diff --git a/usr/src/uts/common/sys/time_impl.h b/usr/src/uts/common/sys/time_impl.h
index ee2da890e0..4fb2551c73 100644
--- a/usr/src/uts/common/sys/time_impl.h
+++ b/usr/src/uts/common/sys/time_impl.h
@@ -37,8 +37,6 @@
#ifndef _SYS_TIME_IMPL_H
#define _SYS_TIME_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/feature_tests.h>
#ifdef __cplusplus