Use Thread-Local storage:
#define KEYS_MAXIMUM 2048
__thread void * keys[KEYS_MAXIMUM];
To allow destructors you might use:
typedef struct
{
void * p;
void (*f) (void *);
} Key
__thread Key * keys[KEYS_MAXIMUM];
All that is missing here is some wrappers mimicing the pthread_key*
API.