mirror of
https://gitlab.com/embeddable-common-lisp/ecl.git
synced 2026-01-25 05:51:55 -08:00
We will use this operators to allocate the first environment and stacks so that there is no circularity between ecl_boot and starting the garbage collector.
81 lines
1.7 KiB
C
81 lines
1.7 KiB
C
/* -*- Mode: C; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
|
/* vim: set filetype=c tabstop=2 shiftwidth=2 expandtab: */
|
|
|
|
/*
|
|
* memory.c - manual memory managament
|
|
*
|
|
* Copyright (c) 2024 Daniel Kochmański
|
|
*
|
|
* See file 'LICENSE' for the copyright details.
|
|
*
|
|
*/
|
|
|
|
/* -- imports --------------------------------------------------------------- */
|
|
|
|
#include <ecl/ecl.h>
|
|
#include <ecl/ecl-inl.h>
|
|
#include <ecl/internal.h>
|
|
#include <ecl/external.h>
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/* -- implementation -------------------------------------------------------- */
|
|
|
|
static void
|
|
out_of_memory()
|
|
{
|
|
/* FIXME we should signal the STORAGE-EXHAUSTED and allow a potential handler
|
|
an attempt to release some memory:
|
|
|
|
ecl_cerror(ecl_ct_oom_tag);
|
|
goto AGAIN;
|
|
|
|
For now let's crash with an appropriate error. */
|
|
ecl_internal_error("*** manual memory allocator: out of memory\n");
|
|
}
|
|
|
|
void *
|
|
ecl_malloc(cl_index n)
|
|
{
|
|
/* GC-free equivalent of ecl_alloc_atomic. */
|
|
const cl_env_ptr the_env = ecl_process_env_unsafe();
|
|
void *ptr;
|
|
if (!the_env) {
|
|
ptr = malloc(n);
|
|
} else {
|
|
ecl_disable_interrupts_env(the_env);
|
|
ptr = malloc(n);
|
|
ecl_enable_interrupts_env(the_env);
|
|
}
|
|
if (ptr == NULL) out_of_memory();
|
|
return ptr;
|
|
}
|
|
|
|
void
|
|
ecl_free(void *ptr)
|
|
{
|
|
const cl_env_ptr the_env = ecl_process_env_unsafe();
|
|
if (!the_env) {
|
|
free(ptr);
|
|
} else {
|
|
ecl_disable_interrupts_env(the_env);
|
|
free(ptr);
|
|
ecl_enable_interrupts_env(the_env);
|
|
}
|
|
}
|
|
|
|
void *
|
|
ecl_realloc(void *ptr, cl_index osize, cl_index nsize)
|
|
{
|
|
void *p = ecl_malloc(nsize);
|
|
ecl_copy(p, ptr, (osize < nsize) ? osize : nsize);
|
|
ecl_free(ptr);
|
|
return p;
|
|
}
|
|
|
|
void
|
|
ecl_copy(void *dst, void *src, cl_index ndx)
|
|
{
|
|
memcpy(dst, src, ndx);
|
|
}
|