← Back to C-Kernel-Engine Docs Doxygen Source Documentation
 
Loading...
Searching...
No Matches
ckernel_alloc.c File Reference
#include "ckernel_alloc.h"
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

Go to the source code of this file.

Macros

#define _GNU_SOURCE
 
#define HUGE_PAGE_SIZE   (2UL * 1024UL * 1024UL)
 

Functions

static size_t align_up_bytes (size_t n, size_t align)
 
void ck_bump_alloc_free (ck_bump_alloc_t *alloc)
 
int ck_bump_alloc_init (ck_bump_alloc_t *alloc, const char *weights_path, size_t total_size, size_t weights_base, size_t activations_base)
 
int ck_bump_alloc_needs_weight_materialization (const ck_bump_alloc_t *alloc)
 
static void ck_bump_alloc_reset (ck_bump_alloc_t *alloc)
 
void * ck_huge_alloc (size_t bytes)
 
void ck_huge_free (void *ptr, size_t bytes)
 
static ck_huge_alloc_entry_t * detach_allocation (void *ptr)
 
static int env_flag_enabled (const char *name)
 
static int record_allocation (void *ptr, size_t len, int was_mmap)
 

Variables

static ck_huge_alloc_entry_t * g_alloc_list = NULL
 
static pthread_mutex_t g_alloc_mutex = PTHREAD_MUTEX_INITIALIZER
 

Macro Definition Documentation

◆ _GNU_SOURCE

#define _GNU_SOURCE

Definition at line 1 of file ckernel_alloc.c.

◆ HUGE_PAGE_SIZE

#define HUGE_PAGE_SIZE   (2UL * 1024UL * 1024UL)

Definition at line 18 of file ckernel_alloc.c.

Function Documentation

◆ align_up_bytes()

static size_t align_up_bytes ( size_t  n,
size_t  align 
)
static

Definition at line 31 of file ckernel_alloc.c.

32{
33 if (align == 0) return n;
34 return (n + align - 1) & ~(align - 1);
35}

Referenced by ck_bump_alloc_init(), and ck_huge_alloc().

◆ ck_bump_alloc_free()

void ck_bump_alloc_free ( ck_bump_alloc_t alloc)

Definition at line 313 of file ckernel_alloc.c.

314{
315 if (!alloc || !alloc->base) {
316 ck_bump_alloc_reset(alloc);
317 return;
318 }
319
320 if (alloc->mode == CK_BUMP_MODE_MIXED_FILE_BACKED) {
321 if (alloc->mapped_len > 0) {
322 munmap(alloc->base, alloc->mapped_len);
323 }
324 } else if (alloc->mode == CK_BUMP_MODE_ANON) {
325 ck_huge_free(alloc->base, alloc->total_size);
326 }
327
328 ck_bump_alloc_reset(alloc);
329}
static void ck_bump_alloc_reset(ck_bump_alloc_t *alloc)
void ck_huge_free(void *ptr, size_t bytes)
@ CK_BUMP_MODE_ANON
@ CK_BUMP_MODE_MIXED_FILE_BACKED
ck_bump_mode_t mode

References ck_bump_alloc_t::base, ck_bump_alloc_reset(), CK_BUMP_MODE_ANON, CK_BUMP_MODE_MIXED_FILE_BACKED, ck_huge_free(), ck_bump_alloc_t::mapped_len, ck_bump_alloc_t::mode, and ck_bump_alloc_t::total_size.

◆ ck_bump_alloc_init()

int ck_bump_alloc_init ( ck_bump_alloc_t alloc,
const char *  weights_path,
size_t  total_size,
size_t  weights_base,
size_t  activations_base 
)

Definition at line 257 of file ckernel_alloc.c.

262{
263 int force_mixed = 0;
264 int disable_mixed = 0;
265
266 if (!alloc || total_size == 0) {
267 fprintf(stderr, "ck_bump_alloc_init: invalid arguments\n");
268 return -1;
269 }
270
271 ck_bump_alloc_reset(alloc);
272 alloc->total_size = total_size;
273 alloc->weights_base = weights_base;
274 alloc->activations_base = activations_base;
275 force_mixed = env_flag_enabled("CK_BUMP_FORCE_MIXED");
276 disable_mixed = env_flag_enabled("CK_BUMP_DISABLE_MIXED");
277
278 if (weights_base > activations_base || activations_base > total_size) {
279 fprintf(stderr,
280 "ck_bump_alloc_init: invalid bump layout weights=%zu activations=%zu total=%zu\n",
281 weights_base, activations_base, total_size);
282 ck_bump_alloc_reset(alloc);
283 return -1;
284 }
285
286 if (!force_mixed) {
287 void *anon = ck_huge_alloc(total_size);
288 if (anon) {
289 alloc->base = (uint8_t *)anon;
290 alloc->mapped_len = align_up_bytes(total_size, HUGE_PAGE_SIZE);
291 alloc->mode = CK_BUMP_MODE_ANON;
292 return 0;
293 }
294 }
295
296#ifdef __linux__
297 if (!disable_mixed) {
298 if (ck_bump_alloc_try_mixed(alloc, weights_path) == 0) {
299 return 0;
300 }
301 }
302#else
303 (void)weights_path;
304#endif
305
306 fprintf(stderr,
307 "ck_bump_alloc_init: failed to allocate bump arena (%zu bytes, %.2f MiB)\n",
308 total_size, (double)total_size / (1024.0 * 1024.0));
309 ck_bump_alloc_reset(alloc);
310 return -1;
311}
static size_t align_up_bytes(size_t n, size_t align)
static int env_flag_enabled(const char *name)
void * ck_huge_alloc(size_t bytes)
#define HUGE_PAGE_SIZE
size_t activations_base

References ck_bump_alloc_t::activations_base, align_up_bytes(), ck_bump_alloc_t::base, ck_bump_alloc_reset(), CK_BUMP_MODE_ANON, ck_huge_alloc(), env_flag_enabled(), HUGE_PAGE_SIZE, ck_bump_alloc_t::mapped_len, ck_bump_alloc_t::mode, ck_bump_alloc_t::total_size, and ck_bump_alloc_t::weights_base.

◆ ck_bump_alloc_needs_weight_materialization()

int ck_bump_alloc_needs_weight_materialization ( const ck_bump_alloc_t alloc)

Definition at line 331 of file ckernel_alloc.c.

332{
333 if (!alloc) {
334 return 1;
335 }
336 return alloc->mode != CK_BUMP_MODE_MIXED_FILE_BACKED;
337}

References CK_BUMP_MODE_MIXED_FILE_BACKED, and ck_bump_alloc_t::mode.

◆ ck_bump_alloc_reset()

static void ck_bump_alloc_reset ( ck_bump_alloc_t alloc)
static

Definition at line 138 of file ckernel_alloc.c.

139{
140 if (!alloc) {
141 return;
142 }
143 alloc->base = NULL;
144 alloc->total_size = 0;
145 alloc->weights_base = 0;
146 alloc->activations_base = 0;
147 alloc->mapped_len = 0;
148 alloc->weights_file_size = 0;
150}
@ CK_BUMP_MODE_UNINITIALIZED
size_t weights_file_size

References ck_bump_alloc_t::activations_base, ck_bump_alloc_t::base, CK_BUMP_MODE_UNINITIALIZED, ck_bump_alloc_t::mapped_len, ck_bump_alloc_t::mode, ck_bump_alloc_t::total_size, ck_bump_alloc_t::weights_base, and ck_bump_alloc_t::weights_file_size.

Referenced by ck_bump_alloc_free(), and ck_bump_alloc_init().

◆ ck_huge_alloc()

void * ck_huge_alloc ( size_t  bytes)

Allocate a large, contiguous memory region for model weights/activations.

Implementation strategy:

  • Try to allocate 2MB-aligned memory backed by huge pages where possible.
  • Fall back to aligned_alloc + madvise(MADV_HUGEPAGE) when explicit huge pages are not available.

Returns NULL on failure.

Definition at line 70 of file ckernel_alloc.c.

71{
72 size_t len = align_up_bytes(bytes, HUGE_PAGE_SIZE);
73
74 /* First, try explicit huge pages via mmap + MAP_HUGETLB. */
75 void *p = mmap(NULL, len,
76 PROT_READ | PROT_WRITE,
77 MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB,
78 -1, 0);
79 if (p != MAP_FAILED) {
80 if (!record_allocation(p, len, 1)) {
81 munmap(p, len);
82 return NULL;
83 }
84 return p;
85 }
86
87 /* Fallback: aligned_alloc with transparent hugepage hint. */
88 void *q = aligned_alloc(HUGE_PAGE_SIZE, len);
89 if (!q) {
90 fprintf(stderr, "ck_huge_alloc: aligned_alloc failed for %zu bytes: %s\n",
91 len, strerror(errno));
92 return NULL;
93 }
94
95 /* Best-effort hint; ignore errors. */
96 (void)madvise(q, len, MADV_HUGEPAGE);
97 if (!record_allocation(q, len, 0)) {
98 free(q);
99 return NULL;
100 }
101 return q;
102}
static int record_allocation(void *ptr, size_t len, int was_mmap)

Referenced by ck_bump_alloc_init().

◆ ck_huge_free()

void ck_huge_free ( void *  ptr,
size_t  bytes 
)

Free memory allocated by ck_huge_alloc.

The bytes parameter should be the same size passed to ck_huge_alloc.

Definition at line 104 of file ckernel_alloc.c.

105{
106 if (!ptr || bytes == 0) {
107 return;
108 }
109
110 ck_huge_alloc_entry_t *entry = detach_allocation(ptr);
111 if (!entry) {
112 /* Fall back to malloc/free if the allocation wasn't tracked. */
113 free(ptr);
114 return;
115 }
116
117 if (entry->was_mmap) {
118 munmap(ptr, entry->len);
119 } else {
120 free(ptr);
121 }
122
123 free(entry);
124}
static ck_huge_alloc_entry_t * detach_allocation(void *ptr)

Referenced by ck_bump_alloc_free().

◆ detach_allocation()

static ck_huge_alloc_entry_t * detach_allocation ( void *  ptr)
static

Definition at line 53 of file ckernel_alloc.c.

54{
55 pthread_mutex_lock(&g_alloc_mutex);
56 ck_huge_alloc_entry_t **node = &g_alloc_list;
57 while (*node) {
58 if ((*node)->ptr == ptr) {
59 ck_huge_alloc_entry_t *entry = *node;
60 *node = entry->next;
61 pthread_mutex_unlock(&g_alloc_mutex);
62 return entry;
63 }
64 node = &(*node)->next;
65 }
66 pthread_mutex_unlock(&g_alloc_mutex);
67 return NULL;
68}
static ck_huge_alloc_entry_t * g_alloc_list
static pthread_mutex_t g_alloc_mutex

References g_alloc_list, and g_alloc_mutex.

Referenced by ck_huge_free().

◆ env_flag_enabled()

static int env_flag_enabled ( const char *  name)
static

Definition at line 126 of file ckernel_alloc.c.

127{
128 const char *value = getenv(name);
129 if (!value || !*value) {
130 return 0;
131 }
132 if (strcmp(value, "0") == 0 || strcasecmp(value, "false") == 0 || strcasecmp(value, "no") == 0) {
133 return 0;
134 }
135 return 1;
136}

Referenced by ck_bump_alloc_init().

◆ record_allocation()

static int record_allocation ( void *  ptr,
size_t  len,
int  was_mmap 
)
static

Definition at line 37 of file ckernel_alloc.c.

38{
39 ck_huge_alloc_entry_t *entry = malloc(sizeof(*entry));
40 if (!entry) {
41 return 0;
42 }
43 entry->ptr = ptr;
44 entry->len = len;
45 entry->was_mmap = was_mmap;
46 pthread_mutex_lock(&g_alloc_mutex);
47 entry->next = g_alloc_list;
48 g_alloc_list = entry;
49 pthread_mutex_unlock(&g_alloc_mutex);
50 return 1;
51}

References g_alloc_list, and g_alloc_mutex.

Referenced by ck_huge_alloc().

Variable Documentation

◆ g_alloc_list

ck_huge_alloc_entry_t* g_alloc_list = NULL
static

Definition at line 29 of file ckernel_alloc.c.

Referenced by detach_allocation(), and record_allocation().

◆ g_alloc_mutex

pthread_mutex_t g_alloc_mutex = PTHREAD_MUTEX_INITIALIZER
static

Definition at line 28 of file ckernel_alloc.c.

Referenced by detach_allocation(), and record_allocation().