symbian-qemu-0.9.1-12/python-2.6.1/Modules/_ctypes/malloc_closure.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*****************************************************************
       
     2   This file should be kept compatible with Python 2.3, see PEP 291.
       
     3  *****************************************************************/
       
     4 
       
     5 #include <Python.h>
       
     6 #include <ffi.h>
       
     7 #ifdef MS_WIN32
       
     8 #include <windows.h>
       
     9 #else
       
    10 #include <sys/mman.h>
       
    11 #include <unistd.h>
       
    12 # if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
       
    13 #  define MAP_ANONYMOUS MAP_ANON
       
    14 # endif
       
    15 #endif
       
    16 #include "ctypes.h"
       
    17 
       
    18 /* BLOCKSIZE can be adjusted.  Larger blocksize will take a larger memory
       
    19    overhead, but allocate less blocks from the system.  It may be that some
       
    20    systems have a limit of how many mmap'd blocks can be open.
       
    21 */
       
    22 
       
    23 #define BLOCKSIZE _pagesize
       
    24 
       
    25 /* #define MALLOC_CLOSURE_DEBUG */ /* enable for some debugging output */
       
    26 
       
    27 /******************************************************************/
       
    28 
       
    29 typedef union _tagITEM {
       
    30 	ffi_closure closure;
       
    31 	union _tagITEM *next;
       
    32 } ITEM;
       
    33 
       
    34 static ITEM *free_list;
       
    35 int _pagesize;
       
    36 
       
    37 static void more_core(void)
       
    38 {
       
    39 	ITEM *item;
       
    40 	int count, i;
       
    41 
       
    42 /* determine the pagesize */
       
    43 #ifdef MS_WIN32
       
    44 	if (!_pagesize) {
       
    45 		SYSTEM_INFO systeminfo;
       
    46 		GetSystemInfo(&systeminfo);
       
    47 		_pagesize = systeminfo.dwPageSize;
       
    48 	}
       
    49 #else
       
    50 	if (!_pagesize) {
       
    51 #ifdef _SC_PAGESIZE
       
    52 		_pagesize = sysconf(_SC_PAGESIZE);
       
    53 #else
       
    54 		_pagesize = getpagesize();
       
    55 #endif
       
    56 	}
       
    57 #endif
       
    58 
       
    59 	/* calculate the number of nodes to allocate */
       
    60 	count = BLOCKSIZE / sizeof(ITEM);
       
    61 
       
    62 	/* allocate a memory block */
       
    63 #ifdef MS_WIN32
       
    64 	item = (ITEM *)VirtualAlloc(NULL,
       
    65 					       count * sizeof(ITEM),
       
    66 					       MEM_COMMIT,
       
    67 					       PAGE_EXECUTE_READWRITE);
       
    68 	if (item == NULL)
       
    69 		return;
       
    70 #else
       
    71 	item = (ITEM *)mmap(NULL,
       
    72 			    count * sizeof(ITEM),
       
    73 			    PROT_READ | PROT_WRITE | PROT_EXEC,
       
    74 			    MAP_PRIVATE | MAP_ANONYMOUS,
       
    75 			    -1,
       
    76 			    0);
       
    77 	if (item == (void *)MAP_FAILED)
       
    78 		return;
       
    79 #endif
       
    80 
       
    81 #ifdef MALLOC_CLOSURE_DEBUG
       
    82 	printf("block at %p allocated (%d bytes), %d ITEMs\n",
       
    83 	       item, count * sizeof(ITEM), count);
       
    84 #endif
       
    85 	/* put them into the free list */
       
    86 	for (i = 0; i < count; ++i) {
       
    87 		item->next = free_list;
       
    88 		free_list = item;
       
    89 		++item;
       
    90 	}
       
    91 }
       
    92 
       
    93 /******************************************************************/
       
    94 
       
    95 /* put the item back into the free list */
       
    96 void FreeClosure(void *p)
       
    97 {
       
    98 	ITEM *item = (ITEM *)p;
       
    99 	item->next = free_list;
       
   100 	free_list = item;
       
   101 }
       
   102 
       
   103 /* return one item from the free list, allocating more if needed */
       
   104 void *MallocClosure(void)
       
   105 {
       
   106 	ITEM *item;
       
   107 	if (!free_list)
       
   108 		more_core();
       
   109 	if (!free_list)
       
   110 		return NULL;
       
   111 	item = free_list;
       
   112 	free_list = item->next;
       
   113 	return item;
       
   114 }