X-Git-Url: https://pd.if.org/git/?a=blobdiff_plain;f=platform%2Fposix%2Ffunctions%2F_PDCLIB%2Fallocpages.c;fp=platform%2Fposix%2Ffunctions%2F_PDCLIB%2Fallocpages.c;h=435e8c64b8840fa7c429f2faadaf9d81caca3d8a;hb=a38d56a6a13dbb89022b5448d2d5247f3f99ea41;hp=0000000000000000000000000000000000000000;hpb=81f4c957d2f820d9340d90d5b650cbbed054caa0;p=pdclib.old diff --git a/platform/posix/functions/_PDCLIB/allocpages.c b/platform/posix/functions/_PDCLIB/allocpages.c new file mode 100644 index 0000000..435e8c6 --- /dev/null +++ b/platform/posix/functions/_PDCLIB/allocpages.c @@ -0,0 +1,83 @@ +/* $Id$ */ + +/* _PDCLIB_allocpages( int const ) + + This file is part of the Public Domain C Library (PDCLib). + Permission is granted to use, modify, and / or redistribute at will. +*/ + +/* This is an example implementation of _PDCLIB_allocpages() (declared in + _PDCLIB_config.h), fit for use with POSIX kernels. +*/ + +#include +#include + +int brk( void * ); +void * sbrk( intptr_t ); + +#ifndef _PDCLIB_GLUE_H +#define _PDCLIB_GLUE_H _PDCLIB_GLUE_H +#include <_PDCLIB_glue.h> +#endif + +static void * membreak = NULL; + +void * _PDCLIB_allocpages( int const n ) +{ + if ( membreak == NULL ) + { + /* first call, make sure end-of-heap is page-aligned */ + intptr_t unaligned = 0; + membreak = sbrk( 0 ); + unaligned = _PDCLIB_PAGESIZE - (intptr_t)membreak % _PDCLIB_PAGESIZE; + if ( unaligned < _PDCLIB_PAGESIZE ) + { + /* end-of-heap not page-aligned - adjust */ + if ( sbrk( unaligned ) != membreak ) + { + /* error */ + return NULL; + } + membreak = (char *)membreak + unaligned; + } + } + /* increasing or decreasing heap - standard operation */ + void * oldbreak = membreak; + membreak = (void *)( (char *)membreak + ( n * _PDCLIB_PAGESIZE ) ); + if ( brk( membreak ) == 0 ) + { + /* successful */ + return oldbreak; + } + else + { + /* out of memory */ + membreak = oldbreak; + return NULL; + } +} + +#ifdef TEST +#include <_PDCLIB_test.h> + +int main( void ) +{ +#ifndef REGTEST + { + char * startbreak = sbrk( 0 ); + TESTCASE( _PDCLIB_allocpages( 0 ) ); + TESTCASE( ( (char *)sbrk( 0 ) - startbreak ) <= _PDCLIB_PAGESIZE ); + startbreak = sbrk( 0 ); + TESTCASE( _PDCLIB_allocpages( 1 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 1 * _PDCLIB_PAGESIZE ) ); + TESTCASE( _PDCLIB_allocpages( 5 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 6 * _PDCLIB_PAGESIZE ) ); + TESTCASE( _PDCLIB_allocpages( -3 ) ); + TESTCASE( sbrk( 0 ) == startbreak + ( 3 * _PDCLIB_PAGESIZE ) ); + } +#endif + return TEST_RESULTS; +} + +#endif