]> pd.if.org Git - pdclib/blob - platform/example/functions/_PDCLIB/allocpages.c
435e8c64b8840fa7c429f2faadaf9d81caca3d8a
[pdclib] / platform / example / functions / _PDCLIB / allocpages.c
1 /* $Id$ */
2
3 /* _PDCLIB_allocpages( int const )
4
5    This file is part of the Public Domain C Library (PDCLib).
6    Permission is granted to use, modify, and / or redistribute at will.
7 */
8
9 /* This is an example implementation of _PDCLIB_allocpages() (declared in
10    _PDCLIB_config.h), fit for use with POSIX kernels.
11 */
12
13 #include <stdint.h>
14 #include <stddef.h>
15
16 int brk( void * );
17 void * sbrk( intptr_t );
18
19 #ifndef _PDCLIB_GLUE_H
20 #define _PDCLIB_GLUE_H _PDCLIB_GLUE_H
21 #include <_PDCLIB_glue.h>
22 #endif
23
24 static void * membreak = NULL;
25
26 void * _PDCLIB_allocpages( int const n )
27 {
28     if ( membreak == NULL )
29     {
30         /* first call, make sure end-of-heap is page-aligned */
31         intptr_t unaligned = 0;
32         membreak = sbrk( 0 );
33         unaligned = _PDCLIB_PAGESIZE - (intptr_t)membreak % _PDCLIB_PAGESIZE;
34         if ( unaligned < _PDCLIB_PAGESIZE )
35         {
36             /* end-of-heap not page-aligned - adjust */
37             if ( sbrk( unaligned ) != membreak )
38             {
39                 /* error */
40                 return NULL;
41             }
42             membreak = (char *)membreak + unaligned;
43         }
44     }
45     /* increasing or decreasing heap - standard operation */
46     void * oldbreak = membreak;
47     membreak = (void *)( (char *)membreak + ( n * _PDCLIB_PAGESIZE ) );
48     if ( brk( membreak ) == 0 )
49     {
50         /* successful */
51         return oldbreak;
52     }
53     else
54     {
55         /* out of memory */
56         membreak = oldbreak;
57         return NULL;
58     }
59 }
60
61 #ifdef TEST
62 #include <_PDCLIB_test.h>
63
64 int main( void )
65 {
66 #ifndef REGTEST
67     {
68     char * startbreak = sbrk( 0 );
69     TESTCASE( _PDCLIB_allocpages( 0 ) );
70     TESTCASE( ( (char *)sbrk( 0 ) - startbreak ) <= _PDCLIB_PAGESIZE );
71     startbreak = sbrk( 0 );
72     TESTCASE( _PDCLIB_allocpages( 1 ) );
73     TESTCASE( sbrk( 0 ) == startbreak + ( 1 * _PDCLIB_PAGESIZE ) );
74     TESTCASE( _PDCLIB_allocpages( 5 ) );
75     TESTCASE( sbrk( 0 ) == startbreak + ( 6 * _PDCLIB_PAGESIZE ) );
76     TESTCASE( _PDCLIB_allocpages( -3 ) );
77     TESTCASE( sbrk( 0 ) == startbreak + ( 3 * _PDCLIB_PAGESIZE ) );
78     }
79 #endif
80     return TEST_RESULTS;
81 }
82
83 #endif