ddnet/src/game/server/alloc.h

84 lines
2.9 KiB
C
Raw Normal View History

/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#ifndef GAME_SERVER_ALLOC_H
#define GAME_SERVER_ALLOC_H
#include <new>
#include <base/system.h>
2021-11-03 00:05:46 +00:00
#ifndef __has_feature
#define __has_feature(x) 0
#endif
2021-11-02 23:51:03 +00:00
#if __has_feature(address_sanitizer)
2021-11-02 23:21:46 +00:00
#include <sanitizer/asan_interface.h>
2021-11-03 00:05:46 +00:00
#else
2021-11-02 23:51:03 +00:00
#define ASAN_POISON_MEMORY_REGION(addr, size) \
((void)(addr), (void)(size))
#define ASAN_UNPOISON_MEMORY_REGION(addr, size) \
((void)(addr), (void)(size))
#endif
#define MACRO_ALLOC_HEAP() \
public: \
void *operator new(size_t Size) \
{ \
void *p = malloc(Size); \
mem_zero(p, Size); \
return p; \
} \
void operator delete(void *pPtr) \
{ \
free(pPtr); \
} \
\
private:
#define MACRO_ALLOC_POOL_ID() \
public: \
void *operator new(size_t Size, int id); \
void operator delete(void *p, int id); \
void operator delete(void *p); /* NOLINT(misc-new-delete-overloads) */ \
\
private:
2021-11-03 15:08:16 +00:00
#if __has_feature(address_sanitizer)
2021-11-04 09:50:39 +00:00
#define MACRO_ALLOC_GET_SIZE(POOLTYPE) ((sizeof(POOLTYPE) + 7) & ~7)
2021-11-03 15:08:16 +00:00
#else
2021-11-04 09:50:39 +00:00
#define MACRO_ALLOC_GET_SIZE(POOLTYPE) (sizeof(POOLTYPE))
2021-11-03 15:08:16 +00:00
#endif
#define MACRO_ALLOC_POOL_ID_IMPL(POOLTYPE, PoolSize) \
2021-11-04 09:50:39 +00:00
static char ms_PoolData##POOLTYPE[PoolSize][MACRO_ALLOC_GET_SIZE(POOLTYPE)] = {{0}}; \
static int ms_PoolUsed##POOLTYPE[PoolSize] = {0}; \
2021-11-03 15:08:16 +00:00
[[maybe_unused]] static int ms_PoolDummy##POOLTYPE = (ASAN_POISON_MEMORY_REGION(ms_PoolData##POOLTYPE, sizeof(ms_PoolData##POOLTYPE)), 0); \
void *POOLTYPE::operator new(size_t Size, int id) \
{ \
2021-11-03 15:08:16 +00:00
dbg_assert(sizeof(POOLTYPE) >= Size, "size error"); \
dbg_assert(!ms_PoolUsed##POOLTYPE[id], "already used"); \
/*dbg_msg("pool", "++ %s %d", #POOLTYPE, id);*/ \
2021-11-03 15:08:16 +00:00
ASAN_UNPOISON_MEMORY_REGION(ms_PoolData##POOLTYPE[id], sizeof(ms_PoolData##POOLTYPE[id])); \
ms_PoolUsed##POOLTYPE[id] = 1; \
2021-11-03 15:08:16 +00:00
mem_zero(ms_PoolData##POOLTYPE[id], sizeof(ms_PoolData##POOLTYPE[id])); \
return ms_PoolData##POOLTYPE[id]; \
} \
void POOLTYPE::operator delete(void *p, int id) \
{ \
dbg_assert(ms_PoolUsed##POOLTYPE[id], "not used"); \
dbg_assert(id == (POOLTYPE *)p - (POOLTYPE *)ms_PoolData##POOLTYPE, "invalid id"); \
/*dbg_msg("pool", "-- %s %d", #POOLTYPE, id);*/ \
ms_PoolUsed##POOLTYPE[id] = 0; \
2021-11-03 15:08:16 +00:00
mem_zero(ms_PoolData##POOLTYPE[id], sizeof(ms_PoolData##POOLTYPE[id])); \
ASAN_POISON_MEMORY_REGION(ms_PoolData##POOLTYPE[id], sizeof(ms_PoolData##POOLTYPE[id])); \
} \
void POOLTYPE::operator delete(void *p) /* NOLINT(misc-new-delete-overloads) */ \
{ \
int id = (POOLTYPE *)p - (POOLTYPE *)ms_PoolData##POOLTYPE; \
dbg_assert(ms_PoolUsed##POOLTYPE[id], "not used"); \
/*dbg_msg("pool", "-- %s %d", #POOLTYPE, id);*/ \
ms_PoolUsed##POOLTYPE[id] = 0; \
2021-11-03 15:08:16 +00:00
mem_zero(ms_PoolData##POOLTYPE[id], sizeof(ms_PoolData##POOLTYPE[id])); \
ASAN_POISON_MEMORY_REGION(ms_PoolData##POOLTYPE[id], sizeof(ms_PoolData##POOLTYPE[id])); \
}
#endif