1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2018 Joyent, Inc.
14  */
15 
16 /*
17  * All we're doing is constantly modifying a thread name while DTrace is
18  * watching us, making sure we don't break.
19  */
20 
21 #include <sys/fcntl.h>
22 #include <pthread.h>
23 #include <stdlib.h>
24 #include <stdio.h>
25 
26 #define	NR_THREADS (100)
27 #define	RUNTIME (30) /* seconds */
28 
29 static void
random_ascii(char * buf,size_t bufsize)30 random_ascii(char *buf, size_t bufsize)
31 {
32 	char table[] = "abcdefghijklmnopqrstuvwxyz"
33 	    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ,.-#'?!";
34 	size_t len = rand() % bufsize;
35 
36 	bzero(buf, bufsize);
37 
38 	for (size_t i = 0; i < len; i++) {
39 		buf[i] = table[rand() % (sizeof (table) - 1)];
40 	}
41 }
42 
43 static void
busy()44 busy()
45 {
46 	struct timeval tv1;
47 	struct timeval tv2;
48 
49 	if (gettimeofday(&tv1, NULL) != 0)
50 		abort();
51 
52 	for (;;) {
53 		static volatile int i;
54 		for (i = 0; i < 2000000; i++)
55 			;
56 
57 		if (gettimeofday(&tv2, NULL) != 0)
58 			abort();
59 
60 		/* janky, but we don't care */
61 		if (tv2.tv_sec != tv1.tv_sec)
62 			return;
63 	}
64 }
65 
66 static void *
thread(void * arg)67 thread(void *arg)
68 {
69 	char name[PTHREAD_MAX_NAMELEN_NP];
70 
71 	for (size_t i = 0; ; i++) {
72 		random_ascii(name, sizeof (name));
73 
74 		if ((i % 100) == 0) {
75 			if (pthread_setname_np(pthread_self(), NULL) != 0)
76 				abort();
77 		} else {
78 			(void) pthread_setname_np(pthread_self(), name);
79 		}
80 
81 		busy();
82 	}
83 
84 	return (NULL);
85 }
86 
87 int
main(int argc,char ** argv)88 main(int argc, char **argv)
89 {
90 	pthread_t tids[NR_THREADS];
91 
92 	for (size_t i = 0; i < NR_THREADS; i++) {
93 		if (pthread_create(&tids[i], NULL, thread, NULL) != 0)
94 			exit(EXIT_FAILURE);
95 	}
96 
97 	sleep(RUNTIME);
98 	exit(EXIT_SUCCESS);
99 }
100