summaryrefslogtreecommitdiff
path: root/usr/src/test
diff options
context:
space:
mode:
authorJohn Levon <john.levon@joyent.com>2018-10-08 15:34:11 +0100
committerDan McDonald <danmcd@joyent.com>2018-10-19 16:40:54 -0400
commitab618543cc6fc4bc273c077ef5d247961cdb29d4 (patch)
tree24c80e35e958a4c5fef77d444eacb1b4f45798a2 /usr/src/test
parent62f63298eba531d48f87aa8c2089298cb7821962 (diff)
downloadillumos-joyent-ab618543cc6fc4bc273c077ef5d247961cdb29d4.tar.gz
8158 Want named threads API
9857 proc manpages should have LIBRARY section Reviewed by: Andy Fiddaman <andy@omniosce.org> Reviewed by: Gordon Ross <gwr@nexenta.com> Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/test')
-rw-r--r--usr/src/test/libc-tests/runfiles/default.run3
-rw-r--r--usr/src/test/libc-tests/tests/threads/Makefile4
-rw-r--r--usr/src/test/libc-tests/tests/threads/thread_name.c278
3 files changed, 282 insertions, 3 deletions
diff --git a/usr/src/test/libc-tests/runfiles/default.run b/usr/src/test/libc-tests/runfiles/default.run
index 9c7e893cf6..cde5a5f8c8 100644
--- a/usr/src/test/libc-tests/runfiles/default.run
+++ b/usr/src/test/libc-tests/runfiles/default.run
@@ -12,7 +12,7 @@
#
# Copyright (c) 2012 by Delphix. All rights reserved.
# Copyright 2014 Garrett D'Amore <garrett@damore.org>
-# Copyright 2017 Joyent, Inc.
+# Copyright 2018 Joyent, Inc.
#
[DEFAULT]
@@ -88,6 +88,7 @@ timeout = 600
[/opt/libc-tests/tests/set_constraint_handler_s.32]
[/opt/libc-tests/tests/set_constraint_handler_s.64]
[/opt/libc-tests/tests/strerror]
+[/opt/libc-tests/tests/thread_name]
[/opt/libc-tests/tests/timespec_get.32]
[/opt/libc-tests/tests/timespec_get.64]
diff --git a/usr/src/test/libc-tests/tests/threads/Makefile b/usr/src/test/libc-tests/tests/threads/Makefile
index 1e73e7b8c7..31cb1ddefe 100644
--- a/usr/src/test/libc-tests/tests/threads/Makefile
+++ b/usr/src/test/libc-tests/tests/threads/Makefile
@@ -10,7 +10,7 @@
#
#
-# Copyright 2016 Joyent, Inc.
+# Copyright 2018 Joyent, Inc.
#
include $(SRC)/Makefile.master
@@ -18,7 +18,7 @@ include $(SRC)/Makefile.master
ROOTOPTPKG = $(ROOT)/opt/libc-tests
TESTDIR = $(ROOTOPTPKG)/tests
-PROGS = pthread_attr_get_np
+PROGS = pthread_attr_get_np thread_name
include $(SRC)/cmd/Makefile.cmd
include $(SRC)/test/Makefile.com
diff --git a/usr/src/test/libc-tests/tests/threads/thread_name.c b/usr/src/test/libc-tests/tests/threads/thread_name.c
new file mode 100644
index 0000000000..b164272644
--- /dev/null
+++ b/usr/src/test/libc-tests/tests/threads/thread_name.c
@@ -0,0 +1,278 @@
+/*
+ * 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 2018 Joyent, Inc.
+ */
+
+/*
+ * Some basic pthread name API tests.
+ */
+
+#include <sys/stat.h>
+#include <pthread.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <thread.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <err.h>
+
+
+/*ARGSUSED*/
+static void *
+thr(void *unused)
+{
+ (void) sleep(100);
+ return (NULL);
+}
+
+/*ARGSUSED*/
+int
+main(int argc, char *argv[])
+{
+ char name[PTHREAD_MAX_NAMELEN_NP];
+ pthread_attr_t attr;
+ char path[PATH_MAX];
+ pthread_t tid;
+ ssize_t n;
+ int test;
+ int rc;
+ int fd;
+
+ /* Default thread name is empty string. */
+ test = 1;
+
+ rc = pthread_getname_np(pthread_self(), name, sizeof (name));
+
+ if (rc != 0 || strcmp(name, "") != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* Can set name. */
+ test = 2;
+
+ (void) strlcpy(name, "main", sizeof (name));
+ rc = pthread_setname_np(pthread_self(), name);
+
+ if (rc != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_getname_np(pthread_self(), name, sizeof (name));
+
+ if (rc != 0 || strcmp(name, "main") != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* ERANGE check. */
+ test = 3;
+
+ rc = pthread_getname_np(pthread_self(), name, 2);
+
+ if (rc != ERANGE)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* EINVAL check. */
+ test = 4;
+
+ rc = pthread_getname_np(pthread_self(), NULL, sizeof (name));
+
+ if (rc != EINVAL)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* can clear thread name. */
+ test = 5;
+
+ rc = pthread_setname_np(pthread_self(), NULL);
+
+ if (rc != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_getname_np(pthread_self(), name, sizeof (name));
+
+ if (rc != 0 || strcmp(name, "") != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* non-existent thread check. */
+ test = 6;
+
+ rc = pthread_getname_np(808, name, sizeof (name));
+
+ if (rc != ESRCH)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_setname_np(808, "state");
+
+ if (rc != ESRCH)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* too long a name. */
+ test = 7;
+
+ rc = pthread_setname_np(pthread_self(),
+ "12345678901234567890123456789012");
+
+ if (rc != ERANGE)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* can name another thread. */
+ test = 8;
+
+ rc = pthread_create(&tid, NULL, thr, NULL);
+
+ if (rc != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_setname_np(tid, "otherthread");
+
+ if (rc != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* attr tests. */
+ test = 9;
+
+ (void) pthread_attr_init(&attr);
+
+ rc = pthread_attr_setname_np(&attr,
+ "12345678901234567890123456789012");
+
+ if (rc != ERANGE)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_attr_setname_np(&attr, "thread2");
+
+ if (rc != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_attr_getname_np(&attr, NULL, sizeof (name));
+
+ if (rc != EINVAL)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_attr_getname_np(&attr, name, 2);
+
+ if (rc != ERANGE)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* does the attr actually apply? */
+ test = 10;
+
+ rc = pthread_create(&tid, &attr, thr, NULL);
+
+ if (rc != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_getname_np(tid, name, sizeof (name));
+
+ if (rc != 0 || strcmp(name, "thread2") != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* proc read tests */
+ test = 11;
+
+ (void) snprintf(path, sizeof (path),
+ "/proc/self/lwp/%d/lwpname", (int)tid);
+
+ fd = open(path, O_RDWR);
+
+ if (fd == -1)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
+
+ n = read(fd, name, sizeof (name));
+
+ if (n != sizeof (name) || strcmp(name, "thread2") != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ if (lseek(fd, 0, SEEK_SET) != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
+
+ n = read(fd, name, PTHREAD_MAX_NAMELEN_NP * 2);
+
+ if (n != sizeof (name) || strcmp(name, "thread2") != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ if (lseek(fd, 0, SEEK_SET) != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
+
+ n = read(fd, name, 4);
+
+ if (n != 4 || strncmp(name, "thre", 4) != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* proc write tests */
+ test = 12;
+
+ if (lseek(fd, 0, SEEK_SET) != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
+
+ n = write(fd, "1234567890123456789012345678901",
+ PTHREAD_MAX_NAMELEN_NP);
+
+ if (n != PTHREAD_MAX_NAMELEN_NP)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
+
+ if (lseek(fd, 0, SEEK_SET) != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
+
+ n = write(fd, "foo", sizeof ("foo"));
+
+ if (n != sizeof ("foo"))
+ errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
+
+ if (lseek(fd, 0, SEEK_SET) != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, errno);
+
+ n = read(fd, name, sizeof (name));
+
+ if (n != sizeof (name) || strcmp(name, "foo") != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ (void) close(fd);
+
+ /* thr_* API. */
+ test = 13;
+
+ rc = thr_setname(thr_self(), "main");
+
+ if (rc != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = thr_getname(thr_self(), name, sizeof (name));
+
+ if (rc != 0 || strcmp(name, "main") != 0)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ /* badness */
+ test = 14;
+
+ rc = thr_setname(thr_self(), "\033]0;messeduptitle\a");
+
+ if (rc != EINVAL)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = thr_setname(thr_self(), "ab\177\177\n");
+
+ if (rc != EINVAL)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_attr_setname_np(&attr, "\033]0;messeduptitle\a");
+
+ if (rc != EINVAL)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ rc = pthread_attr_setname_np(&attr, "ab\177\177\n");
+
+ if (rc != EINVAL)
+ errx(EXIT_FAILURE, "test %d failed with %d", test, rc);
+
+ return (EXIT_SUCCESS);
+}