Simple coroutine library / objects in plain C Snapshot
Classes | Typedefs | Enumerator | Functions | Variables
STACKS

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
STACKStagSTACK_ENTRY::stacks

Detailed Description

a pool of stacks for a threading package.


Typedef Documentation

typedef struct tagSTACK_ENTRY STACK_ENTRY
typedef struct tagSTACKS STACKS

Function Documentation

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)

Definition at line 107 of file stacks.c.

{
  STACKS *stack = entry->stacks;
  DLIST_push_front( &stack->root, &entry->entry );
  return 0;
}

Variable Documentation

Definition at line 20 of file stacks.h.

Definition at line 21 of file stacks.h.

Definition at line 22 of file stacks.h.

Definition at line 23 of file stacks.h.

Definition at line 28 of file stacks.h.

Definition at line 29 of file stacks.h.