mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +00:00
Initial import
This commit is contained in:
commit
c91b3c5006
14915 changed files with 590219 additions and 0 deletions
71
third_party/dlmalloc/malloc_inspect_all.c
vendored
Normal file
71
third_party/dlmalloc/malloc_inspect_all.c
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
#include "libc/mem/mem.h"
|
||||
#include "third_party/dlmalloc/dlmalloc.h"
|
||||
|
||||
static void internal_inspect_all(mstate m,
|
||||
void (*handler)(void* start, void* end,
|
||||
size_t used_bytes,
|
||||
void* callback_arg),
|
||||
void* arg) {
|
||||
if (is_initialized(m)) {
|
||||
mchunkptr top = m->top;
|
||||
msegmentptr s;
|
||||
for (s = &m->seg; s != 0; s = s->next) {
|
||||
mchunkptr q = align_as_chunk(s->base);
|
||||
while (segment_holds(s, q) && q->head != FENCEPOST_HEAD) {
|
||||
mchunkptr next = next_chunk(q);
|
||||
size_t sz = chunksize(q);
|
||||
size_t used;
|
||||
void* start;
|
||||
if (is_inuse(q)) {
|
||||
used = sz - CHUNK_OVERHEAD; /* must not be mmapped */
|
||||
start = chunk2mem(q);
|
||||
} else {
|
||||
used = 0;
|
||||
if (is_small(sz)) { /* offset by possible bookkeeping */
|
||||
start = (void*)((char*)q + sizeof(struct malloc_chunk));
|
||||
} else {
|
||||
start = (void*)((char*)q + sizeof(struct malloc_tree_chunk));
|
||||
}
|
||||
}
|
||||
if (start < (void*)next) /* skip if all space is bookkeeping */
|
||||
handler(start, next, used, arg);
|
||||
if (q == top) break;
|
||||
q = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses the heap and calls the given handler for each managed
|
||||
* region, skipping all bytes that are (or may be) used for bookkeeping
|
||||
* purposes. Traversal does not include include chunks that have been
|
||||
* directly memory mapped. Each reported region begins at the start
|
||||
* address, and continues up to but not including the end address. The
|
||||
* first used_bytes of the region contain allocated data. If
|
||||
* used_bytes is zero, the region is unallocated. The handler is
|
||||
* invoked with the given callback argument. If locks are defined, they
|
||||
* are held during the entire traversal. It is a bad idea to invoke
|
||||
* other malloc functions from within the handler.
|
||||
*
|
||||
* For example, to count the number of in-use chunks with size greater
|
||||
* than 1000, you could write:
|
||||
*
|
||||
* static int count = 0;
|
||||
* void count_chunks(void* start, void* end, size_t used, void* arg) {
|
||||
* if (used >= 1000) ++count;
|
||||
* }
|
||||
*
|
||||
* then,
|
||||
*
|
||||
* malloc_inspect_all(count_chunks, NULL);
|
||||
*/
|
||||
void malloc_inspect_all(void (*handler)(void* start, void* end,
|
||||
size_t used_bytes, void* callback_arg),
|
||||
void* arg) {
|
||||
ensure_initialization();
|
||||
if (!PREACTION(gm)) {
|
||||
internal_inspect_all(gm, handler, arg);
|
||||
POSTACTION(gm);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue