|
|
|
@ -849,30 +849,6 @@ static int running_on_valgrind = -1; |
|
|
|
|
|
|
|
/*==========================================================================*/ |
|
|
|
|
|
|
|
/* |
|
|
|
* Locking |
|
|
|
* |
|
|
|
* To reduce lock contention, it would probably be better to refine the |
|
|
|
* crude function locking with per size class locking. I'm not positive |
|
|
|
* however, whether it's worth switching to such locking policy because |
|
|
|
* of the performance penalty it might introduce. |
|
|
|
* |
|
|
|
* The following macros describe the simplest (should also be the fastest) |
|
|
|
* lock object on a particular platform and the init/fini/lock/unlock |
|
|
|
* operations on it. The locks defined here are not expected to be recursive |
|
|
|
* because it is assumed that they will always be called in the order: |
|
|
|
* INIT, [LOCK, UNLOCK]*, FINI. |
|
|
|
*/ |
|
|
|
|
|
|
|
/* |
|
|
|
* Python's threads are serialized, so object malloc locking is disabled. |
|
|
|
*/ |
|
|
|
#define SIMPLELOCK_DECL(lock) /* simple lock declaration */ |
|
|
|
#define SIMPLELOCK_INIT(lock) /* allocate (if needed) and initialize */ |
|
|
|
#define SIMPLELOCK_FINI(lock) /* free/destroy an existing lock */ |
|
|
|
#define SIMPLELOCK_LOCK(lock) /* acquire released lock */ |
|
|
|
#define SIMPLELOCK_UNLOCK(lock) /* release acquired lock */ |
|
|
|
|
|
|
|
/* When you say memory, my mind reasons in terms of (pointers to) blocks */ |
|
|
|
typedef uint8_t block; |
|
|
|
|
|
|
|
@ -944,15 +920,6 @@ struct arena_object { |
|
|
|
|
|
|
|
/*==========================================================================*/ |
|
|
|
|
|
|
|
/* |
|
|
|
* This malloc lock |
|
|
|
*/ |
|
|
|
SIMPLELOCK_DECL(_malloc_lock) |
|
|
|
#define LOCK() SIMPLELOCK_LOCK(_malloc_lock) |
|
|
|
#define UNLOCK() SIMPLELOCK_UNLOCK(_malloc_lock) |
|
|
|
#define LOCK_INIT() SIMPLELOCK_INIT(_malloc_lock) |
|
|
|
#define LOCK_FINI() SIMPLELOCK_FINI(_malloc_lock) |
|
|
|
|
|
|
|
/* |
|
|
|
* Pool table -- headed, circular, doubly-linked lists of partially used pools. |
|
|
|
|
|
|
|
@ -1381,7 +1348,6 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
LOCK(); |
|
|
|
/* |
|
|
|
* Most frequent paths first |
|
|
|
*/ |
|
|
|
@ -1537,13 +1503,11 @@ pymalloc_alloc(void *ctx, void **ptr_p, size_t nbytes) |
|
|
|
goto init_pool; |
|
|
|
|
|
|
|
success: |
|
|
|
UNLOCK(); |
|
|
|
assert(bp != NULL); |
|
|
|
*ptr_p = (void *)bp; |
|
|
|
return 1; |
|
|
|
|
|
|
|
failed: |
|
|
|
UNLOCK(); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
@ -1612,8 +1576,6 @@ pymalloc_free(void *ctx, void *p) |
|
|
|
} |
|
|
|
/* We allocated this address. */ |
|
|
|
|
|
|
|
LOCK(); |
|
|
|
|
|
|
|
/* Link p to the start of the pool's freeblock list. Since |
|
|
|
* the pool had at least the p block outstanding, the pool |
|
|
|
* wasn't empty (so it's already in a usedpools[] list, or |
|
|
|
@ -1798,7 +1760,6 @@ pymalloc_free(void *ctx, void *p) |
|
|
|
goto success; |
|
|
|
|
|
|
|
success: |
|
|
|
UNLOCK(); |
|
|
|
return 1; |
|
|
|
} |
|
|
|
|
|
|
|
|