darling-libobjc2/pool.h
theraven 2d84b96a72 Tidied up some bits by creating private headers for private data structures.
Imported selector table code frm the Étoilé runtime.  We can now make dispatch type dependent with a -D switch.  Not enabled yet, but it will be enabled in a warning mode soon - I consider preferable to the existing GNU and Apple solution of corrupting the stack.
2010-05-13 22:29:56 +00:00

54 lines
1.2 KiB
C

#include <stdlib.h>
#include "lock.h"
#ifndef POOL_TYPE
#error POOL_TYPE must be defined
#endif
#ifndef POOL_TYPE
#error POOL_NAME must be defined
#endif
// Horrible multiple indirection to satisfy the weird precedence rules in cpp
#define REALLY_PREFIX_SUFFIX(x,y) x ## y
#define PREFIX_SUFFIX(x, y) REALLY_PREFIX_SUFFIX(x, y)
#define NAME(x) PREFIX_SUFFIX(POOL_NAME, x)
#define PAGE_SIZE 4096
// Malloc one page at a time.
#define POOL_SIZE ((PAGE_SIZE) / sizeof(POOL_TYPE))
static POOL_TYPE* NAME(_pool);
static int NAME(_pool_next_index) = -1;
#ifdef THREAD_SAFE_POOL
static mutex_t NAME(_lock);
#define LOCK_POOL() LOCK(&POOL_NAME##_lock)
#define UNLOCK_POOL() LOCK(&POOL_NAME##_lock)
#else
#define LOCK_POOL()
#define UNLOCK_POOL()
#endif
static inline POOL_TYPE*NAME(_pool_alloc)(void)
{
LOCK_POOL();
if (0 > NAME(_pool_next_index))
{
NAME(_pool) = malloc(PAGE_SIZE);
NAME(_pool_next_index) = POOL_SIZE - 1;
}
POOL_TYPE* new = &NAME(_pool)[NAME(_pool_next_index)--];
UNLOCK_POOL();
return new;
}
#undef NAME
#undef POOL_SIZE
#undef PAGE_SIZE
#undef POOL_NAME
#undef POOL_TYPE
#undef LOCK_POOL
#undef UNLOCK_POOL
#ifdef THREAD_SAFE_POOL
#undef THREAD_SAFE_POOL
#endif