simple reference counting shared pointer

Signed-off-by: Cedric Roux <cedric.roux@eurecom.fr>
This commit is contained in:
Cedric Roux
2025-11-21 10:36:19 +01:00
parent 26efcc4989
commit cab6adbe94
5 changed files with 89 additions and 1 deletions

View File

@@ -7,6 +7,7 @@ add_library(ds OBJECT
hashtable.c
obj_hashtable.c
spsc_q.c
shared_pointer.c
)
target_include_directories(ds PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})

View File

@@ -0,0 +1,56 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#include "shared_pointer.h"
#include "common/utils/utils.h"
#define fatal(x, ...) do { \
if (!(x)) { \
fprintf(stderr, __VA_ARGS__); \
fflush(stderr); \
exit(1); \
} \
} while (0)
static void lock(shared_pointer_t *p)
{
fatal(pthread_mutex_lock(&p->m) == 0, "pthread_mutex_lock failed\n");
}
static void unlock(shared_pointer_t *p)
{
fatal(pthread_mutex_unlock(&p->m) == 0, "pthread_mutex_unlock failed\n");
}
shared_pointer_t *new_shared_pointer(void *p, void (*free)(void *p))
{
shared_pointer_t *s = malloc_or_fail(sizeof(*s));
s->p = p;
s->free = free;
s->count = 1;
pthread_mutex_init(&s->m, NULL);
return s;
}
void unref_shared_pointer(shared_pointer_t *p)
{
lock(p);
fatal(p->count, "unref_shared_pointer() called for a pointer with count == 0\n");
p->count--;
if (p->count) {
unlock(p);
return;
}
unlock(p);
p->free(p->p);
free(p);
}
void ref_shared_pointer(shared_pointer_t *p)
{
lock(p);
fatal(p->count, "ref_shared_pointer() called for a pointer with count == 0\n");
p->count++;
unlock(p);
}

View File

@@ -0,0 +1,21 @@
/*
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
*/
#ifndef COMMON_UTILS_DS_SHARED_POINTER_H
#define COMMON_UTILS_DS_SHARED_POINTER_H
#include <pthread.h>
typedef struct {
void *p;
void (*free)(void *p);
int count;
pthread_mutex_t m;
} shared_pointer_t;
shared_pointer_t *new_shared_pointer(void *p, void (*free)(void *p));
void unref_shared_pointer(shared_pointer_t *p);
void ref_shared_pointer(shared_pointer_t *p);
#endif /* COMMON_UTILS_DS_SHARED_POINTER_H */

View File

@@ -7,6 +7,16 @@
#include "../../alg/foreach.h"
#include <assert.h>
/* needed because shared_pointer.c is using DevAssert() and AssertFatal() */
void exit_function(const char *file, const char *function, const int line, const char *s, const int assert)
{
if (assert) {
abort();
} else {
exit(EXIT_SUCCESS);
}
}
/*
Example to show seq_arr_t capabilities and usage
To compile: gcc test_seq_array.c ../seq_arr.c ../../alg/find.c ../../alg/foreach.c

View File

@@ -6,7 +6,7 @@ target_link_libraries(test_time_manager_manual LOG CONFIG_LIB)
add_executable(test_time_manager_auto test_auto.c)
target_link_libraries(test_time_manager_auto time_management)
target_link_libraries(test_time_manager_auto LOG CONFIG_LIB)
target_link_libraries(test_time_manager_auto LOG CONFIG_LIB ds)
add_dependencies(tests test_time_manager_auto)
add_test(NAME time_management_tests