[ctypes-commit] ctypes/source malloc_closure.c,1.4,1.5
Brought to you by:
theller
From: Thomas H. <th...@us...> - 2004-10-21 10:40:26
|
Update of /cvsroot/ctypes/ctypes/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv17909 Modified Files: malloc_closure.c Log Message: I'm happy with this file, so far. Index: malloc_closure.c =================================================================== RCS file: /cvsroot/ctypes/ctypes/source/malloc_closure.c,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** malloc_closure.c 21 Oct 2004 10:11:46 -0000 1.4 --- malloc_closure.c 21 Oct 2004 10:40:07 -0000 1.5 *************** *** 1,11 **** ! /* Allocate executable memory */ #include <Python.h> #include <ffi.h> #include "ctypes.h" ! #ifdef Py_DEBUG ! #define MALLOC_CLOSURE_DEBUG ! #endif #ifdef MS_WIN32 --- 1,39 ---- ! /* ! * Memory blocks with executable permission are allocated of size BLOCKSIZE. ! * They are chained together, and the start of the chain is the global 'start' ! * pointer. ! * ! * Each block has an array of ffi_closure in it. The ffi_closure.cif field is ! * used to mark an entry used or free, and the block has a 'used' field which ! * counts the used entries. ! * ! * MallocClosure() returns a pointer to an ffi_closure entry, allocating a new ! * block when needed. ! * ! * FreeClosure(ffi_closure*) marks the ffi_closure entry unused again. ! * If a memory block has only unused entries, it is freed again - unless it is ! * the last one in use. ! */ #include <Python.h> #include <ffi.h> #include "ctypes.h" + /* BLOCKSIZE can be adjusted. Larger blocksize will make MallocClosure() and + FreeClosure() somewhat slower, but allocate less blocks from the system. + It may be that some systems have a limit of how many mmap'd blocks can be + open. ! sizeof(ffi_closure) typically is: ! ! Windows: 28 bytes ! Linux x86, OpenBSD x86: 24 bytes ! Linux x86_64: 48 bytes ! */ ! ! #define BLOCKSIZE _pagesize * 4 ! ! /* #define MALLOC_CLOSURE_DEBUG */ /* enable for some debugging output */ ! ! /******************************************************************/ #ifdef MS_WIN32 *************** *** 27,36 **** } BLOCK; ! BLOCK *start; ! unsigned int _pagesize; ! ! #define BLOCKSIZE _pagesize * 4 ! static BLOCK *get_block(void) { BLOCK *block; --- 55,62 ---- } BLOCK; ! static BLOCK *start; /* points to the list of allocated blocks */ ! static unsigned int _pagesize; /* the system's pagesize */ ! static BLOCK *allocate_block(void) { BLOCK *block; *************** *** 65,72 **** #ifdef MALLOC_CLOSURE_DEBUG ! printf("One BLOCK has %d closures\n", block->count); ! block->count = 1; - printf("ALLOCATED block %p\n", block); #endif --- 91,97 ---- #ifdef MALLOC_CLOSURE_DEBUG ! printf("One BLOCK has %d closures of %d bytes each\n", ! block->count, sizeof(ffi_closure)); block->count = 1; printf("ALLOCATED block %p\n", block); #endif *************** *** 94,97 **** --- 119,125 ---- while (block) { + /* We could calculate the entry by pointer arithmetic, + to avoid a linear search. + */ for (i = 0; i < block->count; ++i) { if (&block->closure[i] == pcl) { *************** *** 103,107 **** block = block->next; } ! Py_FatalError("ctypes: closure not found in heap"); done: --- 131,135 ---- block = block->next; } ! Py_FatalError("ctypes: closure not found in any block"); done: *************** *** 121,131 **** } else { start = block->next; ! if (start) ! start->prev = NULL; ! else ! Py_FatalError("ctypes: no free block left\n"); } ! /* now, block can be freed */ free_block(block); #ifdef MALLOC_CLOSURE_DEBUG --- 149,156 ---- } else { start = block->next; ! start->prev = NULL; } ! /* now, the block can be freed */ free_block(block); #ifdef MALLOC_CLOSURE_DEBUG *************** *** 141,145 **** if (start == NULL) ! block = start = get_block(); while(block) { --- 166,170 ---- if (start == NULL) ! block = start = allocate_block(); while(block) { *************** *** 161,165 **** else { /* need a fresh block */ ! BLOCK *new_block = get_block(); if (new_block == NULL) return NULL; --- 186,190 ---- else { /* need a fresh block */ ! BLOCK *new_block = allocate_block(); if (new_block == NULL) return NULL; |