Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ target_link_libraries(safe-math-test cmocka)
target_link_libraries(safe-math-test safemathstatic)
target_link_libraries(safe-mem-test cmocka)
target_link_libraries(safe-mem-test safememstatic)

target_link_libraries(safe-mem-test pthread)

# enable testing
enable_testing()
Expand Down
13 changes: 13 additions & 0 deletions include/utils/safe_mem.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdatomic.h>
#include <pthread.h>

/*
memory_object is a wrapper around a void pointer type
Expand All @@ -9,8 +11,19 @@
typedef struct memory_object {
void *data;
bool freed;
pthread_mutex_t *mutex;
atomic_bool locked;
} memory_object;



int free_memory_object(memory_object *obj);
memory_object new_memory_object(void *input);
// retrieves the data object stored by memory_object
// this allows us to safely perform operations against it
// without worrying about concurrent access
void *get_data_memory_object(memory_object *obj);
// after modifying or operating with the data object
// return it to the memory_object and unlock the mutex
// allowing others to access it
int put_data_memory_object(memory_object *obj, void *data);
27 changes: 27 additions & 0 deletions src/utils/safe_mem.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include <stdlib.h>
#include <stdbool.h>
#include <stdatomic.h>
#include <pthread.h>
#include "../../include/utils/safe_mem.h"

/*
Expand All @@ -23,6 +25,29 @@ int free_memory_object(memory_object *obj) {
return 0;
}

void *get_data_memory_object(memory_object *obj) {
// try locking otherwise return null pointer
int status = pthread_mutex_trylock(obj->mutex);
if (!status) {
return NULL;
}
void *pdata = atomic_load(&obj->data);
atomic_store(&obj->locked, true);
return pdata;
}

int put_data_memory_object(memory_object *obj, void *data) {
// if this check fails, it means get_data_memory_object wasnt called
// and thus is an error, so return -1
if (!atomic_load(&obj->locked)) {
return -1;
}
atomic_store(&obj->data, data);
atomic_store(&obj->locked, false);
pthread_mutex_unlock(obj->mutex);
return 0;
}

/*
new_memory_object is used to return an initialized memory_object
with the data member set to the void pointer
Expand All @@ -31,5 +56,7 @@ memory_object new_memory_object(void *input) {
memory_object mobj;
mobj.freed = false;
mobj.data = input;
mobj.mutex = NULL;
pthread_mutex_init(mobj.mutex, NULL);
return mobj;
}