implement RCU (Read-Copy-Update) operations. NOTE: vxrcu.c should be included in the openssl generated Makefile by ./Configure. (#20)
Reviewed-on: http://13.234.246.121:3000/Neominds/ossl35vx69/pulls/20 Co-authored-by: siddhant <siddhant.singh@neominds.in> Co-committed-by: siddhant <siddhant.singh@neominds.in>
This commit is contained in:
@@ -23,6 +23,7 @@
|
|||||||
#include <openssl/trace.h>
|
#include <openssl/trace.h>
|
||||||
#include <openssl/engine.h>
|
#include <openssl/engine.h>
|
||||||
#include "conf_local.h"
|
#include "conf_local.h"
|
||||||
|
#include <openssl/vxrcu.c>
|
||||||
|
|
||||||
DEFINE_STACK_OF(CONF_MODULE)
|
DEFINE_STACK_OF(CONF_MODULE)
|
||||||
DEFINE_STACK_OF(CONF_IMODULE)
|
DEFINE_STACK_OF(CONF_IMODULE)
|
||||||
|
|||||||
@@ -12,9 +12,21 @@
|
|||||||
# pragma once
|
# pragma once
|
||||||
|
|
||||||
#include "crypto/context.h"
|
#include "crypto/context.h"
|
||||||
|
#include <types/vxWind.h>
|
||||||
|
|
||||||
typedef void (*rcu_cb_fn)(void *data);
|
typedef void (*rcu_cb_fn)(void *data);
|
||||||
|
|
||||||
|
struct rcu_lock_st{
|
||||||
|
/* Callbacks to call for next ossl_synchronize_rcu */
|
||||||
|
struct rcu_cb_item *cb_items;
|
||||||
|
|
||||||
|
/* Mutex for writers */
|
||||||
|
SEM_ID writer_lock;
|
||||||
|
|
||||||
|
/* Reader counter */
|
||||||
|
volatile int active_readers;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct rcu_lock_st CRYPTO_RCU_LOCK;
|
typedef struct rcu_lock_st CRYPTO_RCU_LOCK;
|
||||||
|
|
||||||
CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers, OSSL_LIB_CTX *ctx);
|
CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers, OSSL_LIB_CTX *ctx);
|
||||||
|
|||||||
@@ -0,0 +1,158 @@
|
|||||||
|
#include <semLib.h>
|
||||||
|
#include <vxAtomicLib.h>
|
||||||
|
#include "../crypto/rcu_internal.h"
|
||||||
|
|
||||||
|
typedef struct crypto_rwlock_st {
|
||||||
|
SEM_ID sem;
|
||||||
|
}CRYPTO_RWLOCK_VX;
|
||||||
|
|
||||||
|
static CRYPTO_RWLOCK_VX *local_rcu_rwlock;
|
||||||
|
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)
|
||||||
|
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_INVERSION_SAFE,
|
||||||
|
SEM_EMPTY);
|
||||||
|
lock->active_readers = 0;
|
||||||
|
|
||||||
|
if (!is_rwlock_init)
|
||||||
|
{
|
||||||
|
local_rcu_rwlock->sem = semBCreate (SEM_Q_PRIORITY |
|
||||||
|
SEM_DELETE_SAFE | SEM_INVERSION_SAFE,
|
||||||
|
SEM_EMPTY);
|
||||||
|
is_rwlock_init = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return lock;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock)
|
||||||
|
{
|
||||||
|
if (is_rwlock_init)
|
||||||
|
{
|
||||||
|
semDelete (local_rcu_rwlock->sem);
|
||||||
|
is_rwlock_init = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
semBTake (lock->writer_lock, WAIT_FOREVER);
|
||||||
|
cb_items = lock->cb_items;
|
||||||
|
lock->cb_items = NULL;
|
||||||
|
semBGive (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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user