123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- #include <stdlib.h>
- #include <assert.h>
- #include "nvim/lib/ringbuf.h"
- enum { RB_SIZE = 1024 };
- typedef struct {
- void *ptr;
- size_t size;
- } AllocRecord;
- RINGBUF_TYPEDEF(AllocRecords, AllocRecord)
- RINGBUF_INIT(AllocRecords, arecs, AllocRecord, RINGBUF_DUMMY_FREE)
- RINGBUF_STATIC(static, AllocRecords, AllocRecord, arecs, RB_SIZE)
- size_t allocated_memory = 0;
- size_t ever_allocated_memory = 0;
- size_t allocated_memory_limit = SIZE_MAX;
- void *xmalloc(const size_t size)
- {
- void *ret = malloc(size);
- allocated_memory += size;
- ever_allocated_memory += size;
- assert(allocated_memory <= allocated_memory_limit);
- assert(arecs_rb_length(&arecs) < RB_SIZE);
- arecs_rb_push(&arecs, (AllocRecord) {
- .ptr = ret,
- .size = size,
- });
- return ret;
- }
- void xfree(void *const p)
- {
- if (p == NULL) {
- return;
- }
- RINGBUF_FORALL(&arecs, AllocRecord, arec) {
- if (arec->ptr == p) {
- allocated_memory -= arec->size;
- arecs_rb_remove(&arecs, arecs_rb_find_idx(&arecs, arec));
- return;
- }
- }
- abort();
- }
- void *xrealloc(void *const p, size_t new_size)
- {
- void *ret = realloc(p, new_size);
- RINGBUF_FORALL(&arecs, AllocRecord, arec) {
- if (arec->ptr == p) {
- allocated_memory -= arec->size;
- allocated_memory += new_size;
- if (new_size > arec->size) {
- ever_allocated_memory += (new_size - arec->size);
- }
- arec->ptr = ret;
- arec->size = new_size;
- return ret;
- }
- }
- abort();
- return (void *)(intptr_t)1;
- }
- char *xstrdup(const char *str)
- FUNC_ATTR_MALLOC FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_RET
- FUNC_ATTR_NONNULL_ALL
- {
- return xmemdupz(str, strlen(str));
- }
- void *xmallocz(size_t size)
- FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
- {
- size_t total_size = size + 1;
- assert(total_size > size);
- void *ret = xmalloc(total_size);
- ((char *)ret)[size] = 0;
- return ret;
- }
- char *xstpcpy(char *restrict dst, const char *restrict src)
- FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
- {
- const size_t len = strlen(src);
- return (char *)memcpy(dst, src, len + 1) + len;
- }
- void *xmemdupz(const void *data, size_t len)
- FUNC_ATTR_MALLOC FUNC_ATTR_NONNULL_RET FUNC_ATTR_WARN_UNUSED_RESULT
- FUNC_ATTR_NONNULL_ALL
- {
- return memcpy(xmallocz(len), data, len);
- }
|