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

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)
{