Serene Runtime 1.0.0
C runtime for the Serene programming language
Loading...
Searching...
No Matches
stack_posix.c File Reference
#include <stdint.h>
#include "serene/rt/fiber.h"
#include "serene/rt/mm/interface.h"
#include "serene/utils.h"
#include <sys/mman.h>
Include dependency graph for stack_posix.c:

Go to the source code of this file.

Macros

#define STACK_FLAGS   MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_STACK
 

Functions

srn_fiber_stack_t srn_fiber_stack_alloc (size_t size)
 Allocate a stack of at least size usable bytes plus a guard page, or SRN_FIBER_DEFAULT_STACK_SIZE when size is 0.
 
void srn_fiber_stack_free (srn_fiber_stack_t stack)
 

Macro Definition Documentation

◆ STACK_FLAGS

#define STACK_FLAGS   MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_STACK

Definition at line 30 of file stack_posix.c.

Function Documentation

◆ srn_fiber_stack_alloc()

srn_fiber_stack_t srn_fiber_stack_alloc ( size_t size)
nodiscard

Allocate a stack of at least size usable bytes plus a guard page, or SRN_FIBER_DEFAULT_STACK_SIZE when size is 0.

Platform specific.

Definition at line 34 of file stack_posix.c.

34 {
35 const size_t os_page_size = srn_mm_get_os_page_size();
36 const size_t desired_size = size ? size : (size_t)SRN_FIBER_DEFAULT_STACK_SIZE;
37
38 // Round upto a multiple of PAGE size
39 const size_t usable = (desired_size + os_page_size - 1) & ~(os_page_size - 1);
40 // Add a page to act as a guard page
41 const size_t total = usable + os_page_size;
42
43 // Since stack grows downward, the starting point where mmap returns will
44 // be the end of the stack for us. We could of used MAP_GROWSDOWN to
45 // change the behaviour, but that causes the stack to grow, but we have
46 // a fix stack.
47 void *end = mmap(nullptr, total, PROT_READ | PROT_WRITE, STACK_FLAGS,
48 // according to the man page, for anonymous mode fd should be -1
49 -1,
50 // according to the man page, for anonymous mode offset should be 0
51 0);
52
53 PANIC_IF(end == MAP_FAILED, "Failed to allocate the stack for the fiber subsystem");
54
55 if (mprotect(end, os_page_size, PROT_NONE) == -1) {
56 munmap(end, total);
57 PANIC("Failed to allocate the guard page for the fiber subsystem");
58 }
59
60 const uintptr_t start = (uintptr_t)end + (uintptr_t)total;
61 const uintptr_t limit = (uintptr_t)end + (uintptr_t)os_page_size;
62
63 srn_fiber_stack_t stack = {.start = (void *)start, .limit = (void *)limit, .guard = end};
64 return stack;
65}
static atomic_int total
Definition 05_parallel.c:42
size_t srn_mm_get_os_page_size(void)
Retutrns the OS page size.
Definition default.c:270
#define SRN_FIBER_DEFAULT_STACK_SIZE
Default size of every fiber stack.
Definition fiber.h:138
#define STACK_FLAGS
Definition stack_posix.c:30
One stack per fiber, mapped with a guard page at the low end so an overflow faults deterministically ...
Definition fiber.h:168
#define PANIC_IF(cond, msg)
Definition utils.h:57
#define PANIC(msg)
Definition utils.h:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ srn_fiber_stack_free()

void srn_fiber_stack_free ( srn_fiber_stack_t stack)

Definition at line 67 of file stack_posix.c.

67 {
68 munmap(stack.guard, (uintptr_t)stack.start - (uintptr_t)stack.guard);
69}
void * guard
The protected page to detect stack overflows.
Definition fiber.h:174
void * start
High end, stack pointer initialises to this address.
Definition fiber.h:170
Here is the caller graph for this function: