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
  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
  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 *
  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
  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 }