Skip to content

Instantly share code, notes, and snippets.

@johnsonjh
Created November 27, 2023 11:46
Show Gist options
  • Save johnsonjh/d49145a83335236318bd38d8f8456954 to your computer and use it in GitHub Desktop.
Save johnsonjh/d49145a83335236318bd38d8f8456954 to your computer and use it in GitHub Desktop.
#define _GNU_SOURCE
#define _ALL_SOURCE
#include <pthread.h>
#include <stdarg.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
static uint32_t g_sleep_time = 4;
_Thread_local pid_t g_tls = -1;
static uint64_t
get_time_microseconds ()
{
struct timespec ts;
if (clock_gettime (CLOCK_MONOTONIC, &ts) == 0)
return ts.tv_sec * 1000000ULL + ts.tv_nsec / 1000ULL;
return 0;
}
static void
logit (const char *format, ...)
{
va_list args;
char buf[1024];
snprintf (buf, sizeof (buf), "[#%2d LWP:%d 0x%lx] %s", g_tls + 1, gettid (),
(unsigned long)pthread_self (), format);
va_start (args, format);
vprintf (buf, args);
va_end (args);
}
static void *
thread_proc (void *arg)
{
g_tls = (int)(intptr_t)arg;
uint64_t t0 = get_time_microseconds ();
if (!t0)
{
logit ("sleep(%u)\n", g_sleep_time);
sleep (g_sleep_time);
}
else
{
uint64_t last = t0;
logit ("busy loop %u\n", g_sleep_time);
for (;;)
{
uint64_t t1 = get_time_microseconds ();
if (t1 - t0 >= g_sleep_time * 1000000)
break;
if (t1 - last >= 1000000)
{
logit ("%.2f seconds\n", (t1 - t0) / 1000000.0f);
last = t1;
}
}
}
pid_t tid = gettid ();
logit ("pthread_exit(%d)\n", tid);
pthread_exit ((void *)(intptr_t)tid);
/* unreachable */
return 0;
}
int
main (int argc, char *argv[])
{
pthread_t threadids[256];
static const size_t max_threads = sizeof (threadids) / sizeof (threadids[0]);
size_t num_threads = (argc > 1) ? atoi (argv[1]) : 6;
if (num_threads < 2)
num_threads = 2;
else if (num_threads > max_threads)
num_threads = max_threads;
logit ("num_threads:%zu\n", num_threads);
for (size_t i = 0; i < num_threads; i++)
{
int err = pthread_create (&(threadids[i]), NULL, &thread_proc,
(void *)(intptr_t)i);
logit ("pthread_create:%d (%s) pthread_t:%lx\n", err, strerror (err),
threadids[i]);
}
sleep (1);
for (size_t i = 0; i < num_threads; i++)
{
logit ("Waiting for thread #%zu\n", i);
void *status = NULL;
int rc = pthread_join (threadids[i], &status);
logit ("Thread #%zu rc:%d status:%d\n", i, rc, (int)(intptr_t)status);
}
logit ("done.\n");
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment