diff --git a/CMakeLists.txt b/CMakeLists.txt index 6ac7745..d78d1f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/include/utils/safe_mem.h b/include/utils/safe_mem.h index ca8d99a..462d26b 100644 --- a/include/utils/safe_mem.h +++ b/include/utils/safe_mem.h @@ -1,5 +1,7 @@ #include #include +#include +#include /* memory_object is a wrapper around a void pointer type @@ -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); \ No newline at end of file diff --git a/src/utils/safe_mem.c b/src/utils/safe_mem.c index e20b122..bd2cf8e 100644 --- a/src/utils/safe_mem.c +++ b/src/utils/safe_mem.c @@ -1,5 +1,7 @@ #include #include +#include +#include #include "../../include/utils/safe_mem.h" /* @@ -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 @@ -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; } \ No newline at end of file