Skip to content

Instantly share code, notes, and snippets.

@thoughtpolice
Created June 25, 2013 06:12
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thoughtpolice/5856323 to your computer and use it in GitHub Desktop.
Save thoughtpolice/5856323 to your computer and use it in GitHub Desktop.
Über fast thread-local storage on OS X
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
/** Snipped from pthread_machdep.h */
#define __PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4 94
extern __inline__ void *
_pthread_getspecific_direct(unsigned long slot) {
void* ret;
#if defined(__i386__) || defined(__x86_64__)
__asm__("mov %%gs:%1, %0" : "=r" (ret) : "m" (*(void **)(slot * sizeof(void *))));
#else
#error "No definition of pthread_getspecific_direct!"
#endif
return ret;
}
/* To be used with static constant keys only */
extern __inline__ int
_pthread_setspecific_direct(unsigned long slot, void * val)
{
#if defined(__x86_64__)
/* PIC is free and cannot be disabled, even with: gcc -mdynamic-no-pic ... */
__asm__("movq %1,%%gs:%0" : "=m" (*(void **)(slot * sizeof(void *))) : "rn" (val));
#else
#error "No definition of pthread_setspecific_direct!"
#endif
return 0;
}
/** End snippets */
static const pthread_key_t fooKey =
__PTK_FRAMEWORK_JAVASCRIPTCORE_KEY4;
#define GET_FOO() ((void*)(_pthread_getspecific_direct(fooKey)))
#define SET_FOO(to) (_pthread_setspecific_direct(fooKey, to))
void* f1(void* x) {
int* tmp;
SET_FOO(x);
sleep(10);
tmp = GET_FOO();
printf("thread #1: foo = %p/%d\n", tmp, *tmp);
/* el fin */
free(x);
pthread_exit(0);
}
void* f2(void* x) {
int* tmp;
sleep(5);
SET_FOO(x);
tmp = GET_FOO();
printf("thread #2: foo = %p/%d\n", tmp, *tmp);
/* el fin */
free(x);
pthread_exit(0);
}
int main(int ac, char* av[]) {
int foobar = 0;
if (ac < 2) foobar = 10;
else foobar = atoi(av[1]);
printf("[MAIN] default value = %d\n", foobar);
/* initialize thread-local data structures */
int* i1 = malloc(sizeof(*i1));
int* i2 = malloc(sizeof(*i2));
*i1 = foobar+1;
*i2 = foobar+2;
printf("[MAIN] mallocs: thr1 = %p; thr2 = %p\n", i1, i2);
/* initialize threads */
pthread_t thr1, thr2;
pthread_create(&thr1, NULL, &f1, i1);
pthread_create(&thr2, NULL, &f2, i2);
pthread_join(thr1, NULL);
pthread_join(thr2, NULL);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment