|
Simple coroutine library / objects in plain C Snapshot
|
a pool of stacks for a threading package. More...
Classes | |
| struct | tagSTACKS |
| struct | tagSTACK_ENTRY |
Typedefs | |
| typedef struct tagSTACKS | STACKS |
| typedef struct tagSTACK_ENTRY | STACK_ENTRY |
Functions | |
| int | STACKS_init (STACKS *stack, int num_stacks, int pages_per_stack) |
| int | STACKS_destroy (STACKS *stack) |
| void * | STACKS_get (STACKS *stack, STACK_ENTRY **rentry) |
| int | STACKS_release (STACK_ENTRY *entry) |
| M_INLINE size_t | STACKS_get_stack_size (STACKS *stack) |
Variables | |
| size_t | tagSTACKS::mapping_length |
| int | tagSTACKS::num_stacks |
| size_t | tagSTACKS::one_stack_size |
| DLIST | tagSTACKS::root |
| void * | tagSTACK_ENTRY::stack_start |
| STACKS * | tagSTACK_ENTRY::stacks |
a pool of stacks for a threading package.
| typedef struct tagSTACK_ENTRY STACK_ENTRY |
| int STACKS_destroy | ( | STACKS * | stack | ) |
Definition at line 83 of file stacks.c.
{
if ( DLIST_size( &stack->root) != (size_t) stack->num_stacks ) {
return -1;
}
if (munmap( stack->mapping, stack->mapping_length)) {
return -1;
}
return 0;
}
| void* STACKS_get | ( | STACKS * | stack, |
| STACK_ENTRY ** | rentry | ||
| ) |
Definition at line 96 of file stacks.c.
{
STACK_ENTRY *entry;
if (DLIST_isempty( &stack->root ) ) {
return 0;
}
entry = (STACK_ENTRY *) DLIST_pop_front( &stack->root );
*rentry = entry;
return entry->stack_start;
}
| M_INLINE size_t STACKS_get_stack_size | ( | STACKS * | stack | ) |
Definition at line 38 of file stacks.h.
{
return stack->one_stack_size;
}
| int STACKS_init | ( | STACKS * | stack, |
| int | num_stacks, | ||
| int | pages_per_stack | ||
| ) |
Definition at line 22 of file stacks.c.
{
int page_size;
size_t len, one_stack_size;
STACK_DIR dir;
STACK_ENTRY *entry;
uint8_t *mapping, *stack_start;
uint8_t *guard_page;
int i;
page_size = sysconf( _SC_PAGE_SIZE );
one_stack_size = page_size * pages_per_stack;
len = num_stacks * one_stack_size;
dir = stack_direction();
mapping = (uint8_t *) mmap( 0 , len, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS
#if 0
#ifdef MAP_STACK
| MAP_STACK
#endif
#endif
, -1, 0 );
if (!mapping) {
return -1;
}
//fprintf( stderr, "all stacks %p - %p\n", mapping, mapping + len );
stack->mapping = mapping;
stack->mapping_length = len;
stack->num_stacks = num_stacks;
stack->one_stack_size = one_stack_size - page_size;
DLIST_init( &stack->root );
for( i = 0; i < num_stacks; i ++ ) {
stack_start = mapping + ( i * one_stack_size);
if (dir == STACK_DIR_GROWING_DOWN) {
//stack_start = mapping + ( (i + 1) * one_stack_size) - 1;
guard_page = mapping + (i * one_stack_size);
} else {
guard_page = mapping + ( i + 1 ) * one_stack_size - page_size;
}
if (mprotect( guard_page , page_size, PROT_NONE )) {
return -1;
}
entry = (STACK_ENTRY *) malloc( sizeof( STACK_ENTRY ) );
if (!entry) {
return -1;
}
entry->stack_start = stack_start;
entry->stacks = stack;
DLIST_push_back( &stack->root, &entry->entry );
}
return 0;
}
| int STACKS_release | ( | STACK_ENTRY * | entry | ) |
| size_t tagSTACKS::mapping_length |
| size_t tagSTACKS::one_stack_size |
| DLIST tagSTACKS::root |
1.7.4