#ifndef PERTHREAD_H
#define PERTHREAD_H 1
#include <pthread.h>
#include <stdlib.h>

/* PER_THREAD(type, name):
 * Create a thread-local key, which is a pointer to thread-local storage for
 * the given type. Memory is allocated when first needed
 */
#define PER_THREAD(type, name) \
static pthread_once_t __ ## name ## _init = PTHREAD_ONCE_INIT; \
static pthread_key_t __ ## name ## _location; \
void __init_ ## name (void) { \
    pthread_key_create(&__ ## name ## _location, free);\
}\
int *__get_ ## name ## _location(void) { \
    void *ptr; \
    (void) pthread_once(&__ ## name ## _init, __init_ ## name); \
    ptr = pthread_getspecific(__ ## name ## _location); \
    if(!ptr) { \
        ptr = malloc(sizeof(type)); \
        pthread_setspecific(__ ## name ## _location, ptr); \
    } \
    return (type*)ptr; \
}

#endif
