RCU fix: Compile vxrcu.c file. Use Mutex semaphore instead of Binary semaphore. Runtime memory allocation for 'local_rcu_rwlock' (#58)
**NOTE:** Debug printfs have been added in this commit for tracing purposes. OpenSSL, being a library, does not print error messages directly on stderr; instead, it maintains an error queue. Proper handling of the error queue will be implemented in commits for debug and trace. | TODO | Proper handling for debug messages in vxrcu.c | | --- | --- | Reviewed-on: http://13.234.246.121:3000/Neominds/ossl35vx69/pulls/58 Co-authored-by: siddhant <siddhant.singh@neominds.in> Co-committed-by: siddhant <siddhant.singh@neominds.in>
This commit is contained in:
@@ -111,7 +111,7 @@ $UTIL_COMMON=\
|
||||
threads_vxworks.c initthread.c \
|
||||
context.c sparse_array.c asn1_dsa.c packet.c param_build.c \
|
||||
param_build_set.c der_writer.c threads_lib.c params_dup.c \
|
||||
time.c params_idx.c
|
||||
time.c params_idx.c vxrcu.c
|
||||
|
||||
SOURCE[../libcrypto]=$UTIL_COMMON \
|
||||
mem.c mem_sec.c \
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
#include <openssl/trace.h>
|
||||
#include <openssl/engine.h>
|
||||
#include "conf_local.h"
|
||||
#include <openssl/vxrcu.c>
|
||||
#include <openssl/vxrcu.h>
|
||||
|
||||
DEFINE_STACK_OF(CONF_MODULE)
|
||||
DEFINE_STACK_OF(CONF_IMODULE)
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/vxrcu.h>
|
||||
|
||||
static CRYPTO_RWLOCK_VX *local_rcu_rwlock = NULL;
|
||||
static int is_rwlock_init = 0;
|
||||
|
||||
/*---------- Atomic routines ----------*/
|
||||
int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock)
|
||||
{
|
||||
CRYPTO_RWLOCK_VX *vx;
|
||||
|
||||
if (!val || !ret || !lock)
|
||||
{
|
||||
printf ("CRYPTO_atomic_load_int:: invalid parameter(s)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vx = (CRYPTO_RWLOCK_VX *)lock;
|
||||
semTake (vx->sem, WAIT_FOREVER);
|
||||
*ret = *val;
|
||||
semGive (vx->sem);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CRYPTO_atomic_store(uint64_t *dst, uint64_t val, CRYPTO_RWLOCK *lock)
|
||||
{
|
||||
CRYPTO_RWLOCK_VX *vx;
|
||||
|
||||
if (!dst || !lock)
|
||||
{
|
||||
printf ("CRYPTO_atomic_store:: invalid parameter(s)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
vx = (CRYPTO_RWLOCK_VX *)lock;
|
||||
semTake (vx->sem, WAIT_FOREVER);
|
||||
*dst = val;
|
||||
semGive (vx->sem);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*---------- RCU routines ----------*/
|
||||
CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers, OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
CRYPTO_RCU_LOCK *lock = OPENSSL_malloc (sizeof(CRYPTO_RCU_LOCK));
|
||||
if (!lock)
|
||||
{
|
||||
printf ("ossl_rcu_lock_new:: Failed to allocate memory for RCU lock\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lock->writer_lock = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
|
||||
if (!(lock->writer_lock))
|
||||
printf ("ossl_rcu_lock_new:: semMCreate failed for writer_lock\n");
|
||||
|
||||
lock->active_readers = 0;
|
||||
|
||||
if (!is_rwlock_init)
|
||||
{
|
||||
local_rcu_rwlock = OPENSSL_malloc (sizeof (CRYPTO_RWLOCK_VX));
|
||||
if (!local_rcu_rwlock)
|
||||
{
|
||||
printf ("ossl_rcu_lock_new:: Failed to allocate memory\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset (local_rcu_rwlock, sizeof (CRYPTO_RWLOCK_VX), 0);
|
||||
|
||||
local_rcu_rwlock->sem = semMCreate(SEM_Q_PRIORITY | SEM_DELETE_SAFE | SEM_INVERSION_SAFE);
|
||||
if (!(local_rcu_rwlock->sem))
|
||||
printf ("ossl_rcu_lock_new:: semMCreate failed for local_rcu_rwlock\n");
|
||||
|
||||
is_rwlock_init = 1;
|
||||
}
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
if (is_rwlock_init)
|
||||
{
|
||||
semDelete (local_rcu_rwlock);
|
||||
OPENSSL_free (local_rcu_rwlock);
|
||||
local_rcu_rwlock = NULL;
|
||||
is_rwlock_init = 0;
|
||||
}
|
||||
|
||||
if (!lock)
|
||||
{
|
||||
printf ("ossl_rcu_lock_free:: RCU lock is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
semDelete (lock->writer_lock);
|
||||
free(lock);
|
||||
}
|
||||
|
||||
void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
vxAtomicInc (&(lock->active_readers));
|
||||
}
|
||||
|
||||
void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
vxAtomicDec (&(lock->active_readers));
|
||||
}
|
||||
|
||||
void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
semMTake (lock->writer_lock, WAIT_FOREVER);
|
||||
}
|
||||
|
||||
void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
semMGive (lock->writer_lock);
|
||||
}
|
||||
|
||||
void *ossl_rcu_uptr_deref(void **p)
|
||||
{
|
||||
/* readers just dereference safely */
|
||||
return *p;
|
||||
}
|
||||
|
||||
void ossl_rcu_assign_uptr(void **p, void **v)
|
||||
{
|
||||
void *ret, *val;
|
||||
|
||||
ret = p;
|
||||
val = v;
|
||||
|
||||
/* publish new pointer immediately */
|
||||
CRYPTO_atomic_load_int(val, ret, local_rcu_rwlock);
|
||||
}
|
||||
|
||||
void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
int retVal = 0;
|
||||
struct rcu_cb_item *cb_items, *tmpcb;
|
||||
|
||||
semMTake (lock->writer_lock, WAIT_FOREVER);
|
||||
cb_items = lock->cb_items;
|
||||
lock->cb_items = NULL;
|
||||
semMGive (lock->writer_lock);
|
||||
|
||||
/* Wait until all readers finish */
|
||||
do {
|
||||
CRYPTO_atomic_load_int (&(lock->active_readers), &retVal,
|
||||
local_rcu_rwlock);
|
||||
taskDelay(0);
|
||||
|
||||
}while (retVal > 0);
|
||||
|
||||
/* handle any callbacks that we have */
|
||||
while (cb_items != NULL) {
|
||||
tmpcb = cb_items;
|
||||
cb_items = cb_items->next;
|
||||
tmpcb->fn(tmpcb->data);
|
||||
OPENSSL_free(tmpcb);
|
||||
}
|
||||
}
|
||||
|
||||
int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data)
|
||||
{
|
||||
if (!lock || !cb)
|
||||
{
|
||||
printf ("ossl_rcu_call:: invalid parameter(s)\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct rcu_cb_item *new = OPENSSL_zalloc(sizeof(*new));
|
||||
if (!new)
|
||||
{
|
||||
printf ("ossl_rcu_call:: memory allocation for RCU callback failed\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
new->data = data;
|
||||
new->fn = cb;
|
||||
|
||||
new->next = lock->cb_items;
|
||||
lock->cb_items = new;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,138 +0,0 @@
|
||||
#ifndef RCU_VX69_H
|
||||
#define RCU_VX69_H
|
||||
|
||||
#include <semLib.h>
|
||||
#include <vxAtomicLib.h>
|
||||
#include "../crypto/rcu_internal.h"
|
||||
|
||||
typedef struct crypto_rwlock_st {
|
||||
SEM_ID sem;
|
||||
}CRYPTO_RWLOCK_VX;
|
||||
|
||||
|
||||
/*---------- Atomic routines ----------*/
|
||||
int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock)
|
||||
{
|
||||
CRYPTO_RWLOCK_VX *vx;
|
||||
|
||||
if (!val || !ret || !lock)
|
||||
return 0;
|
||||
|
||||
vx = (CRYPTO_RWLOCK_VX *)lock;
|
||||
semTake (vx->sem, WAIT_FOREVER);
|
||||
*ret = *val;
|
||||
semGive (vx->sem);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int CRYPTO_atomic_store(uint64_t *dst, uint64_t val, CRYPTO_RWLOCK *lock)
|
||||
{
|
||||
CRYPTO_RWLOCK_VX *vx;
|
||||
|
||||
if (!dst || !lock)
|
||||
return 0;
|
||||
|
||||
vx = (CRYPTO_RWLOCK_VX *)lock;
|
||||
semTake (vx->sem, WAIT_FOREVER);
|
||||
*dst = val;
|
||||
semGive (vx->sem);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*---------- RCU routines ----------*/
|
||||
CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers, OSSL_LIB_CTX *ctx)
|
||||
{
|
||||
CRYPTO_RCU_LOCK *lock = malloc (sizeof(CRYPTO_RCU_LOCK));
|
||||
if (!lock)
|
||||
return NULL;
|
||||
|
||||
lock->writer_lock = semBCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE, SEM_EMPTY);
|
||||
lock->active_readers = 0;
|
||||
|
||||
return lock;
|
||||
}
|
||||
|
||||
void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
if (!lock) return;
|
||||
|
||||
semDelete (lock->writer_lock);
|
||||
free(lock);
|
||||
}
|
||||
|
||||
void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
vxAtomicInc (&(lock->active_readers));
|
||||
}
|
||||
|
||||
void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
vxAtomicDec (&(lock->active_readers));
|
||||
}
|
||||
|
||||
void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
semBTake (lock->writer_lock, WAIT_FOREVER);
|
||||
}
|
||||
|
||||
void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
semBGive (lock->writer_lock);
|
||||
}
|
||||
|
||||
void *ossl_rcu_uptr_deref(void **p)
|
||||
{
|
||||
/* readers just dereference safely */
|
||||
return *p;
|
||||
}
|
||||
|
||||
void ossl_rcu_assign_uptr(void **p, void **v)
|
||||
{
|
||||
/* publish new pointer immediately */
|
||||
*p = *v;
|
||||
|
||||
}
|
||||
|
||||
void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock)
|
||||
{
|
||||
struct rcu_cb_item *cb_items, *tmpcb;
|
||||
|
||||
semBTake (lock->writer_lock, WAIT_FOREVER);
|
||||
cb_items = lock->cb_items;
|
||||
lock->cb_items = NULL;
|
||||
semBGive (lock->writer_lock);
|
||||
|
||||
/* Wait until all readers finish */
|
||||
while (lock->active_readers > 0)
|
||||
taskDelay(1);
|
||||
|
||||
/* handle any callbacks that we have */
|
||||
while (cb_items != NULL) {
|
||||
tmpcb = cb_items;
|
||||
cb_items = cb_items->next;
|
||||
tmpcb->fn(tmpcb->data);
|
||||
OPENSSL_free(tmpcb);
|
||||
}
|
||||
}
|
||||
|
||||
int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data)
|
||||
{
|
||||
struct rcu_cb_item *new = OPENSSL_zalloc(sizeof(*new));
|
||||
|
||||
if (!lock || !cb) return 0;
|
||||
|
||||
if (new == NULL)
|
||||
return 0;
|
||||
|
||||
new->data = data;
|
||||
new->fn = cb;
|
||||
|
||||
new->next = lock->cb_items;
|
||||
lock->cb_items = new;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,26 @@
|
||||
#ifndef RCU_VX69_H
|
||||
#define RCU_VX69_H
|
||||
|
||||
#include <semLib.h>
|
||||
#include <vxAtomicLib.h>
|
||||
#include "../internal/rcu.h"
|
||||
#include "../crypto/rcu_internal.h"
|
||||
|
||||
typedef struct crypto_rwlock_st {
|
||||
SEM_ID sem;
|
||||
}CRYPTO_RWLOCK_VX;
|
||||
|
||||
int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock);
|
||||
int CRYPTO_atomic_store(uint64_t *dst, uint64_t val, CRYPTO_RWLOCK *lock);
|
||||
CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers, OSSL_LIB_CTX *ctx);
|
||||
void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock);
|
||||
void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock);
|
||||
void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock);
|
||||
void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock);
|
||||
void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock);
|
||||
void *ossl_rcu_uptr_deref(void **p);
|
||||
void ossl_rcu_assign_uptr(void **p, void **v);
|
||||
void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock);
|
||||
int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data);
|
||||
|
||||
#endif /*RCU_VX69_H*/
|
||||
Reference in New Issue
Block a user