/** * Remove a talloc'ed memory chunk from the dependency tree, taking care of its * children (they will depend on parent). * * @param mem pointer to previously talloc'ed memory chunk. * @param parent pointer to previously talloc'ed memory chunk from which this * chunk's children will depend, or NULL. */ void talloc_steal(void *mem, void *parent) { if (!mem) return; talloc_set_parent(mem, NULL); if (!child(mem)) return; if (parent) { /* Insert mem children in front of the list of parent children. */ if (child(parent)) { void *last = child(mem); while (next(last)) last = next(last); prev(child(parent)) = last; next(last) = child(parent); } child(parent) = child(mem); } parent(child(mem)) = parent; child(mem) = NULL; }
/** * Remove chunk of talloc'ed memory from dependency chain. * * @param mem pointer to previously talloc'ed memory * @param parent pointer to previously talloc'ed memory from wich this chunk's * sons will depend or NULL */ void talloc_steal ( void* mem, void* parent ) { void **aux; if ( !mem ) return; for ( aux = ((void***)mem)[-3]; aux; aux = ((void***)mem)[-3] ) { aux[2] = NULL; ((void**)mem)[-3] = aux[1]; talloc_set_parent( aux + 3, parent ); } talloc_set_parent( mem, NULL ); }
/** * Initialize a raw chunk of memory. * * @param mem pointer to a raw memory chunk. * @param parent pointer to previously talloc'ed memory chunk from which this * chunk depends, or NULL. * * @return pointer to the allocated memory chunk, or NULL if there was an error. */ static void *talloc_init(void *mem, void *parent) { if (!mem) return NULL; memset(mem, 0, HEADER_SIZE); mem = raw2usr(mem); talloc_set_parent(mem, parent); return mem; }
/** * Deallocate a talloc'ed memory chunk and all the chunks depending on it. * * @param mem pointer to previously talloc'ed memory chunk. * * @return always NULL, can be safely ignored. */ void *tfree(void *mem) { if (!mem) return NULL; talloc_set_parent(mem, NULL); __tfree(child(mem)); free(usr2raw(mem)); return NULL; }
/** * Allocate zeroed memory * * @param size amount of memory requested * @param parent pointer to previously talloc'ed memory from wich this chunk * depends or NULL * * @return a pointer to the allocated memory */ void* tcalloc ( size_t size, void* parent ) { if (mutex == NULL) { init_mutex(); } pthread_mutex_lock(mutex); void **mem = calloc( 1, size + sizeof( void* ) * 3 ); if ( !mem ) { pthread_mutex_unlock(mutex); return NULL; } talloc_set_parent( mem + 3, parent ); pthread_mutex_unlock(mutex); return mem + 3; }
/** * Free memory * * @param mem pointer to previously talloc'ed memory */ void tfree ( void* mem ) { if ( !mem ) return; if (mutex == NULL) { init_mutex(); } pthread_mutex_lock(mutex); talloc_set_parent( mem, NULL ); __tfree( ((void**)mem)[-3] ); free( (void**)mem - 3 ); pthread_mutex_unlock(mutex); }