void NRT_MemInfo_release(MemInfo *mi, int defer) { NRT_Debug(nrt_debug_print("NRT_release %p refct=%zu\n", mi, mi->payload.refct)); assert (mi->payload.refct > 0 && "RefCt cannot be 0"); /* RefCt drop to zero */ if (TheMSys.atomic_dec(&mi->payload.refct) == 0) { NRT_MemInfo_call_dtor(mi, defer); } }
MemInfo* NRT_MemSys_pop_meminfo(void) { MemInfo *node = nrt_pop_meminfo_list(&TheMSys.mi_freelist); if (NULL == node) { node = meminfo_malloc(); } memset(node, 0, sizeof(MemInfo)); /* to catch bugs; not required */ NRT_Debug(nrt_debug_print("NRT_MemSys_pop_meminfo: return %p\n", node)); TheMSys.atomic_inc(&TheMSys.stats_mi_alloc); return node; }
static void nrt_push_meminfo_list(MemInfo * volatile *list, MemInfo *repl) { MemInfo *old, *head; head = *list; /* get the current head */ do { old = head; /* old is what CAS compare against */ /* Set the next item to be the current head */ repl->list_next = head; /* Try to replace the head with the new node. The function also perform: head <- atomicload(list) */ } while ( !TheMSys.atomic_cas(list, old, repl, &head) ); }
void NRT_MemSys_insert_meminfo(MemInfo *newnode) { assert(newnode && "`newnode` cannot be NULL"); /* if (NULL == newnode) { newnode = meminfo_malloc(); } else { assert(newnode->payload.refct == 0 && "RefCt must be 0"); } */ assert(newnode->payload.refct == 0 && "RefCt must be 0"); NRT_Debug(nrt_debug_print("NRT_MemSys_insert_meminfo newnode=%p\n", newnode)); memset(newnode, 0, sizeof(MemInfo)); /* to catch bugs; not required */ nrt_push_meminfo_list(&TheMSys.mi_freelist, newnode); TheMSys.atomic_inc(&TheMSys.stats_mi_free); }
static MemInfo *nrt_pop_meminfo_list(MemInfo * volatile *list) { MemInfo *old, *repl, *head; head = *list; /* get the current head */ do { old = head; /* old is what CAS compare against */ if ( head ) { /* if head is not NULL, replace with the next item */ repl = head->list_next; } else { /* else, replace with NULL */ repl = NULL; } /* Try to replace list head with the next node. The function also perform: head <- atomicload(list) */ } while ( !TheMSys.atomic_cas(list, old, repl, &head)); return old; }
void NRT_Free(void *ptr) { NRT_Debug(nrt_debug_print("NRT_Free %p\n", ptr)); free(ptr); TheMSys.atomic_inc(&TheMSys.stats_free); }
void* NRT_Allocate(size_t size) { void *ptr = malloc(size); NRT_Debug(nrt_debug_print("NRT_Allocate bytes=%llu ptr=%p\n", size, ptr)); TheMSys.atomic_inc(&TheMSys.stats_alloc); return ptr; }
void NRT_MemInfo_acquire(MemInfo *mi) { NRT_Debug(nrt_debug_print("NRT_acquire %p refct=%zu\n", mi, mi->payload.refct)); assert(mi->payload.refct > 0 && "RefCt cannot be zero"); TheMSys.atomic_inc(&mi->payload.refct); }
void NRT_MemInfo_acquire(MemInfo *mi) { NRT_Debug(nrt_debug_print("NRT_acquire %p\n", mi)); TheMSys.atomic_inc(&mi->payload.refct); }