ยปCore Development>Code coverage>Modules/_ctypes/malloc_closure.c

Python code coverage for Modules/_ctypes/malloc_closure.c

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