Make a brk/sbrk emulation.

Mac OS X seems to have some difficulties with brk/sbrk (maybe with the
4MB heap limit), and replace all the allocation logic will be prone to
errors, I'll add a new define and lib to emulate brk/sbrk using more
standard allocation methods. By default the heap is 64MB, it should be
enough.
This commit is contained in:
Manoel Trapier 2013-03-27 15:49:29 +01:00 committed by Manoël Trapier
parent e92393d6f3
commit 5f00cd2e53
8 changed files with 134 additions and 5 deletions

View File

@ -10,4 +10,20 @@ int brk(void * addr);
char *mktemp(char *template);
#endif
#ifdef EMULATE_BRK
void *sbrk_emu(int increment);
int brk_emu(void * addr);
#ifdef sbrk
#undef sbrk
#endif
#ifdef brk
#undef brk
#endif
#define sbrk sbrk_emu
#define brk brk_emu
#endif
#endif /* H_MISSING_H */

20
modules/src/sbrk/pmfile Normal file
View File

@ -0,0 +1,20 @@
-- $Source$
-- $State$
local d = "modules/src/sbrk/"
lib_sbrk = file (LIBDIR.."libsbrk.a")
module_sbrk = clibrary {
cfile (d.."sbrk_emu.c"),
outputs = {"%U%/libsbrk.a"},
install = {
pm.install(LIBDIR.."libsbrk.a"),
}
}
-- Revision history
-- $Log$
-- Revision 1.1 2013/03/27 godzil
-- First version.
--

View File

@ -0,0 +1,83 @@
/*
* The Amsterdam Compiler Kit
* See the copyright notice in the ACK home directory, in the file "Copyright".
*/
/*
* sbrk(), brk() emulation based on calloc()
* Based on version from D A Gwyn
* 02-Mar-1990 D A Gwyn
* http://www.linuxmisc.com/10-unix-questions/0875f91c36e18724.htm
*/
#include <stdio.h>
#include <errno.h> /* for errno, ENOMEM */
#if __STDC__
#include <stdlib.h> /* for calloc */
#else
extern char *calloc();
#endif
/* Allocate 64MB to brk/sbrk should be enough for such application */
#ifndef HEAP_SIZE /* with 32-bit ints, 0x200000 is recommended */
#define HEAP_SIZE 0x4000000 /* size of simulated heap, in bytes */
#endif
#define BRK_OK 0
#define BRK_ERR (-1)
#define SBRK_ERR ((void *)-1) /* horrible interface design */
static void *bottom = NULL; /* bottom of calloc()ed pseudo-heap */
static void *brkval = NULL; /* current value of simulated break */
int brk_emu( void *endds )
{
int offset;
if ( bottom == NULL )
{
if ( (bottom = calloc( HEAP_SIZE, 1 )) == 0 )
{
return BRK_ERR; /* unable to set up pseudo-heap */
}
else
{
brkval = bottom;
}
}
if ( (offset = endds - bottom) < 0 || offset > HEAP_SIZE )
{
errno = ENOMEM;
return BRK_ERR; /* attempt to set break out of heap */
}
else
{
brkval = endds;
return BRK_OK;
}
}
void *sbrk_emu(int incr)
{
int offset;
if ( bottom == 0 )
{
if ( (bottom = (char *)calloc( HEAP_SIZE, 1 )) == 0 )
{
return SBRK_ERR; /* unable to set up heap */
}
else
{
brkval = bottom;
}
}
if ( (offset = (brkval - bottom) + incr) < 0 || offset > HEAP_SIZE )
{
errno = ENOMEM;
return SBRK_ERR; /* attempt to set break out of heap */
}
else
{
char *oldbrk = brkval;
brkval += incr;
return oldbrk;
}
}

View File

@ -6,6 +6,7 @@
#include "system.h"
#include <unistd.h>
#include <missing_proto.h>
char *sys_break(int incr)
{

9
pmfile
View File

@ -19,6 +19,8 @@ CINCLUDES = {
include "util/data/pmfile"
include "modules/src/sbrk/pmfile"
include "util/LLgen/pmfile-ack"
include "modules/src/alloc/pmfile"
@ -104,6 +106,9 @@ include "plat/nes/pmfile" -- NES
default = group {
-- Lots of things use LLgen, so we need to build it first.
-- Need it before anything else! (even LLgen depends on it)
module_sbrk,
tool_LLgen,
-- Some of the dependency management across modules isn't entirely
@ -181,8 +186,8 @@ default = group {
-- Build the platforms.
platform_pc86,
platform_linux386,
platform_cpm,
-- platform_linux386,
-- platform_cpm,
-- platform_nes,
}

View File

@ -26,6 +26,8 @@ tool_LLgen = cprogram {
cfile (d.."src/Lpars.c"),
cfile (d.."src/tokens.c"),
lib_sbrk,
outputs = {"%U%/LLgen"},
install = pm.install("%TOOLDIR%LLgen")
}

View File

@ -20,6 +20,7 @@ tool_led = cprogram {
lib_string,
lib_object,
lib_sbrk,
outputs = {"%U%/led"},
install = {

View File

@ -51,6 +51,7 @@ tool_ncgg = cprogram {
},
lib_em_data,
lib_sbrk,
outputs = {"%U%-ncgg"},
install = pm.install(TOOLDIR.."ncgg")