]> pd.if.org Git - pdclib.old/blob - platform/example_cygwin/functions/_PDCLIB/allocpages.c
Improved by Caleb1994 of osdev.org.
[pdclib.old] / platform / example_cygwin / 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 void * sbrk( intptr_t );
17
18 #ifndef _PDCLIB_GLUE_H
19 #define _PDCLIB_GLUE_H _PDCLIB_GLUE_H
20 #include <_PDCLIB_glue.h>
21 #endif
22
23 static void * membreak = NULL;
24
25 void * _PDCLIB_allocpages( int const n )
26 {
27     if ( membreak == NULL )
28     {
29         /* first call, make sure end-of-heap is page-aligned */
30         intptr_t unaligned = 0;
31         membreak = sbrk( 0 );
32         unaligned = _PDCLIB_PAGESIZE - (intptr_t)membreak % _PDCLIB_PAGESIZE;
33         if ( unaligned < _PDCLIB_PAGESIZE )
34         {
35             /* end-of-heap not page-aligned - adjust */
36             if ( sbrk( unaligned ) != membreak )
37             {
38                 /* error */
39                 return NULL;
40             }
41             membreak = (char *)membreak + unaligned;
42         }
43     }
44     /* increasing or decreasing heap - standard operation */
45     void * oldbreak = membreak;
46     membreak = (void *)( (char *)membreak + ( n * _PDCLIB_PAGESIZE ) );
47     if ( sbrk( (char*)membreak - (char*)oldbreak ) == membreak )
48     {
49         /* successful */
50         return oldbreak;
51     }
52     else
53     {
54         /* out of memory */
55         membreak = oldbreak;
56         return NULL;
57     }
58 }
59
60 #ifdef TEST
61 #include <_PDCLIB_test.h>
62
63 int main( void )
64 {
65     char * startbreak = sbrk( 0 );
66     TESTCASE( _PDCLIB_allocpages( 0 ) );
67     TESTCASE( ( (char *)sbrk( 0 ) - startbreak ) <= _PDCLIB_PAGESIZE );
68     startbreak = sbrk( 0 );
69     TESTCASE( _PDCLIB_allocpages( 1 ) );
70     TESTCASE( sbrk( 0 ) == startbreak + ( 1 * _PDCLIB_PAGESIZE ) );
71     TESTCASE( _PDCLIB_allocpages( 5 ) );
72     TESTCASE( sbrk( 0 ) == startbreak + ( 6 * _PDCLIB_PAGESIZE ) );
73     TESTCASE( _PDCLIB_allocpages( -3 ) );
74     TESTCASE( sbrk( 0 ) == startbreak + ( 3 * _PDCLIB_PAGESIZE ) );
75 }
76
77 #endif