Vous pouvez utiliser un verrou libre liste et quelques seaux de différentes tailles.
Alors:
typedef struct
{
union{
SLIST_ENTRY entry;
void* list;
};
byte mem[];
} mem_block;
typedef struct
{
SLIST_HEADER root;
} mem_block_list;
#define BUCKET_COUNT 4
#define BLOCKS_TO_ALLOCATE 16
static mem_block_list Buckets[BUCKET_COUNT];
void init_buckets()
{
for(int i = 0; i < BUCKET_COUNT; ++i)
{
InitializeSListHead(&Buckets[i].root);
for(int j = 0; j < BLOCKS_TO_ALLOCATE; ++j)
{
mem_block* p = (mem_block*) malloc(sizeof(mem_block) + (0x1 << BUCKET_COUNT) * 0x8);
InterlockedPushEntrySList(&Buckets[i].root, &p->entry);
}
}
}
void* balloc(size_t size)
{
for(int i = 0; i < BUCKET_COUNT; ++i)
{
if(size <= (0x1 << i) * 0x8)
{
mem_block* p = (mem_block*) InterlockedPopEntrySList(&Buckets[i].root);
p->list = &Buckets[i];
}
}
return 0; // block to large
}
void bfree(void* p)
{
mem_block* block = (mem_block*) (((byte*)p) - sizeof(block->entry));
InterlockedPushEntrySList(((mem_block_list*)block)->root, &block->entry);
}
SLIST_ENTRY, InterlockedPushEntrySList, InterlockedPopEntrySList, InitializeSListHead
sont des fonctions de verrouillage sans opérations unique liste chaînée sous Win32. Utilisez les opérations correspondantes sur d'autres systèmes d'exploitation.
Inconvénients:
- aériennes de
sizeof(SLIST_ENTRY)
- Les seaux ne peuvent se développer efficacement une fois au début, après que vous pouvez exécuter de mémoire et doivent demander à l'OS/d'autres seaux. (D'autres seaux conduit à la fragmentation)
- Cet échantillon est un peu trop facile et doit être étendue à traiter davantage d'affaires
+1 merci pour le lien – Viet
Ce document est la première chose à laquelle j'ai pensé quand j'ai vu la question. Nous avons utilisé une variante de cet allocateur dans l'un de nos produits et c'était vraiment très utile. –
Merci Dan. Cela semble génial! J'ai donc confiance pour m'améliorer. – Viet