Skip to content

Commit

Permalink
done one of the TODOs plus some code clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
pzaino committed Nov 22, 2023
1 parent 355a26b commit 9b88e21
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 32 deletions.
4 changes: 2 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@
],
"C_Cpp.default.intelliSenseMode": "gcc-x64",
"C_Cpp.formatting": "clangFormat",
"c-cpp-compile-run.cpp-flags": "-Wall -Wextra ",
"c-cpp-compile-run.c-flags": "-Wall -Wextra -I${workspaceFolder}/src ",
"c-cpp-compile-run.cpp-flags": "-Wall -Wextra -pedantic",
"c-cpp-compile-run.c-flags": "-Wall -Wextra -pedantic -I${workspaceFolder}/src ",
"editor.insertSpaces": false,
"editor.trimAutoWhitespace": true,
"editor.detectIndentation": true,
Expand Down
95 changes: 66 additions & 29 deletions src/zvector.c
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,7 @@ static void *safe_strncpy(const char * const str_src,

tmp_dst[sizeof(tmp_dst) - 1] = 0;

str_dst = (void *)malloc(sizeof(char *) * (sizeof(tmp_dst) + 1));
str_dst = malloc(sizeof(char *) * (sizeof(tmp_dst) + 1));
if ( str_dst == NULL )
{
log_msg(ZVLP_ERROR, "Error: %*i, %s\n", 8, -1000, "Out of memory!");
Expand Down Expand Up @@ -378,7 +378,7 @@ static void p_throw_error(const zvect_retval error_code,
ZVECT_ALWAYSINLINE
static inline
#endif // ZVECT_MEMX_METHOD
void *p_vect_memcpy(const void *__restrict dst, const void *__restrict src,
void *p_vect_memcpy(const void * __restrict dst, const void * __restrict src,
size_t size)
{
#if (ZVECT_MEMX_METHOD == 0)
Expand Down Expand Up @@ -605,28 +605,65 @@ static inline zvect_retval lock_after_signal(const vector v,
return 0;
}

/*
* TODO: Write a generic function to allow user to use signals:
* wait_for_signal(v, lock_type, f1, f2, f3, ...)
* where f1 is a function that returns true if the signal
* should be sent, and f2, f3, ... are functions that
* should be called before the signal is sent.
* Example:
*
static inline zvect_retval wait_for_signal(const vector v, const int32_t lock_type, bool (*f1)(const vector v), ) {
if (lock_type >= v->lock_type) {
if (!mutex_trylock(&(v->lock))) {
while(!(*f1)(v)) {
// wait until we get a signal
pthread_cond_wait(&(v->cond), &(v->lock))
}
return 1;
}
}
return 0;
}
/* This function waits for a signal from another thread
* and then it locks the vector.
* It's used by the ZVector primitives.
* The function takes a variable number of arguments.
* The first argument is the vector to lock.
* The second argument is the lock type.
* The third argument is a function that returns a boolean
* value. This function is used to check if the condition
* for the signal is true or not.
* The fourth argument is a function that is called before
* the signal is sent.
* The fifth argument is a function that is called after
* the signal is sent.
*/

// Function prototype for condition check function
typedef bool (*condition_func)(const vector*);

// Function prototype for other functions to be called before signal
typedef void (*before_signal_func)(void);

static inline bool wait_for_signal(ivector v, const int32_t lock_type,
condition_func f1, ...)
{
if (lock_type >= v->lock_type)
{
mutex_lock(&(v->lock));
while(!f1(&v)) {
va_list args;
va_start(args, f1);
before_signal_func func;

// Calling functions f2, f3, ... before the signal is sent
while ((func = va_arg(args, before_signal_func)) != NULL) {
func();
}

va_end(args);

// Wait for the condition to be true
#if (MUTEX_TYPE == 1)
pthread_cond_wait(&(v->cond), &(v->lock));
#elif (MUTEX_TYPE == 2)
LeaveCriticalSection(&(v->lock));
WaitForSingleObject(&(v->cond), INFINITE);
EnterCriticalSection(&(v->lock));
#endif
}
#if (MUTEX_TYPE == 1)
mutex_unlock(&(v->lock));
#elif (MUTEX_TYPE == 2)
LeaveCriticalSection(&(v->lock));
#endif
return true;
}
return false;
}

static inline zvect_retval send_signal(cvector v, const int32_t lock_type)
{
return (lock_type >= v->lock_type) ? pthread_cond_signal(&(v->cond)) : 0;
Expand Down Expand Up @@ -677,24 +714,24 @@ void p_init_zvect(void)
// Vector's Utilities:

ZVECT_ALWAYSINLINE
static inline zvect_retval p_vect_check(cvector x)
static inline zvect_retval p_vect_check(const_vector const x)
{
return (x == NULL) ? ZVERR_VECTUNDEF : 0;
}

ZVECT_ALWAYSINLINE
static inline zvect_index p_vect_capacity(cvector v)
static inline zvect_index p_vect_capacity(const_vector const v)
{
return ( v->cap_left + v->cap_right );
}

ZVECT_ALWAYSINLINE
static inline zvect_index p_vect_size(cvector v)
static inline zvect_index p_vect_size(const_vector const v)
{
return ( v->end > v->begin ) ? ( v->end - v->begin ) : ( v->begin - v->end );
}

static inline void p_item_safewipe(ivector v, void *const item)
static inline void p_item_safewipe(const_vector const v, void *const item)
{
if (item != NULL) {
if (!(v->status & ZVS_CUST_WIPE_ON)) {
Expand All @@ -715,7 +752,7 @@ static inline zvect_retval p_usr_status(zvect_index flag_id)
}
}

bool vect_check_status(ivector v, zvect_index flag_id)
bool vect_check_status(const_vector const v, zvect_index flag_id)
{
return (v->status >> flag_id) & 1U;
}
Expand Down Expand Up @@ -1132,7 +1169,7 @@ static inline zvect_retval p_vect_add_at(ivector v, const void *value,
return ZVERR_OUTOFMEM;
}
#else
v->data[base] = (void *)malloc(v->data_size);
v->data[base] = malloc(v->data_size);
if (v->data[base] == NULL)
return ZVERR_OUTOFMEM;
#endif
Expand All @@ -1147,7 +1184,7 @@ static inline zvect_retval p_vect_add_at(ivector v, const void *value,
return ZVERR_OUTOFMEM;
}
#else
v->data[base + vsize] = (void *)malloc(v->data_size);
v->data[base + vsize] = malloc(v->data_size);
if (v->data[base + vsize] == NULL)
return ZVERR_OUTOFMEM;
#endif
Expand Down
3 changes: 2 additions & 1 deletion src/zvector.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extern "C" {

// Declare required structs:
typedef struct p_vector * vector;
typedef struct p_vector const * const_vector;

#if defined(ZVECT_COOPERATIVE)
// Cooperative Scheduler support
Expand Down Expand Up @@ -151,7 +152,7 @@ void vect_clear(vector const v);
/*
* Vector status bits control
*/
bool vect_check_status(const vector v, zvect_index flag_id);
bool vect_check_status(const_vector const v, zvect_index flag_id);

bool vect_set_status(const vector v, zvect_index flag_id);

Expand Down

0 comments on commit 9b88e21

Please sign in to comment.