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