Data Structures

Reference counting
[CDS library - Common Data Structures]

Experimental functions for reference counting (to simplify this code elsewhere). More...

Collaboration diagram for Reference counting:

Data Structures


Detailed Description

Reference counter (reference_counter_data_t) holds integer number which should be changed using functions add_reference and remove_reference. Using these functions is the number read/changed from locked section guarded by one mutex from a set of 'group mutexes'.

Often used scenario:

Note that mutex for adding references is needed because references are not added from critical section guarded by main list mutex but can be added whenever.

Typical usage:

 struct some_structure {
     ...
     reference_counter_data_t ref;
     ...
 };

 reference_counter_group_t *some_grp;
 
 void init()
 {
     some_grp = init_reference_counter_group(16);
 }

 void destroy()
 {
     free_reference_counter_group(some_grp);
 }
 
 ...

 // adding a member:
 struct some_struct *ss = malloc(...);
 init_reference_counter(some_grp, &ss->ref);
 lock(list);
 add_to_list(ss);
 unlock(list);

 ...
 // adding a reference doesn't need to lock list
 // can be done only by a reference owner
 add_reference(&ss->ref);

 // releasing a member when not needed for caller and there is
 // no way how to obtain reference for released member
 // (no way how to find a member in list)
 if (remove_reference(&ss->ref)) {
     // last reference removed
     lock(list);
     remove_from_list(ss);
     free(ss);
     unlock(list);
 }
  
 // or 
 // releasing a member when not needed for caller and it is possible 
 // to 'search' in the list (reference to released member can be somehow 
 // obtained by inspecting the list):
 lock(list);
 if (remove_reference(&ss->ref)) {
     // last reference removed
     remove_from_list(ss);
     free(ss);
 } 
 unlock(list);
Todo:
use atomic operations instead of locking

Function Documentation

void add_reference ( reference_counter_data_t ref  ) 

This function can be called only by owner of at least one reference!

Definition at line 52 of file ref_cntr.c.

References reference_counter_data_t::cntr, and reference_counter_data_t::mutex.

reference_counter_group_t* create_reference_counter_group ( int  mutex_cnt  ) 

All reference counters 'belonging' to this group are using the same set of mutexes.

Definition at line 7 of file ref_cntr.c.

References cds_malloc, reference_counter_group_t::mutex_cnt, reference_counter_group_t::mutex_to_assign, and reference_counter_group_t::mutexes.

void free_reference_counter_group ( reference_counter_group_t grp  ) 

After this function call no reference counter initialized by this group can be used.

Definition at line 27 of file ref_cntr.c.

References cds_free, reference_counter_group_t::mutex_cnt, and reference_counter_group_t::mutexes.

int get_reference_count ( reference_counter_data_t ref  ) 

This function is mostly useless.

Definition at line 61 of file ref_cntr.c.

References reference_counter_data_t::cntr, and reference_counter_data_t::mutex.

void init_reference_counter ( reference_counter_group_t grp,
reference_counter_data_t ref 
)

After call to this function, the caller is owner of first reference. From now it can call other functions like add_reference or remove_reference.

This function initializes the mutex - it chooses one from group mutexes. The mutex can not be changed after this call (it is only for reading).

Definition at line 40 of file ref_cntr.c.

References reference_counter_data_t::cntr, reference_counter_data_t::mutex, reference_counter_group_t::mutex_cnt, reference_counter_group_t::mutex_to_assign, and reference_counter_group_t::mutexes.

Referenced by msg_queue_init_ref_cnt().

Here is the caller graph for this function:

int remove_reference ( reference_counter_data_t ref  ) 

This function can be called only by owner of at least one reference!

Return values:
0 if reference removed, but other references exist
1 if removed last reference

Definition at line 72 of file ref_cntr.c.

References reference_counter_data_t::cntr, and reference_counter_data_t::mutex.