-// :vi sw=4 ts=4 noet:
+ // :vi sw=4 ts=4 noet2
/*
==================================================================================
Copyright (c) 2019-2020 Nokia
#include <unistd.h>
#include <netdb.h>
#include <pthread.h>
+#include <immintrin.h>
+#include <stdbool.h>
#include <RIC_message_types.h> // needed for route manager messages
if( time( NULL ) > ok2clear ) { // things still stable after expiry
rmr_vlog( RMR_VL_INFO, "drop alarm cleared\n" );
alarm_raised = 0;
- uta_alarm( pctx, ALARM_DROPS | ALARM_CLEAR, prob_id++, "RMR message dropping has stopped" );
+ uta_alarm( pctx, ALARM_DROPS | ALARM_CLEAR, prob_id, "RMR message dropping has stopped" );
+ prob_id++;
}
}
}
}
// ---- utility -----------------------------------------------------------------------------------
+
+int isspace_with_fence(int c) {
+ _mm_lfence();
+ return isspace( c );
+}
+
/*
Little diddy to trim whitespace and trailing comments. Like shell, trailing comments
must be at the start of a word (i.e. must be immediatly preceeded by whitespace).
*/
static char* clip( char* buf ) {
- char* tok;
+ char* tok=NULL;
while( *buf && isspace( *buf ) ) { // skip leading whitespace
buf++;
}
}
- for( tok = buf + (strlen( buf ) - 1); tok > buf && isspace( *tok ); tok-- ); // trim trailing spaces too
+ for( tok = buf + (strlen( buf ) - 1); tok > buf && isspace_with_fence( *tok ); tok-- ); // trim trailing spaces too
*(tok+1) = 0;
return buf;
is no active table (first load), so we have to account for that (no locking).
*/
static void roll_tables( uta_ctx_t* ctx ) {
-
+ pthread_mutex_lock( ctx->rtgate ); // must hold lock to move to active
if( ctx->new_rtable == NULL || ctx->new_rtable->error ) {
rmr_vlog( RMR_VL_WARN, "new route table NOT rolled in: nil pointer or error indicated\n" );
ctx->old_rtable = ctx->new_rtable;
- ctx->new_rtable = NULL;
- return;
- }
-
- if( ctx->rtable != NULL ) { // initially there isn't one, so must check!
- pthread_mutex_lock( ctx->rtgate ); // must hold lock to move to active
+ }else if( ctx->rtable != NULL ) { // initially there isn't one, so must check!
ctx->old_rtable = ctx->rtable; // currently active becomes old and allowed to 'drain'
ctx->rtable = ctx->new_rtable; // one we've been adding to becomes active
- pthread_mutex_unlock( ctx->rtgate );
} else {
ctx->old_rtable = NULL; // ensure there isn't an old reference
ctx->rtable = ctx->new_rtable; // make new the active one
}
-
ctx->new_rtable = NULL;
+ pthread_mutex_unlock( ctx->rtgate );
}
/*
uint64_t key = 0; // the symtab key will be mtype or sub_id+mtype
char* tokens[128];
char* gtokens[64];
- int i;
int ngtoks; // number of tokens in the group list
int grp; // index into group list
int cgidx; // contiguous group index (prevents the addition of a contiguous group without ep)
rte->mtype = atoi( ts_field ); // capture mtype for debugging
for( grp = 0, cgidx = 0; grp < ngtoks; grp++ ) {
+ int i; // avoid sonar grumbling by defining this here
+
if( (ntoks = uta_rmip_tokenise( gtokens[grp], ctx->ip_list, tokens, 64, ',' )) > 0 ) { // remove any references to our ip addrs
for( i = 0; i < ntoks; i++ ) {
if( strcmp( tokens[i], ctx->my_name ) != 0 ) { // don't add if it is us -- cannot send to ourself
int grp; // group number
rtable_ent_t const* rte; // route table entry added
char* tokens[128];
- char* tok; // pointer into a token or string
+ char* tok=NULL; // pointer into a token or string
char wbuf[1024];
if( ! buf ) {
while( *buf && isspace( *buf ) ) { // skip leading whitespace
buf++;
}
- for( tok = buf + (strlen( buf ) - 1); tok > buf && isspace( *tok ); tok-- ); // trim trailing spaces too
+ for( tok = buf + (strlen( buf ) - 1); tok > buf && isspace_with_fence( *tok ); tok-- ); // trim trailing spaces too
*(tok+1) = 0;
memset( tokens, 0, sizeof( tokens ) );
break;
case 'u': // update current table, not a total replacement
- if( ! ctx->flags & CFL_FULLRT ) { // we cannot update until we have a full table from route generator
+ if( ! (ctx->flags & CFL_FULLRT) ) { // we cannot update until we have a full table from route generator
rmr_vlog( RMR_VL_WARN, "route table update ignored: full table not previously recevied" );
break;
}
return NULL;
}
- rt->gate = ctx->rtgate; // single mutex needed for all route tables
rt->ephash = ctx->ephash; // all route tables share a common endpoint hash
- pthread_mutex_init( rt->gate, NULL );
-
return rt;
}
do not need to run that portion of the table to deref like we do for the RTEs.
*/
static route_table_t* prep_new_rt( uta_ctx_t* ctx, int all ) {
- int counter = 0;
+ //int counter = 0;
route_table_t* rt;
if( ctx == NULL ) {
return NULL;
}
+ pthread_mutex_lock( ctx->rtgate );
if( (rt = ctx->old_rtable) != NULL ) {
ctx->old_rtable = NULL;
- while( rt->ref_count > 0 ) { // wait for all who are using to stop
- if( counter++ > 1000 ) {
- rmr_vlog( RMR_VL_WARN, "rt_prep_newrt: internal mishap, ref count on table seems wedged" );
- break;
- }
+ while( rt->ref_count > 0 ) { // wait for all who are using to stop
+ //if( counter++ > 1000 ) {
+ // rmr_vlog( RMR_VL_WARN, "rt_prep_newrt: internal mishap, ref count on table seems wedged" );
+ // break;
+ //}
+
+ pthread_mutex_unlock( ctx->rtgate );
usleep( 1000 ); // small sleep to yield the processer if that is needed
+ pthread_mutex_lock( ctx->rtgate );
+
}
if( rt->hash != NULL ) {
} else {
rt = NULL;
}
+ pthread_mutex_unlock( ctx->rtgate );
rt = uta_rt_clone( ctx, ctx->rtable, rt, all ); // also sets the ephash pointer
if( rt != NULL ) { // very small chance for nil, but not zero, so test
}
pthread_mutex_unlock( ctx->rtgate );
}
+
#endif