34 #define BLOCKS_PER_PAGE (SSM_MEM_PAGE_SIZE / sizeof(block_t))
37 #define UNINITIALIZED_FREE_BLOCK ((block_t *)0x0)
40 #define END_OF_FREELIST ((block_t *)0x42)
55 static void *(*alloc_page)(void);
58 static void *(*alloc_mem)(
size_t size);
61 static void (*
free_mem)(
void *mem,
size_t size);
89 #ifdef CONFIG_MEM_STATS
101 #ifndef CONFIG_MALLOC_HEAP
112 static inline void alloc_pool(
size_t p) {
116 #ifdef CONFIG_MEM_STATS
137 void *(*alloc_mem_handler)(
size_t),
138 void (*free_mem_handler)(
void *,
size_t)) {
149 VALGRIND_PRINTF(
"Performing leak check at memory initialization.\n");
150 VALGRIND_PRINTF(
"(Checkpoints how much memory is allocated at init time.)\n");
151 VALGRIND_PRINTF(
"\n");
152 VALGRIND_DO_QUICK_LEAK_CHECK;
166 VALGRIND_PRINTF(
"About to destroy SSM allocator. Performing leak check.\n");
167 VALGRIND_PRINTF(
"(Note that leaks from malloc() may be false positives.)\n");
168 VALGRIND_PRINTF(
"\n");
169 VALGRIND_DO_ADDED_LEAK_CHECK;
173 #ifndef CONFIG_MALLOC_HEAP
178 for (
size_t i = 0; i < num_pages; i++)
185 #ifdef CONFIG_MEM_STATS
192 #ifdef CONFIG_MALLOC_HEAP
211 VALGRIND_MALLOCLIKE_BLOCK(m, size, 0, 1);
220 VALGRIND_MAKE_MEM_UNDEFINED(m, size);
226 #ifdef CONFIG_MEM_TRACE
227 fprintf(stderr,
"%p = ssm_mem_alloc(%lu)\n", m, size);
235 #ifdef CONFIG_MEM_TRACE
236 fprintf(stderr,
"%p ssm_mem_free(%lu)\n", m, size);
239 #ifdef CONFIG_MEM_STATS
244 #ifdef CONFIG_MALLOC_HEAP
261 VALGRIND_FREELIKE_BLOCK(m, 0);
314 uint16_t scaled_size =
337 size =
sizeof(
struct ssm_sv);
368 for (
size_t i = 0; i < cnt; i++)
373 for (
size_t i = 0; i < cnt; i++)
377 #ifdef CONFIG_MEM_STATS
#define ssm_adt_heap_size(v)
Compute the size of an ADT already allocated on the heap.
#define ssm_adt_field(v, i)
Access the field of an ADT object.
#define ssm_adt_size(val_count)
Compute the size of a heap-allocated ADT.
ssm_value_t ssm_new_adt_int(uint8_t field_count, uint8_t tag)
Allocate a new ADT object on the heap.
#define ssm_adt_field_count(v)
Obtain number of fields in the ADT pointed by v.
#define ssm_array_element(v, i)
Obtain pointer to the ith element of the array pointed by v.
#define ssm_array_len(v)
The length of an array pointed by v.
#define ssm_array_heap_size(v)
Compute the size an array in the heap from an ssm_value_t.
#define ssm_array_size(count)
Compute the size of an array with its header.
ssm_value_t ssm_new_array_int(uint16_t elems)
Allocate an array on the heap.
ssm_value_t ssm_new_blob_int(uint16_t size)
Allocate a blob on the heap.
#define ssm_blob_size(size)
Compute the size of a blob with its header.
#define ssm_blob_heap_size(v)
Compute the size a blob in the heap.
#define SSM_BLOB_SIZE_SCALE
The size resolution for heap-allocated blobs.
ssm_value_t ssm_new_closure_int(ssm_func_t f, uint8_t arg_cap)
Allocate a closure on the heap.
#define ssm_closure_arg_count(v)
Obtain the number of argument values owned by a closure.
#define ssm_closure_heap_size(v)
Compute the size of a closure already allocated on the heap.
#define ssm_closure_size(val_count)
Compute the size of a closure object.
#define ssm_closure_arg(v, i)
Obtain the ith argument of a closure.
ssm_act_t *(* ssm_func_t)(ssm_act_t *parent, ssm_priority_t prio, ssm_depth_t depth, ssm_value_t *argv, ssm_value_t *ret)
The type signature for all SSM enter functions.
#define SSM_ASSERT(cond)
Throw an internal error.
#define SSM_THROW(reason)
Terminate due to a non-recoverable error, with a specified reason.
@ SSM_INTERNAL_ERROR
Reserved for unforeseen, non-user-facing errors.
void ssm_mem_prealloc(size_t size, size_t num_pages)
Preallocate memory pages to ensure capacity in memory pools.
void ssm_mem_free(void *m, size_t size)
Deallocate memory allocated by ssm_mem_alloc().
void ssm_mem_destroy(void(*free_page_handler)(void *))
Tears down the underlying allocator system.
#define SSM_MEM_POOL_COUNT
Number of memory pools.
void ssm_drops(size_t cnt, ssm_value_t *arr)
Call ssm_drop() on an array of values.
#define ssm_dup(v)
Duplicate a possible heap reference, incrementing its ref count.
#define SSM_MEM_POOL_SIZE(pool)
Compute the size of a memory pool.
#define SSM_MEM_PAGE_SIZE
The size of a memory page; must be greater than SSM_MEM_POOL_MAX.
#define ssm_drop(v)
Drop a reference to a possible heap item, and free it if necessary.
void ssm_drop_final(ssm_value_t v)
Finalize and free a heap object.
void ssm_mem_statistics_collect(ssm_mem_statistics_t *stats)
Collect and return statistics about the heap.
void * ssm_mem_alloc(size_t size)
Allocate a contiguous range of memory.
void ssm_dups(size_t cnt, ssm_value_t *arr)
Call ssm_dup() on an array of values.
void ssm_mem_init(void *(*alloc_page_handler)(void), void *(*alloc_mem_handler)(size_t), void(*free_mem_handler)(void *, size_t))
Initializes the underlying allocator system.
@ SSM_BLOB_K
Blob of arbitrary data, e.g., ssm_blob1.
@ SSM_ARRAY_K
Array of values, e.g., ssm_array1.
@ SSM_CLOSURE_K
Closure object, e.g., ssm_closure1.
@ SSM_TIME_K
64-bit timestamps, ssm_time_t
@ SSM_SV_K
Scheduled variables, ssm_sv_t.
@ SSM_ADT_K
ADT object, e.g., ssm_adt1.
void ssm_unschedule(ssm_sv_t *var)
Unschedule any pending events on a variable.
#define ssm_to_sv(val)
Retrieve ssm_sv pointer pointed to by an ssm_value_t.
ssm_value_t ssm_new_sv_int(ssm_value_t val)
Allocate an ssm_sv on the heap.
#define SSM_NEVER
Time indicating something will never happen.
ssm_value_t ssm_new_time_int(ssm_time_t time)
Allocate a ssm_time on the heap.
uint64_t ssm_time_t
Absolute time; never to overflow.
#define container_of(ptr, type, member)
Obtain the pointer to an outer, enclosing struct.
The internal interface of the SSM runtime.
struct mem_pool mem_pools[SSM_MEM_POOL_COUNT]
Memory pools from SSM_MEM_POOL_MIN to SSM_MEM_POOL_MAX.
static void *(* alloc_page)(void)
Page allocation handler, set by ssm_mem_init().
static size_t live_objects
static size_t objects_allocated
#define BLOCKS_PER_PAGE
The number of blocks in each memory page.
#define UNINITIALIZED_FREE_BLOCK
A "pointer" that points to the next contiguous block in memory.
static size_t pages_allocated[SSM_MEM_POOL_COUNT]
static block_t * find_next_block(block_t *block, size_t pool_size)
static size_t find_pool_size(size_t size)
Find the memory pool for some arbitrary size.
static void(* free_mem)(void *mem, size_t size)
Large memory release handler, set by ssm_mem_init().
#define END_OF_FREELIST
Sentinel value indicating the end of the free list.
static size_t num_pages_allocated
Tracks how many pages have been allocated by alloc_pool().
union block block_t
(The beginning of) a block of memory.
static size_t objects_freed
static void *(* alloc_mem)(size_t size)
Large memory allocation handler, set by ssm_mem_init().
Interface to the SSM runtime.
A memory pool, which maintains a free list.
block_t * free_list_head
Pointer to the beginning of the free list.
The struct template of a heap-allocated closure object.
ssm_func_t f
Enter function pointer.
struct ssm_mm mm
Memory management header.
size_t pages_allocated
Number of pages allocated to this pool.
size_t free_list_length
Length of the free list.
size_t block_size
Size of this pool's blocks.
Statistics for the heap; filled with ssm_mem_statistics_collect().
size_t pages_allocated
Number of pages that have been allocated.
size_t sizeof_ssm_mm
Size of per-object memory management header.
ssm_mem_statistics_pool_t pool[32]
Size of the blocks in each pool.
size_t live_objects
Number of live objects.
size_t objects_allocated
Total number of allocated objects.
size_t pool_count
Number of memory pools.
size_t objects_freed
Total number of object free events.
size_t page_size
Bytes in a memory page.
The memory management metadata "header" for heap-allocated objects.
struct ssm_mm::@0::@1 variant
uint8_t tag
Which variant is inhabited by this object.
union ssm_mm::@0 info
Three "flavors" of information embedded in the header.
uint8_t ref_count
The number of references to this object.
uint8_t kind
The ssm_kind of object this is.
struct ssm_mm::@0::@2 vector
A scheduled variable that supports scheduled updates with triggers.
ssm_time_t later_time
When the variable should be next updated.
ssm_time_t last_updated
When the variable was last updated.
ssm_value_t value
Current value.
ssm_trigger_t * triggers
List of sensitive continuations.
ssm_value_t later_value
Buffered value for delayed assignment.
Heap-allocated time values.
ssm_time_t time
Time value payload.
struct ssm_mm mm
Embedded memory management header.
(The beginning of) a block of memory.
union block * free_list_next
Pointer to the next block.
uint8_t block_buf[1]
Variable-size buffer of the block.
SSM values are either "packed" values or heap-allocated.
struct ssm_mm * heap_ptr
Pointer to a heap-allocated object.