Skip to content

Instantly share code, notes, and snippets.

@kvanbere
Created January 20, 2014 14:00
Show Gist options
  • Save kvanbere/8520332 to your computer and use it in GitHub Desktop.
Save kvanbere/8520332 to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdint.h>
#include <stddef.h>
#include <malloc.h>
typedef struct gc_root gc_root_t;
typedef struct gc_block_meta gc_block_meta_t;
typedef struct gc_block gc_block_t;
#define BLOCK_ALLOC_SIZE 4096
#define BLOCK_POOL_SIZE (BLOCK_ALLOC_SIZE - sizeof(gc_block_meta_t))
static gc_block_t volatile *volatile gc_block_head = NULL;
static gc_root_t volatile *volatile gc_large_root_head = NULL;
struct gc_root {
gc_root_t *next;
unsigned refs;
};
struct gc_block_meta {
gc_block_t *next;
gc_root_t *root;
unsigned lock;
size_t upto;
};
#pragma pack(push, 0)
struct gc_block {
gc_block_meta_t meta;
uint8_t pool[BLOCK_POOL_SIZE];
};
#pragma pack(pop)
void *gc_malloc_large(size_t size) {
return (void*)0;
}
void *gc_malloc(size_t size) {
if (size > BLOCK_POOL_SIZE) {
return gc_malloc_large(size);
}
size_t upto_n, upto_o;
gc_block_t volatile *block = gc_block_head;
do {
l_retry:
upto_o = block->meta.upto;
upto_n = upto_o + size;
if (upto_n > BLOCK_POOL_SIZE) {
if (__sync_bool_compare_and_swap(&block->meta.lock, 0, 1)) {
//gc_block_t *block_n =
// We have the lock
return (void*)0;
}
while (!block->meta.lock);
block = gc_block_head;
goto l_retry;
}
}
while (!__sync_bool_compare_and_swap(&block->meta.upto, upto_o, upto_n));
gc_root_t *root_n = (gc_root_t*)(&block->pool[upto_o]), *root_o;
root_n->refs = 0;
do {
root_o = block->meta.root;
root_n->next = root_o;
}
while (!__sync_bool_compare_and_swap(&block->meta.root, root_o, root_n));
return root_n;
}
int main() {
printf("%d", gc_malloc(300));
return 0;
}
0x00000001004010e0 <+0>: cmp rcx,0xfe0
0x00000001004010e7 <+7>: ja 0x10040113f <gc_malloc+95>
0x00000001004010e9 <+9>: mov rdx,QWORD PTR [rip+0x4f28] # 0x406018
0x00000001004010f0 <+16>: xor r11d,r11d
0x00000001004010f3 <+19>: mov r10d,0x1
0x00000001004010f9 <+25>: mov r8,QWORD PTR [rdx+0x18]
0x00000001004010fd <+29>: lea r9,[rcx+r8*1]
0x0000000100401101 <+33>: cmp r9,0xfe0
0x0000000100401108 <+40>: ja 0x100401134 <gc_malloc+84>
0x000000010040110a <+42>: mov rax,r8
0x000000010040110d <+45>: lock cmpxchg QWORD PTR [rdx+0x18],r9
0x0000000100401113 <+51>: jne 0x1004010f9 <gc_malloc+25>
0x0000000100401115 <+53>: lea rcx,[rdx+r8*1+0x20]
0x000000010040111a <+58>: mov DWORD PTR [rcx+0x8],0x0
0x0000000100401121 <+65>: mov rax,QWORD PTR [rdx+0x8]
0x0000000100401125 <+69>: mov QWORD PTR [rcx],rax
0x0000000100401128 <+72>: lock cmpxchg QWORD PTR [rdx+0x8],rcx
0x000000010040112e <+78>: jne 0x100401121 <gc_malloc+65>
0x0000000100401130 <+80>: mov rax,rcx
0x0000000100401133 <+83>: ret
0x0000000100401134 <+84>: mov eax,r11d
0x0000000100401137 <+87>: lock cmpxchg DWORD PTR [rdx+0x10],r10d
0x000000010040113d <+93>: jne 0x100401142 <gc_malloc+98>
0x000000010040113f <+95>: xor eax,eax
0x0000000100401141 <+97>: ret
0x0000000100401142 <+98>: mov eax,DWORD PTR [rdx+0x10]
0x0000000100401145 <+101>: test eax,eax
0x0000000100401147 <+103>: je 0x100401142 <gc_malloc+98>
0x0000000100401149 <+105>: mov rdx,QWORD PTR [rip+0x4ec8] # 0x406018
0x0000000100401150 <+112>: jmp 0x1004010f9 <gc_malloc+25>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment