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
29static void
30random_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
43static void
44busy()
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
66static void *
67thread(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
87int
88main(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