Memory Allocation Structure:
# Ifndef hdb_h_defined
# Define hdb_h_defined
# Ifndef _ gnu_source
# DEFINE _ gnu_source
# Endif
# Include <errno. h>
# Include <assert. h>
# Include <stdlib. h>
# Include <string. h>
# Include <pthread. h>
# Include <stdint. h>
# Include <inttypes. h>
Typedef uint64_t hdb_handle_t;
/*
* Formatting for string printing on 32/64 bit Systems
*/
# Define hdb_d_format "%" priu64
# Define hdb_x_format "%" prix64
Enum hdb_handle_state {
Hdb_handle_state_empty,
Hdb_handle_state_pendingremoval,
Hdb_handle_state_active
};
// This struct mainly records the status of each memory allocation
Struct hdb_handle {
Int state;
Void * instance;
Int check;
Int ref_count;
};
// This struct records the entire memory allocation
Struct hdb_handle_database {
Unsigned int handle_count;
Struct hdb_handle * handles;
Unsigned int iterator;
Void (* destructor) (void *);
Pthread_mutex_t lock;
Unsigned int first_run;
};
Static inline void hdb_database_lock (pthread_mutex_t * mutex)
{
Pthread_mutex_lock (mutex );
}
Static inline void hdb_database_unlock (pthread_mutex_t * mutex)
{
Pthread_mutex_unlock (mutex );
}
Static inline void hdb_database_lock_init (pthread_mutex_t * mutex)
{
Pthread_mutex_init (mutex, null );
}
Static inline void hdb_database_lock_destroy (pthread_mutex_t * mutex)
{
Pthread_mutex_destroy (mutex );
}
# Define declare_hdb_database (database_name, destructor_function )\
Static struct hdb_handle_database (database_name) = {\
. Handle_count = 0 ,\
. Handles = NULL ,\
. Iterator = 0 ,\
. Destructor = destructor_function ,\
. First_run = 1 \
};\
// Initialize the memory
Static inline void hdb_create (
Struct hdb_handle_database * handle_database)
{
Memset (handle_database, 0, sizeof (struct hdb_handle_database ));
Hdb_database_lock_init (& handle_database-> lock );
}
// Release the entire memory
Static inline void hdb_destroy (
Struct hdb_handle_database * handle_database)
{
Free (handle_database-> handles );
Hdb_database_lock_destroy (& handle_database-> lock );
Memset (handle_database, 0, sizeof (struct hdb_handle_database ));
}
// Create a memory.
Static inline int hdb_handle_create (
Struct hdb_handle_database * handle_database,
Int instance_size,
Hdb_handle_t * handle_id_out)
{
Int handle;
Unsigned int check;
Void * new_handles;
Int found = 0;
Void * instance;
Int I;
If (handle_database-> first_run = 1 ){
Handle_database-> first_run = 0;
Hdb_database_lock_init (& handle_database-> lock );
}
Hdb_database_lock (& handle_database-> lock );
For (handle = 0; handle If (handle_database-> handles [handle]. State = hdb_handle_state_empty ){
Found = 1;
Break;
}
}
If (found = 0 ){
Handle_database-> handle_count + = 1;
New_handles = (struct hdb_handle *) realloc (handle_database-> handles,
Sizeof (struct hdb_handle) * handle_database-> handle_count );
If (new_handles = NULL ){
Hdb_database_unlock (& handle_database-> lock );
Errno = enomem;
Return (-1 );
}
Handle_database-> handles = new_handles;
}
Instance = (void *) malloc (instance_size );
If (instance = 0 ){
Errno = enomem;
Return (-1 );
}
/*
* This code makes sure the random number isn't zero
* We use 0 to specify an invalid handle out of the 1 ^ 64 address space
* If we get 0 200 times in a row, the RNG may be broken
*/
For (I = 0; I <200; I ++ ){
Check = random ();
If (check! = 0 & check! = 0 xffffffff ){
Break;
}
}
Memset (instance, 0, instance_size );
Handle_database-> handles [handle]. State = hdb_handle_state_active;
Handle_database-> handles [handle]. instance = instance;
Handle_database-> handles [handle]. ref_count = 1;
Handle_database-> handles [handle]. Check = check;
* Handle_id_out = (unsigned long) (check) <32) | handle;
Hdb_database_unlock (& handle_database-> lock );
Return (0 );
}
// Obtain a memory pointer Based on the handle value.
Static inline int hdb_handle_get (
Struct hdb_handle_database * handle_database,
Hdb_handle_t handle_in,
Void ** instance)
{
Unsigned int check = (unsigned INT) (unsigned long) handle_in)> 32 ));
Unsigned int handle = handle_in & 0 xffffffff;
If (handle_database-> first_run = 1 ){
Handle_database-> first_run = 0;
Hdb_database_lock_init (& handle_database-> lock );
}
Hdb_database_lock (& handle_database-> lock );
* Instance = NULL;
If (handle> = handle_database-> handle_count ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
If (handle_database-> handles [handle]. State! = Hdb_handle_state_active ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
If (check! = 0 xffffffff &&
Check! = Handle_database-> handles [handle]. Check ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
* Instance = handle_database-> handles [handle]. instance;
Handle_database-> handles [handle]. ref_count + = 1;
Hdb_database_unlock (& handle_database-> lock );
Return (0 );
}
// Obtain a memory pointer Based on the handle, as long as the pointer status is not hdb_handle_state_empty.
Static inline int hdb_handle_get_always (
Struct hdb_handle_database * handle_database,
Hdb_handle_t handle_in,
Void ** instance)
{
Unsigned int check = (unsigned INT) (unsigned long) handle_in)> 32 ));
Unsigned int handle = handle_in & 0 xffffffff;
If (handle_database-> first_run = 1 ){
Handle_database-> first_run = 0;
Hdb_database_lock_init (& handle_database-> lock );
}
Hdb_database_lock (& handle_database-> lock );
* Instance = NULL;
If (handle> = handle_database-> handle_count ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
If (handle_database-> handles [handle]. State = hdb_handle_state_empty ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
If (check! = 0 xffffffff &&
Check! = Handle_database-> handles [handle]. Check ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
* Instance = handle_database-> handles [handle]. instance;
Handle_database-> handles [handle]. ref_count + = 1;
Hdb_database_unlock (& handle_database-> lock );
Return (0 );
}
// Release a memory
Static inline int hdb_handle_put (
Struct hdb_handle_database * handle_database,
Hdb_handle_t handle_in)
{
Unsigned int check = (unsigned INT) (unsigned long) handle_in)> 32 ));
Unsigned int handle = handle_in & 0 xffffffff;
If (handle_database-> first_run = 1 ){
Handle_database-> first_run = 0;
Hdb_database_lock_init (& handle_database-> lock );
}
Hdb_database_lock (& handle_database-> lock );
If (handle> = handle_database-> handle_count ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
If (check! = 0 xffffffff &&
Check! = Handle_database-> handles [handle]. Check ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
Handle_database-> handles [handle]. ref_count-= 1;
Assert (handle_database-> handles [handle]. ref_count> = 0 );
If (handle_database-> handles [handle]. ref_count = 0 ){
If (handle_database-> destructor ){
Handle_database-> destructor (handle_database-> handles
[Handle]. instance );
}
Free (handle_database-> handles [handle]. instance );
Memset (& handle_database-> handles [handle], 0, sizeof (struct hdb_handle ));
}
Hdb_database_unlock (& handle_database-> lock );
Return (0 );
}
// Release the memory and change the memory status.
Static inline int hdb_handle_destroy (
Struct hdb_handle_database * handle_database,
Hdb_handle_t handle_in)
{
Unsigned int check = (unsigned INT) (unsigned long) handle_in)> 32 ));
Unsigned int handle = handle_in & 0 xffffffff;
Int res;
If (handle_database-> first_run = 1 ){
Handle_database-> first_run = 0;
Hdb_database_lock_init (& handle_database-> lock );
}
Hdb_database_lock (& handle_database-> lock );
If (handle> = handle_database-> handle_count ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
If (check! = 0 xffffffff & check! = Handle_database-> handles [handle]. Check ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
Handle_database-> handles [handle]. State = hdb_handle_state_pendingremoval;
Hdb_database_unlock (& handle_database-> lock );
Res = hdb_handle_put (handle_database, handle_in );
Return (RES );
}
// Obtain the number of times the memory is referenced.
Static inline int hdb_handle_refcount_get (
Struct hdb_handle_database * handle_database,
Hdb_handle_t handle_in)
{
Unsigned int check = (unsigned INT) (unsigned long) handle_in)> 32 ));
Unsigned int handle = handle_in & 0 xffffffff;
Int refcount = 0;
If (handle_database-> first_run = 1 ){
Handle_database-> first_run = 0;
Hdb_database_lock_init (& handle_database-> lock );
}
Hdb_database_lock (& handle_database-> lock );
If (handle> = handle_database-> handle_count ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
If (check! = 0 xffffffff &&
Check! = Handle_database-> handles [handle]. Check ){
Hdb_database_unlock (& handle_database-> lock );
Errno = ebadf;
Return (-1 );
}
Refcount = handle_database-> handles [handle]. ref_count;
Hdb_database_unlock (& handle_database-> lock );
Return (refcount );
}
// Reset the pointer.
Static inline void hdb_iterator_reset (
Struct hdb_handle_database * handle_database)
{
Handle_database-> iterator = 0;
}
// Obtain the memory pointer.
Static inline int hdb_iterator_next (
Struct hdb_handle_database * handle_database,
Void ** instance,
Hdb_handle_t * handle)
{
Int res =-1;
While (handle_database-> iterator * Handle = (unsigned long) (handle_database-> handles [handle_database-
> Iterator]. Check) <32) | handle_database-> iterator;
Res = hdb_handle_get (
Handle_database,
* Handle,
Instance );
Handle_database-> iterator + = 1;
If (RES = 0 ){
Break;
}
}
Return (RES );
}
Static inline unsigned int hdb_base_convert (hdb_handle_t handle)
{
Return (handle & 0 xffffffff );
}
Static inline unsigned long hdb_nocheck_convert (unsigned int handle)
{
Unsigned long retvalue = 0 xffffffull <32 | handle;
Return (retvalue );
}
# Endif/* hdb_h_defined */