merge with master

This commit is contained in:
lukashov
2015-11-23 17:48:59 +01:00
5371 changed files with 1239495 additions and 2138470 deletions
+368 -332
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -37,287 +37,311 @@
#include <ctype.h>
#include <stdlib.h> // for random
//-----------------------------------------------------------------------------
at_command_t g_at_response_mapping[] ={
{ "AT+CGATT=" , at_attach_or_detach },
{ "AT+CGATT?" , at_read_attach_status },
{ "AT+CGDCONT=" , at_set_pdcp_context },
{ "AT+CGDCONT?" , at_read_pdp_context },
{ "AT+CGACT?" , at_read_act_status },
{ "AT+CGACT=" , at_activate_pdp_context },
{ "AT+CGPADDR=" , at_read_pdp_add },
{ "AT+CGEQOS=" , at_show_eps_qos },
{ "AT+CGETFADS=", at_set_tfad_context },
{ "AT+CGETFADR=", at_read_tfad_context },
{ "AT+CGEBRMOD=", at_mod_bearer_req },
{ "AT+CGEBRMOD?", at_read_dedicated_bearer_cid },
{ "null" , NULL}
at_command_t g_at_response_mapping[] = {
{ "AT+CGATT=" , at_attach_or_detach },
{ "AT+CGATT?" , at_read_attach_status },
{ "AT+CGDCONT=" , at_set_pdcp_context },
{ "AT+CGDCONT?" , at_read_pdp_context },
{ "AT+CGACT?" , at_read_act_status },
{ "AT+CGACT=" , at_activate_pdp_context },
{ "AT+CGPADDR=" , at_read_pdp_add },
{ "AT+CGEQOS=" , at_show_eps_qos },
{ "AT+CGETFADS=", at_set_tfad_context },
{ "AT+CGETFADR=", at_read_tfad_context },
{ "AT+CGEBRMOD=", at_mod_bearer_req },
{ "AT+CGEBRMOD?", at_read_dedicated_bearer_cid },
{ "null" , NULL}
};
//-----------------------------------------------------------------------------
size_t at_grab_string(const unsigned char *input, unsigned char **output)
//-----------------------------------------------------------------------------
{
size_t size = 4, position = 0;
int inside_quotes = 0;
size_t size = 4, position = 0;
int inside_quotes = 0;
/* Allocate initial buffer in case string is empty */
*output = (unsigned char *)malloc(size);
if (*output == NULL) {
printf("PARSER_LOG:Ran out of memory!\n");
return 0;
}
/* Allocate initial buffer in case string is empty */
*output = (unsigned char *)malloc(size);
while (inside_quotes ||
( *input != ','
if (*output == NULL) {
printf("PARSER_LOG:Ran out of memory!\n");
return 0;
}
while (inside_quotes ||
( *input != ','
&& *input != ')'
&& *input != 0x0d
&& *input != 0x0a
&& *input != 0x00)) {
/* Check for quotes */
if (*input == '"') {
inside_quotes = ! inside_quotes;
}
/* We also allocate space for traling zero */
if (position + 2 > size) {
size += 10;
*output = (unsigned char *)realloc(*output, size);
if (*output == NULL) {
printf("PARSER_LOG:Ran out of memory!\n");
return 0;
}
}
/* Copy to output */
(*output)[position] = *input;
position++;
input ++;
/* Check for quotes */
if (*input == '"') {
inside_quotes = ! inside_quotes;
}
(*output)[position] = 0;
/* We also allocate space for traling zero */
if (position + 2 > size) {
size += 10;
*output = (unsigned char *)realloc(*output, size);
/* Strip quotes */
if ((*output)[0] == '"' && (*output)[position - 1]) {
memmove(*output, (*output) + 1, position - 2);
(*output)[position - 2] = 0;
if (*output == NULL) {
printf("PARSER_LOG:Ran out of memory!\n");
return 0;
}
}
printf("PARSER_LOG:Grabbed string from reply: \"%s\" (parsed %Id bytes)\n", *output, position);
return position;
/* Copy to output */
(*output)[position] = *input;
position++;
input ++;
}
(*output)[position] = 0;
/* Strip quotes */
if ((*output)[0] == '"' && (*output)[position - 1]) {
memmove(*output, (*output) + 1, position - 2);
(*output)[position - 2] = 0;
}
printf("PARSER_LOG:Grabbed string from reply: \"%s\" (parsed %Id bytes)\n", *output, position);
return position;
}
//-----------------------------------------------------------------------------
int at_parse_command(const unsigned char *input, const char *format, ...)
//-----------------------------------------------------------------------------
{
const char *fmt = format;
const char *inp = (const char *)input;
char *endptr;
unsigned char *out_us;
unsigned char *buffer;
size_t length;
size_t storage_size;
int *out_i;
long int *out_l;
va_list ap;
int error = 1;
const char *fmt = format;
const char *inp = (const char *)input;
char *endptr;
unsigned char *out_us;
unsigned char *buffer;
size_t length;
size_t storage_size;
int *out_i;
long int *out_l;
va_list ap;
int error = 1;
printf("PARSER_LOG:Parsing %s\n with %s\n", input, format);
printf("PARSER_LOG:Parsing %s\n with %s\n", input, format);
va_start(ap, format);
while (*fmt) {
switch(*fmt++) {
case '@':
if (*fmt == 0) {
printf("PARSER_LOG:Invalid format string: %s\n", format);
error = 0;
goto end;
}
switch(*fmt++) {
case 'i':
out_i = va_arg(ap, int *);
*out_i = strtol(inp, &endptr, 10);
if (endptr == inp) {
error = 0;
goto end;
}
printf("PARSER_LOG:Parsed int %d\n", *out_i);
inp = endptr;
break;
case 'I':
out_i = va_arg(ap, int *);
*out_i = strtol(inp, &endptr, 10);
if (endptr == inp) {
printf("PARSER_LOG:Number empty\n");
*out_i = 0;
} else {
printf("PARSER_LOG:Parsed int %d\n", *out_i);
inp = endptr;
}
break;
case 'l':
out_l = va_arg(ap, long int *);
*out_l = strtol(inp, &endptr, 10);
if (endptr == inp) {
error = 0;
goto end;
}
printf("PARSER_LOG:Parsed long int %ld\n", *out_l);
inp = endptr;
break;
case 'r':
out_us = va_arg(ap, unsigned char *);
storage_size = va_arg(ap, size_t);
length = at_grab_string(inp, &buffer);
printf("PARSER_LOG:Parsed raw string \"%s\"\n", buffer);
if (strlen(buffer) > storage_size) {
free(buffer);
error = 0;
goto end;
}
strcpy(out_us, buffer);
free(buffer);
inp += length;
break;
case '@':
if (*inp++ != '@') {
error = 0;
goto end;
}
break;
case '0':
/* Just skip the rest */
goto end;
default:
printf("PARSER_LOG:Invalid format string (@%c): %s\n", *(fmt - 1), format);
error = 0;
goto end;
}
break;
va_start(ap, format);
case ' ':
while (isspace(*inp)) inp++;
break;
default:
if (*inp++ != *(fmt - 1)) {
error = 0;
goto end;
}
break;
}
}
/* Ignore trailing spaces */
while (isspace(*inp)) inp++;
if (*inp != 0) {
printf("PARSER_LOG:String do not end same!\n");
while (*fmt) {
switch(*fmt++) {
case '@':
if (*fmt == 0) {
printf("PARSER_LOG:Invalid format string: %s\n", format);
error = 0;
goto end;
}
switch(*fmt++) {
case 'i':
out_i = va_arg(ap, int *);
*out_i = strtol(inp, &endptr, 10);
if (endptr == inp) {
error = 0;
goto end;
}
printf("PARSER_LOG:Parsed int %d\n", *out_i);
inp = endptr;
break;
case 'I':
out_i = va_arg(ap, int *);
*out_i = strtol(inp, &endptr, 10);
if (endptr == inp) {
printf("PARSER_LOG:Number empty\n");
*out_i = 0;
} else {
printf("PARSER_LOG:Parsed int %d\n", *out_i);
inp = endptr;
}
break;
case 'l':
out_l = va_arg(ap, long int *);
*out_l = strtol(inp, &endptr, 10);
if (endptr == inp) {
error = 0;
goto end;
}
printf("PARSER_LOG:Parsed long int %ld\n", *out_l);
inp = endptr;
break;
case 'r':
out_us = va_arg(ap, unsigned char *);
storage_size = va_arg(ap, size_t);
length = at_grab_string(inp, &buffer);
printf("PARSER_LOG:Parsed raw string \"%s\"\n", buffer);
if (strlen(buffer) > storage_size) {
free(buffer);
error = 0;
goto end;
}
strcpy(out_us, buffer);
free(buffer);
inp += length;
break;
case '@':
if (*inp++ != '@') {
error = 0;
goto end;
}
break;
case '0':
/* Just skip the rest */
goto end;
default:
printf("PARSER_LOG:Invalid format string (@%c): %s\n", *(fmt - 1), format);
error = 0;
goto end;
}
break;
case ' ':
while (isspace(*inp)) inp++;
break;
default:
if (*inp++ != *(fmt - 1)) {
error = 0;
goto end;
}
break;
}
}
/* Ignore trailing spaces */
while (isspace(*inp)) inp++;
if (*inp != 0) {
printf("PARSER_LOG:String do not end same!\n");
error = 0;
goto end;
}
end:
va_end(ap);
return error;
va_end(ap);
return error;
}
//-----------------------------------------------------------------------------
void at_attach_or_detach(char *string,int position)
//-----------------------------------------------------------------------------
{
// From 3GPP TS 27.007 V10.4.0 (2011-06):
//---------------------+--------------------------------------------
// Command | Possible Response(s)
//---------------------+--------------------------------------------
// +CGATT=[<state>] | OK
// | ERROR
//---------------------+--------------------------------------------
// +CGATT? | +CGATT: <state>
//---------------------+--------------------------------------------
// +CGATT=? | +CGATT: (list of supported <state>s)
//---------------------+--------------------------------------------
// Description
// The execution command is used to attach the MT to, or detach the MT from, the Packet Domain service. After the
// command has completed, the MT remains in V.250 command state. If the MT is already in the requested state, the
// command is ignored and the OK response is returned. If the requested state cannot be achieved, an ERROR or
// +CME ERROR response is returned. Extended error responses are enabled by the +CMEE command.
// Any active PDP contexts will be automatically deactivated when the attachment state changes to detached.
// The read command returns the current Packet Domain service state.
// The test command is used for requesting information on the supported Packet Domain service states.
// NOTE:
// This command has the characteristics of both the V.250 action and parameter commands. Hence it has the
// read form in addition to the execution/set and test forms.
//
// Defined Values
// <state>: : a numeric parameter that indicates the state of PS attachment
// 0 detached
// 1 attached
// Other values are reserved and will result in an ERROR response to the execution command.
// From 3GPP TS 27.007 V10.4.0 (2011-06):
//---------------------+--------------------------------------------
// Command | Possible Response(s)
//---------------------+--------------------------------------------
// +CGATT=[<state>] | OK
// | ERROR
//---------------------+--------------------------------------------
// +CGATT? | +CGATT: <state>
//---------------------+--------------------------------------------
// +CGATT=? | +CGATT: (list of supported <state>s)
//---------------------+--------------------------------------------
// Description
// The execution command is used to attach the MT to, or detach the MT from, the Packet Domain service. After the
// command has completed, the MT remains in V.250 command state. If the MT is already in the requested state, the
// command is ignored and the OK response is returned. If the requested state cannot be achieved, an ERROR or
// +CME ERROR response is returned. Extended error responses are enabled by the +CMEE command.
// Any active PDP contexts will be automatically deactivated when the attachment state changes to detached.
// The read command returns the current Packet Domain service state.
// The test command is used for requesting information on the supported Packet Domain service states.
// NOTE:
// This command has the characteristics of both the V.250 action and parameter commands. Hence it has the
// read form in addition to the execution/set and test forms.
//
// Defined Values
// <state>: : a numeric parameter that indicates the state of PS attachment
// 0 detached
// 1 attached
// Other values are reserved and will result in an ERROR response to the execution command.
char *temp;
char *str="+CGATT: (0,1)\r\nOK\r\n";
int Error = -1,attach_status = -1;
if(string[position + 1] == '?')
{
printf("AT PARSER sending: %s\n",str);
at_response(str,strlen(str));
return;
}
temp = string + position +1;
Error = at_parse_command(temp," @i",&attach_status);
if(Error == 1)
{
switch(attach_status)
{
case 1:
printf("AT PARSER: Attach command received\n");
if (mt_attach_request() == 1)
{
at_response("OK\r\n",strlen("OK\r\n"));
}
else
{
at_response("ERROR\r\n",strlen("ERROR\r\n"));
}
break;
case 0:
printf("AT PARSER: Detach command received\n");
if (mt_detach_request() == 1)
{
at_response("OK\r\n",strlen("OK\r\n"));
}
else
{
at_response("ERROR\r\n",strlen("ERROR\r\n"));
}
break;
default:
printf("AT PARSER: Invalid value %d\n",attach_status);
memset(at_error_log,'\0',sizeof(at_error_log));
sprintf(at_error_log,"Invalid value %d",attach_status);
at_response(at_error_log,strlen(at_error_log));
break;
}
} else {
printf("AT PARSER: Parse failed\n");
memset(at_error_log,'\0',sizeof(at_error_log));
sprintf(at_error_log,"ERROR\r\n");
at_response(at_error_log,strlen(at_error_log));
char *temp;
char *str="+CGATT: (0,1)\r\nOK\r\n";
int Error = -1,attach_status = -1;
if(string[position + 1] == '?') {
printf("AT PARSER sending: %s\n",str);
at_response(str,strlen(str));
return;
}
temp = string + position +1;
Error = at_parse_command(temp," @i",&attach_status);
if(Error == 1) {
switch(attach_status) {
case 1:
printf("AT PARSER: Attach command received\n");
if (mt_attach_request() == 1) {
at_response("OK\r\n",strlen("OK\r\n"));
} else {
at_response("ERROR\r\n",strlen("ERROR\r\n"));
}
break;
case 0:
printf("AT PARSER: Detach command received\n");
if (mt_detach_request() == 1) {
at_response("OK\r\n",strlen("OK\r\n"));
} else {
at_response("ERROR\r\n",strlen("ERROR\r\n"));
}
break;
default:
printf("AT PARSER: Invalid value %d\n",attach_status);
memset(at_error_log,'\0',sizeof(at_error_log));
sprintf(at_error_log,"Invalid value %d",attach_status);
at_response(at_error_log,strlen(at_error_log));
break;
}
} else {
printf("AT PARSER: Parse failed\n");
memset(at_error_log,'\0',sizeof(at_error_log));
sprintf(at_error_log,"ERROR\r\n");
at_response(at_error_log,strlen(at_error_log));
}
}
//-----------------------------------------------------------------------------
void at_read_attach_status(char *string,int position)
//-----------------------------------------------------------------------------
{
if (mt_attach_state_request() == 1)
{
printf( "\n PARSER_LOG: UE is Attached\n");
at_response("+CGATT: 1\r\nOK\r\n",strlen("+CGATT: 1\r\nOK\r\n"));
} else {
printf( "\n PARSER_LOG: UE is Detached\n");
at_response("+CGATT: 0\r\nOK\r\n",strlen("+CGATT: 0\r\nOK\r\n"));
}
if (mt_attach_state_request() == 1) {
printf( "\n PARSER_LOG: UE is Attached\n");
at_response("+CGATT: 1\r\nOK\r\n",strlen("+CGATT: 1\r\nOK\r\n"));
} else {
printf( "\n PARSER_LOG: UE is Detached\n");
at_response("+CGATT: 0\r\nOK\r\n",strlen("+CGATT: 0\r\nOK\r\n"));
}
}
//-----------------------------------------------------------------------------
void at_set_pdcp_context(char *string,int position)
@@ -375,132 +399,144 @@ void at_read_dedicated_bearer_cid(char *string,int position)
int at_convert_hex_to_dec(char *temp,int size)
//-----------------------------------------------------------------------------
{
int res = 0,i =0,hex_value = 0,Power = 1,j;
for(i = 0; i < size;i++)
{
switch(temp[size - i - 1])
{
case 'A':
case 'a':hex_value = 10;
break;
case 'B':
case 'b':hex_value = 11;
break;
case 'C':
case 'c':hex_value = 12;
break;
case 'D':
case 'd':hex_value = 13;
break;
case 'E':
case 'e':hex_value = 14;
break;
case 'F':
case 'f':hex_value = 15;
break;
default: hex_value = temp[size - i - 1] - '0';
}
int res = 0,i =0,hex_value = 0,Power = 1,j;
for(j = 1,Power = 1; j <= i ; j++)
Power = Power * 16;
for(i = 0; i < size; i++) {
switch(temp[size - i - 1]) {
case 'A':
case 'a':
hex_value = 10;
break;
res = res + (hex_value * Power);
case 'B':
case 'b':
hex_value = 11;
break;
case 'C':
case 'c':
hex_value = 12;
break;
case 'D':
case 'd':
hex_value = 13;
break;
case 'E':
case 'e':
hex_value = 14;
break;
case 'F':
case 'f':
hex_value = 15;
break;
default:
hex_value = temp[size - i - 1] - '0';
}
return res;
for(j = 1,Power = 1; j <= i ; j++)
Power = Power * 16;
res = res + (hex_value * Power);
}
return res;
}
//-----------------------------------------------------------------------------
void at_parse_string(char * at_strP)
//-----------------------------------------------------------------------------
{
char *buffer = NULL;
char format[4] = "=?\n";
char * ptr;
int i=0,pos = -1,flag = 0;
char *buffer = NULL;
char format[4] = "=?\n";
char * ptr;
int i=0,pos = -1,flag = 0;
// was /r
if((buffer = strchr(at_strP,'\r'))!=NULL)
{
memset(at_command, 0, AT_CMD_BUFFSIZE);
memcpy(at_command, at_strP, buffer-at_strP);
//*(buffer + 1) = '\0';
printf("AT PARSER:received = %s\n",at_command);
} else {
printf("PARSER_LOG:invalid command : Enter Again\n");
memset(at_error_log,'\0',sizeof(at_error_log));
sprintf(at_error_log,"invalid command : Enter Again");
at_response(at_error_log,strlen(at_error_log));
return;
// was /r
if((buffer = strchr(at_strP,'\r'))!=NULL) {
memset(at_command, 0, AT_CMD_BUFFSIZE);
memcpy(at_command, at_strP, buffer-at_strP);
//*(buffer + 1) = '\0';
printf("AT PARSER:received = %s\n",at_command);
} else {
printf("PARSER_LOG:invalid command : Enter Again\n");
memset(at_error_log,'\0',sizeof(at_error_log));
sprintf(at_error_log,"invalid command : Enter Again");
at_response(at_error_log,strlen(at_error_log));
return;
}
buffer = at_command;
ptr = strpbrk(buffer,format);
pos = ptr - buffer;
while(strcmp(g_at_response_mapping[i].command,"null")!=0) {
if(strncmp(buffer,g_at_response_mapping[i].command,pos+1)== 0) {
flag=1;
break;
}
buffer = at_command;
ptr = strpbrk(buffer,format);
pos = ptr - buffer;
while(strcmp(g_at_response_mapping[i].command,"null")!=0)
{
if(strncmp(buffer,g_at_response_mapping[i].command,pos+1)== 0)
{
flag=1;
break;
}
i++;
}
if(flag == 0 )
{
printf("PARSER_LOG:unknown command \n");
memset(at_error_log,'\0',sizeof(at_error_log));
sprintf(at_error_log,"unknown command");
printf("IFM<-UeMgr [ label = \"Unknown AT CMD\" ] ;");
at_response(at_error_log,strlen(at_error_log));
return;
} else {
g_at_response_mapping[i].ResponseFunction(at_command,pos);
}
i++;
}
if(flag == 0 ) {
printf("PARSER_LOG:unknown command \n");
memset(at_error_log,'\0',sizeof(at_error_log));
sprintf(at_error_log,"unknown command");
printf("IFM<-UeMgr [ label = \"Unknown AT CMD\" ] ;");
at_response(at_error_log,strlen(at_error_log));
return;
} else {
g_at_response_mapping[i].ResponseFunction(at_command,pos);
}
}
//-----------------------------------------------------------------------------
void at_parse_init(void (*at_response_handler)(char*, int),
int (*mt_attach_state_request_handler)(void),
int (*mt_attach_request_handler)(void),
int (*mt_detach_request_handler)(void))
int (*mt_attach_state_request_handler)(void),
int (*mt_attach_request_handler)(void),
int (*mt_detach_request_handler)(void))
//-----------------------------------------------------------------------------
{
at_response = at_response_handler;
mt_attach_state_request = mt_attach_state_request_handler;
mt_attach_request = mt_attach_request_handler;
mt_detach_request = mt_detach_request_handler;
at_response = at_response_handler;
mt_attach_state_request = mt_attach_state_request_handler;
mt_attach_request = mt_attach_request_handler;
mt_detach_request = mt_detach_request_handler;
}
//-----------------------------------------------------------------------------
void at_null_callback_handler(char* string, int size)
//-----------------------------------------------------------------------------
{
char at_response[AT_CMD_BUFFSIZE];
char at_response[AT_CMD_BUFFSIZE];
assert(size > 0);
assert(size < AT_CMD_BUFFSIZE);
strncpy(at_response, string, size);
at_response[size] = 0;
printf("AT DEFAULT CALLBACK HANDLER RECEIVED RESPONSE: %s\n", at_response);
assert(size > 0);
assert(size < AT_CMD_BUFFSIZE);
strncpy(at_response, string, size);
at_response[size] = 0;
printf("AT DEFAULT CALLBACK HANDLER RECEIVED RESPONSE: %s\n", at_response);
}
//-----------------------------------------------------------------------------
int mt_null_attach_state_request_handler(void)
//-----------------------------------------------------------------------------
{
int n;
n=rand() %2; /* n is random number in range of 0 - 1 */
return(n);
int n;
n=rand() %2; /* n is random number in range of 0 - 1 */
return(n);
}
//-----------------------------------------------------------------------------
int mt_null_attach_request_handler(void)
//-----------------------------------------------------------------------------
{
int n;
n=rand() %2; /* n is random number in range of 0 - 1 */
return(n);
int n;
n=rand() %2; /* n is random number in range of 0 - 1 */
return(n);
}
//-----------------------------------------------------------------------------
int mt_null_detach_request_handler(void)
//-----------------------------------------------------------------------------
{
int n;
n=rand() %2; /* n is random number in range of 0 - 1 */
return(n);
int n;
n=rand() %2; /* n is random number in range of 0 - 1 */
return(n);
}
+8 -7
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -29,9 +29,9 @@
/*****************************************************************
*
* File Name : parser.h
* Author: Sharad Gupta
* Decription: contains declarations for parser functions
* File Name : parser.h
* Author: Sharad Gupta
* Decription: contains declarations for parser functions
*
* Copyright 2009, Hughes Systique India Private Limited
*
@@ -65,8 +65,8 @@
#define AT_CMD_BUFFSIZE 512
//----------------------------------------------------------------------------
typedef struct {
char *command;
void (*ResponseFunction) (char *,int);
char *command;
void (*ResponseFunction) (char *,int);
} at_command_t;
@@ -218,7 +218,8 @@ public_at_commands(void at_parse_string(char * str);)
This function register the handler, handling responses from AT commands parser.
@param at_response_handler handler procedure.
**/
public_at_commands(void at_parse_init(void (*at_response_handler)(char*, int), int (*mt_attach_state_request_handler)(void), int (*mt_attach_request_handler)(void), int (*mt_detach_request_handler)(void));)
public_at_commands(void at_parse_init(void (*at_response_handler)(char*, int), int (*mt_attach_state_request_handler)(void), int (*mt_attach_request_handler)(void),
int (*mt_detach_request_handler)(void));)
/**
\fn void at_null_callback_handler(char* string, int size)
This function register the handler, handling responses from AT commands parser.
+7 -6
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -31,7 +31,7 @@
#include "linux/module.h"
#ifdef BIGPHYSAREA
#ifdef ARCH_64
#ifdef ARCH_64
char *bigphys_ptr,*bigphys_current;
#else //ARCH_64
unsigned int bigphys_ptr,bigphys_current;
@@ -39,9 +39,10 @@ unsigned int bigphys_ptr,bigphys_current;
// return pointer to memory in big physical area aligned to 16 bytes
void* bigphys_malloc(int n) {
void* bigphys_malloc(int n)
{
int n2 = n + ((16-(n%16))%16);
#ifdef ARCH_64
@@ -58,7 +59,7 @@ void* bigphys_malloc(int n) {
bigphys_old = bigphys_current;
bigphys_current += n2;
#ifdef ARCH_64
#ifdef ARCH_64
printk("[BIGPHYSAREA] Allocated Memory top now @ %p\n",bigphys_current);
return ((void *)(bigphys_old));
#else //ARCH_64
@@ -71,4 +72,4 @@ EXPORT_SYMBOL(bigphys_malloc);
#endif
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+166 -130
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -38,7 +38,7 @@
#include <unistd.h>
#include <signal.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/wait.h>
@@ -51,52 +51,58 @@ extern cli_config *cli_cfg;
command commands[] = {
{0, "help",NULL,com_help, NULL,"Display this text" },
{0, "?",NULL,com_help, NULL, "help at any point" },
{2, "prompt",NULL,prompt, prompt_usage,"Set/get cli prompt" },
{2, "info",NULL,info, NULL,"get software information" },
{1, "start",NULL,start, start_usage,"Start eNB/UE instance" },
{1, "set",NULL,set, set_usage,"set log for a give component" },
{0, "exit",NULL,com_exit, NULL,"Exit using OpenAir CLI Interface" },
{0, (char *)NULL,NULL, NULL,NULL, (char *)NULL }
{0, "help",NULL,com_help, NULL,"Display this text" },
{0, "?",NULL,com_help, NULL, "help at any point" },
{2, "prompt",NULL,prompt, prompt_usage,"Set/get cli prompt" },
{2, "info",NULL,info, NULL,"get software information" },
{1, "start",NULL,start, start_usage,"Start eNB/UE instance" },
{1, "set",NULL,set, set_usage,"set log for a give component" },
{0, "exit",NULL,com_exit, NULL,"Exit using OpenAir CLI Interface" },
{0, (char *)NULL,NULL, NULL,NULL, (char *)NULL }
};
static uid_t real_uid;
void priv_init(void) {
real_uid = getuid();
void priv_init(void)
{
real_uid = getuid();
}
void priv_up(void) {
void priv_up(void)
{
if (seteuid(0) != 0) {
printf("[CLI] Error setting uid to %d\n", real_uid);
}
}
void priv_down(void) {
void priv_down(void)
{
if (seteuid(real_uid) != 0) {
printf("[CLI] Error setting uid to %d\n", 0);
}
}
int cli_start(void) {
int cli_start(void)
{
priv_init();
priv_down();
putenv("REMADDR=");
// get username
if ((username = getlogin()) == NULL) {
username = getenv("USER");
}
set_permissions_map();
// set login info
cli_login(username, CLI_MAX_NODES, CLI_MAX_CMDS);
// send welcome msg to the client
sprintf(buffer, "%s", WELCOME_MSG);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
printf(WELCOME_MSG);
printf("[CLI] started...\n");
sprintf(cli_cfg->prompt,"%s%c ", cli_prompt(), cli_cfg->promptchar);
@@ -105,21 +111,23 @@ int cli_start(void) {
}
int cli_loop(char * msg) {
int cli_loop(char * msg)
{
char *s;
/* Remove leading and trailing whitespace from the line.
Then, if there is anything left, add it to the history list
and execute it. */
s = stripwhite(msg);
if (*s) {
//add_history(s);
execute_line(s);
}
send(cli_cfg->cfd, cli_cfg->prompt, strlen(cli_cfg->prompt), 0);
return 0;
}
@@ -132,120 +140,139 @@ int cli_loop(char * msg) {
* default, config and admin respectively.
*
*/
int set_permissions_map(void) {
gid_t group[10];
int n, i;
int perm_num;
// get the number of supplementary group IDs
n = getgroups(10, group);
int set_permissions_map(void)
{
gid_t group[10];
int n, i;
int perm_num;
// get the number of supplementary group IDs
n = getgroups(10, group);
// give show permissions even if user has none
map_permissions = ADMIN_PERMISSION;
// give show permissions even if user has none
map_permissions = ADMIN_PERMISSION;
for (i=0; i<n; i++) {
perm_num = group[i] - 1000;
if (perm_num < 0 || perm_num > 31) {
continue;
}
//map_permissions |= (1 << perm_num);
map_permissions |= ((1 << (perm_num+1)) - 1);
for (i=0; i<n; i++) {
perm_num = group[i] - 1000;
if (perm_num < 0 || perm_num > 31) {
continue;
}
printf("[CLI] Permissions %04x for this session\n", map_permissions);
return 0;
//map_permissions |= (1 << perm_num);
map_permissions |= ((1 << (perm_num+1)) - 1);
}
printf("[CLI] Permissions %04x for this session\n", map_permissions);
return 0;
}
int cli_login(const char *username, int maxnodes, int maxcmds) {
int cli_login(const char *username, int maxnodes, int maxcmds)
{
cli_set_prompt_char();
printf("[CLI] Client initialised\n");
// log the connection
// telnets use REMADDR
host = getenv("REMADDR");
if (host) {
snprintf(g_sid, MAX_SID, "%s#%s", username, host);
printf("[CLI] login via telnet by user %s from address %s\n", username, host);
} else {
host = getenv("SSH_CLIENT");
if (host) {
char *cp;
// format is <rem_addr> <rem_port> <local_port>
// replace first space with ':', second terminates the string
cp = strchr(host, ' ');
if (cp) {
*cp = ':';
}
cp = strchr(host, ' ');
if (cp) {
*cp = '\0';
}
snprintf(g_sid, MAX_SID, "%s$%s", username, host);
printf("[CLI] login via SSH by user %s from address %s", username, host);
} else {
host = getenv("HOST");
if (host) {
snprintf(g_sid, MAX_SID, "%s$%s", username, host);
printf("[CLI] by user %s from host %s", username, host);
} else {
printf("[CLI]Login by user %s from unknown destination\n", username);
}
snprintf(g_sid, MAX_SID, "%s#%s", username, host);
printf("[CLI] login via telnet by user %s from address %s\n", username, host);
} else {
host = getenv("SSH_CLIENT");
if (host) {
char *cp;
// format is <rem_addr> <rem_port> <local_port>
// replace first space with ':', second terminates the string
cp = strchr(host, ' ');
if (cp) {
*cp = ':';
}
}
//register an exit function
atexit(cli_finish);
return 0;
}
char *cli_prompt(void) {
static char promptstr[200];
promptstr[0]='\0';
snprintf(promptstr, 200,"%s@%s",username, cli_cfg->prompt);
return promptstr;
}
cp = strchr(host, ' ');
int cli_set_prompt_char(void) {
if (map_permissions & ADMIN_PERMISSION) {
cli_cfg->promptchar = '#';
} else if (map_permissions & CONFIG_PERMISSION) {
cli_cfg->promptchar = '%';
} else if (map_permissions & SHOW_PERMISSION) {
cli_cfg->promptchar = '$';
}
return 0;
}
void cli_finish(void) {
char *cp;
if ((cp = strchr(g_sid, '#'))) {
if (cp) {
*cp = '\0';
printf("[CLI] logout via telnet by user %s from address %s\n", g_sid, cp+1);
} else if ((cp = strchr(g_sid, '$'))) {
*cp = '\0';
printf("[CLI] logout via SSH by user %s from address %s\n", g_sid, cp+1);
}
snprintf(g_sid, MAX_SID, "%s$%s", username, host);
printf("[CLI] login via SSH by user %s from address %s", username, host);
} else {
printf("[CLI] logout from %s\n", g_sid);
host = getenv("HOST");
if (host) {
snprintf(g_sid, MAX_SID, "%s$%s", username, host);
printf("[CLI] by user %s from host %s", username, host);
} else {
printf("[CLI]Login by user %s from unknown destination\n", username);
}
}
return;
}
//register an exit function
atexit(cli_finish);
return 0;
}
char *cli_prompt(void)
{
static char promptstr[200];
promptstr[0]='\0';
snprintf(promptstr, 200,"%s@%s",username, cli_cfg->prompt);
return promptstr;
}
int cli_set_prompt_char(void)
{
if (map_permissions & ADMIN_PERMISSION) {
cli_cfg->promptchar = '#';
} else if (map_permissions & CONFIG_PERMISSION) {
cli_cfg->promptchar = '%';
} else if (map_permissions & SHOW_PERMISSION) {
cli_cfg->promptchar = '$';
}
return 0;
}
void cli_finish(void)
{
char *cp;
if ((cp = strchr(g_sid, '#'))) {
*cp = '\0';
printf("[CLI] logout via telnet by user %s from address %s\n", g_sid, cp+1);
} else if ((cp = strchr(g_sid, '$'))) {
*cp = '\0';
printf("[CLI] logout via SSH by user %s from address %s\n", g_sid, cp+1);
} else {
printf("[CLI] logout from %s\n", g_sid);
}
return;
}
/* Execute a command line. */
int execute_line (char *line) {
int execute_line (char *line)
{
register int i;
command *command;
char *word;
/* Isolate the command word. */
i = 0;
while (line[i] && whitespace (line[i]))
i++;
word = line + i;
while (line[i] && !whitespace (line[i]))
i++;
@@ -273,29 +300,35 @@ int execute_line (char *line) {
/* Look up NAME as the name of a command, and return a pointer to that
command. Return a NULL pointer if NAME isn't a command name. */
command * find_command (char *name) {
command * find_command (char *name)
{
register int i;
for (i = 0; commands[i].name; i++){
for (i = 0; commands[i].name; i++) {
if (strcmp (name, commands[i].name) == 0)
return (&commands[i]);
}
return ((command *)NULL);
}
/* Strip whitespace from the start and end of STRING. Return a pointer
into STRING. */
char * stripwhite (char *string) {
char * stripwhite (char *string)
{
register char *s, *t;
for (s = string; whitespace (*s); s++)
;
if (*s == 0)
return (s);
t = s + strlen (s) - 1;
while (t > s && whitespace (*t))
t--;
*++t = '\0';
return s;
@@ -309,39 +342,42 @@ char * stripwhite (char *string) {
/* Print out help for ARG, or for all of the commands if ARG is
not present. */
int com_help (char *arg) {
int com_help (char *arg)
{
register int i;
int printed = 0;
for (i = 0; commands[i].name != NULL; i++){
for (i = 0; commands[i].name != NULL; i++) {
// if (!*arg || (strcmp (arg, commands[i].name) == 0)){
sprintf (buffer,"%s\t\t<%s>\n", commands[i].name, commands[i].doc);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
printed++;
// }
sprintf (buffer,"%s\t\t<%s>\n", commands[i].name, commands[i].doc);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
printed++;
// }
}
if (!printed) {
printf("No commands match `%s'. Possibilties are:\n", arg);
for (i = 0; commands[i].name; i++){
/* Print in six columns. */
if (printed == 6) {
printed = 0;
printf("\n");
}
printf("%s\t", commands[i].name);
printed++;
}
if (printed)
for (i = 0; commands[i].name; i++) {
/* Print in six columns. */
if (printed == 6) {
printed = 0;
printf("\n");
}
printf("%s\t", commands[i].name);
printed++;
}
if (printed)
printf("\n");
}
return (0);
}
int whitespace (char c) {
int whitespace (char c)
{
return (isspace((int)c));
}
+14 -12
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -49,13 +49,13 @@
#include <setjmp.h>
#include <signal.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/types.h>
//#include <readline/readline.h>
//#include <readline/history.h>
//#include <readline/readline.h>
//#include <readline/history.h>
typedef struct {
int port;
int sfd; //server fd
int cfd; // client fd
@@ -64,11 +64,11 @@ typedef struct {
int debug_paused;
char promptchar;
char prompt[200];
// char user_name[200];
int exit;
// char user_name[200];
int exit;
/*end*/
}cli_config;
} cli_config;
typedef struct {
@@ -77,7 +77,7 @@ typedef struct {
void *data;
int (*func)(char*);
int (*help)(char*);
char *doc; /* Documentation for this function. */
char *doc; /* Documentation for this function. */
} command;
@@ -128,10 +128,12 @@ char g_sid[MAX_SID];
int com_help (char * arg);
int com_exit (char *arg);
int prompt(char *arg),prompt_usage(void), info(char *arg);
int prompt(char *arg);
int prompt_usage(char *);
int info(char *arg);
int start(char *arg), set(char *arg);
int start_usage(void), set_usage(void);
int start_usage(char *), set_usage(char *);
/* Forward declarations. */
char *stripwhite (char *string);
+143 -111
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -47,78 +47,84 @@
extern cli_config *cli_cfg;
#define NEXT_OPT do {optv++;optc--; } while (0)
#define CHECK_OPTC do { if(!optc) { \
if((optc - 1) == 1){ \
fprintf(stderr, "[CLI]Error parsing command line options!\n"); \
} else { \
optv--; \
fprintf(stderr, "[CLI]You must provide a parameter when using the %s switch!\n", *optv); \
} \
} } while (0)
#define CHECK_OPTC do { if(!optc) { \
if((optc - 1) == 1){ \
fprintf(stderr, "[CLI]Error parsing command line options!\n"); \
} else { \
optv--; \
fprintf(stderr, "[CLI]You must provide a parameter when using the %s switch!\n", *optv); \
} \
} } while (0)
mapping log_comp[] = {
{"phy", 2},
{"mac", 3},
{"emu", 4},
{"ocg", 5},
{"omg", 6},
{NULL, -1}
{"phy", 2},
{"mac", 3},
{"emu", 4},
{"ocg", 5},
{"omg", 6},
{NULL, -1}
};
mapping log_level[] = {
{"error", 3},
{"warn", 4},
{"info", 6},
{"debug", 7},
{NULL, -1}
{"error", 3},
{"warn", 4},
{"info", 6},
{"debug", 7},
{NULL, -1}
};
mapping log_flag[] = {
{"none", 0x0},
{"low", 0x04},
{"med", 0x34},
{"full", 0x74},
{NULL, -1}
{"none", 0x0},
{"low", 0x04},
{"med", 0x34},
{"full", 0x74},
{NULL, -1}
};
/* ************************ CLI COMMANDS ************************** */
/* The user wishes to quit using this program. Just set DONE non-zero. */
int com_exit (char *arg) {
int com_exit (char *arg)
{
//set the xit value for the threads
cli_cfg->exit = 1;
cli_cfg->promptchar='\0';
cli_cfg->prompt[0]='\0';
snprintf(cli_cfg->prompt,200,"%s","oaicli");
snprintf(cli_cfg->prompt,200,"%s","oaicli");
close(cli_cfg->cfd);
return (0);
}
/* CLI error Function . */
void cli_error (char *caller) {
void cli_error (char *caller)
{
fprintf (stderr,"[CLI]an error running occured during the execution of %s function\n",
caller);
}
int prompt (char *arg) {
int prompt (char *arg)
{
// char buf[200];
if (cli_help("prompt", arg) == OK)
return 0;
if (!arg || !*arg){ // no arg is provided, run get func
if (!arg || !*arg) { // no arg is provided, run get func
snprintf(buffer,200,"%s\n", cli_cfg->prompt);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
// send(cli_cfg->cfd, cli_cfg->prompt, strlen(cli_cfg->prompt), 0);
}else {// set func
} else {// set func
snprintf(cli_cfg->prompt,200,"%s",arg);
sprintf( cli_cfg->prompt,"%s%c ", cli_prompt(), cli_cfg->promptchar);
}
return (0);
}
int info (char *arg) {
int info (char *arg)
{
sprintf(buffer, "CLI by user %s from host %s\n", username, host);
send(cli_cfg->cfd,buffer, strlen(buffer),0);
@@ -126,37 +132,40 @@ int info (char *arg) {
}
int start (char *arg) {
int start (char *arg)
{
// char buf[200];
char* optv[20];
int optc=0;
if (cli_help("start", arg) == OK)
return OK;
if (valid_argument ("start", arg) == ERR){
start_usage();
if (valid_argument ("start", arg) == ERR) {
start_usage("");
return ERR;
}
optc = token_argument(arg, optv);
process_argument(optc, optv);
return (0);
}
int set(char *arg){
int set(char *arg)
{
char* optv[20];
int optc=0;
if (cli_help("set", arg) == OK)
return OK;
if (valid_argument ("set", arg) == ERR){
set_usage();
if (valid_argument ("set", arg) == ERR) {
set_usage( NULL );
return ERR;
}
optc = token_argument(arg, optv);
process_argument(optc, optv);
return OK;
@@ -164,138 +173,161 @@ int set(char *arg){
}
/* Return non-zero if ARG is a valid argument for CALLER, else print
an error message and return zero. */
int valid_argument (char *caller, char *arg) {
int valid_argument (char *caller, char *arg)
{
if (!arg || !*arg) {
snprintf(buffer,200,"%s: argument required\n", caller);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
fprintf (stderr, "%s: argument required\n", caller);
return (ERR);
}
snprintf(buffer,200,"%s: argument required\n", caller);
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
fprintf (stderr, "%s: argument required\n", caller);
return (ERR);
}
return (OK);
}
int cli_help(char *caller, char * arg) {
int cli_help(char *caller, char * arg)
{
command *command;
if ((strcmp(arg, "-h") == 0 ) || (strcmp(arg, "?") == 0 ) || (strcmp(arg, "help") == 0 ) ||
(strcmp(arg, "-help") == 0 ) ||(strcmp(arg, "--help") == 0 )) {
command = find_command (caller); // we are sure that the command exists so no check is done
return ((*(command->help))(caller)); // return zero after calling help func
}
return ERR; // no help is requested bu the user
}
int token_argument(char *arg, char* optv[]) {
int token_argument(char *arg, char* optv[])
{
int tokc;
tokc = 0;
optv[tokc] = strtok(arg, " "); // get the first token
while (optv[tokc]!=NULL) {
tokc++;
optv[tokc] = strtok(NULL, " ");
optv[tokc] = strtok(NULL, " ");
}
return tokc;
return tokc;
}
int process_argument(int optc, char* optv[]) {
int process_argument(int optc, char* optv[])
{
int index;
int state;
int comp=0, level=0, flag=0x34, interval=0;
while (optc > 0) {
/* add an RB */
/* add an RB */
if ((strcmp(*optv, "ue") == 0) || (strcmp(*optv, "UE") == 0) ) {
NEXT_OPT; CHECK_OPTC;
index = atoi (*optv);
if (optc > 0){
NEXT_OPT; CHECK_OPTC;
state = atoi (*optv);
printf("[CLI] UE %d state %d\n", index, state);
oai_emulation.info.cli_start_ue[index]=state;
}
else
return ERR;
}
if ((strcmp(*optv, "enb") == 0) || (strcmp(*optv, "eNB") == 0) ) {
NEXT_OPT; CHECK_OPTC;
NEXT_OPT;
CHECK_OPTC;
index = atoi (*optv);
if (optc > 0) {
NEXT_OPT;CHECK_OPTC;
state = atoi (*optv);
printf("[CLI] eNB %d state %d\n", index, state);
oai_emulation.info.cli_start_enb[index]= state;
}
else
return ERR;
NEXT_OPT;
CHECK_OPTC;
state = atoi (*optv);
printf("[CLI] UE %d state %d\n", index, state);
oai_emulation.info.cli_start_ue[index]=state;
} else
return ERR;
}
if ((strcmp(*optv, "enb") == 0) || (strcmp(*optv, "eNB") == 0) ) {
NEXT_OPT;
CHECK_OPTC;
index = atoi (*optv);
if (optc > 0) {
NEXT_OPT;
CHECK_OPTC;
state = atoi (*optv);
printf("[CLI] eNB %d state %d\n", index, state);
oai_emulation.info.cli_start_enb[index]= state;
} else
return ERR;
}
// fixme
if ((strcmp(*optv, "log") == 0) || (strcmp(*optv, "LOG") == 0) ) {
NEXT_OPT; CHECK_OPTC;
NEXT_OPT;
CHECK_OPTC;
comp = map_str_to_int(log_comp, *optv);
NEXT_OPT;
if (optc > 0) {
CHECK_OPTC;
level = map_str_to_int(log_level, *optv);
}
else
return ERR;
NEXT_OPT;
if (optc > 0) {
CHECK_OPTC;
flag = map_str_to_int (log_flag, *optv);
}
CHECK_OPTC;
level = map_str_to_int(log_level, *optv);
} else
return ERR;
NEXT_OPT;
if (optc > 0) {
CHECK_OPTC;
interval = atoi (*optv);
CHECK_OPTC;
flag = map_str_to_int (log_flag, *optv);
}
printf("[CLI] OMG set log for comp %d level %d flag 0x%x interval %d\n",
comp, level, flag, interval);
NEXT_OPT;
if (optc > 0) {
CHECK_OPTC;
interval = atoi (*optv);
}
printf("[CLI] OMG set log for comp %d level %d flag 0x%x interval %d\n",
comp, level, flag, interval);
set_comp_log(comp, level, flag, interval);
}
NEXT_OPT;
}
return OK;
}
int prompt_usage(void) {
int prompt_usage(char *arg)
{
sprintf(buffer, "Usage: prompt [value]\n");
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
return 0;
}
int start_usage(void) {
int start_usage(char *arg)
{
sprintf(buffer, "Usage: start [enb|UE] [enb_index][0: stop, 1: start] \n");
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
sprintf(buffer, "Example to start enb 0: start enb 0 1 \n");
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
sprintf(buffer, "Example to stop ue &: start ue 1 0 \n");
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
return 0;
}
int set_usage(void) {
int set_usage( char *arg )
{
(void)(arg); // unused
sprintf(buffer, "Usage: set log [comp] [level:debug,info,warn,error][flag:none,low,med,full][intervale: 1-100] \n");
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
sprintf(buffer, "Example 1: set log omg debug\n");
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
sprintf(buffer, "Example 1: set log omg info med 10\n");
send(cli_cfg->cfd, buffer, strlen(buffer), 0);
return 0;
}
+7 -7
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -63,14 +63,14 @@ extern "C" {
# endif
/** @defgroup _cli_if Interfaces of CLI
* @{*/
* @{*/
public_cli_if( void cli_init (void); )
public_cli_if( int cli_server_init(cli_handler_t handler); )
public_cli_if(void cli_server_cleanup(void);)
public_cli_if(void cli_server_recv(const void * data, socklen_t len);)
/* @}*/
public_cli_if( void cli_init (void); )
public_cli_if( int cli_server_init(cli_handler_t handler); )
public_cli_if(void cli_server_cleanup(void);)
public_cli_if(void cli_server_recv(const void * data, socklen_t len);)
/* @}*/
#ifdef __cplusplus
}
+101 -78
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -44,9 +44,9 @@
#include <signal.h>
#include <stdint.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/un.h>
#include <unistd.h>
#include <netinet/in.h>
#include <net/if.h>
#include <signal.h>
@@ -55,7 +55,7 @@
#include "cli.h"
#include "UTIL/LOG/log.h"
#define MAX_NUM_CLIENTS 15
#define MAX_NUM_CLIENTS 15
#define MAX_LINE 100
struct sockaddr_in saddr;
@@ -68,136 +68,159 @@ cli_handler_t cli_server_handler= NULL;
cli_config *cli_cfg;
int cli_server_init(cli_handler_t handler) {
int cli_server_init(cli_handler_t handler)
{
int one = 1;
cli_init();
int one = 1;
cli_init();
cli_server_handler = handler;
if ((cli_cfg->sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return -1;
}
if (setsockopt(cli_cfg->sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
sizeof(one)) < 0) {
perror("setsockopt");
return -1;
}
LOG_I(CLI,"socket created %d\n", cli_cfg->sfd);
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(server_port);
if (bind(cli_cfg->sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
perror("bind");
return -1;
}
/* create telnet listener thread */
if (pthread_create(&cli_server_listener, NULL, cli_server_listen, NULL)) {
perror("thread");
return -1;
}
return 0;
cli_server_handler = handler;
if ((cli_cfg->sfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("socket");
return -1;
}
if (setsockopt(cli_cfg->sfd, SOL_SOCKET, SO_REUSEADDR, (char *) &one,
sizeof(one)) < 0) {
perror("setsockopt");
return -1;
}
LOG_I(CLI,"socket created %d\n", cli_cfg->sfd);
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl(INADDR_ANY);
saddr.sin_port = htons(server_port);
if (bind(cli_cfg->sfd, (struct sockaddr *) &saddr, sizeof(saddr)) < 0) {
perror("bind");
return -1;
}
/* create telnet listener thread */
if (pthread_create(&cli_server_listener, NULL, cli_server_listen, NULL)) {
perror("thread");
return -1;
}
return 0;
}
static void * cli_server_listen(void *arg) {
static void * cli_server_listen(void *arg)
{
struct sockaddr caddr;
socklen_t clen;
clen = sizeof(caddr);
printf("[CLI] server thread started\n");
// to be implemented
while (1){
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (listen(cli_cfg->sfd, MAX_NUM_CLIENTS) < 0) {
perror("listen");
exit(1);
}
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
printf("[CLI] server Started listening on %d\n", cli_cfg->sfd);
if ((cli_cfg->cfd = accept(cli_cfg->sfd, &caddr, &clen)) <0){
while (1) {
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
if (listen(cli_cfg->sfd, MAX_NUM_CLIENTS) < 0) {
perror("listen");
exit(1);
}
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
printf("[CLI] server Started listening on %d\n", cli_cfg->sfd);
if ((cli_cfg->cfd = accept(cli_cfg->sfd, &caddr, &clen)) <0) {
if (cli_cfg->cfd == EINTR )
continue;
continue;
else {
perror("error on accept\n");
exit(1);
perror("error on accept\n");
exit(1);
}
}
printf("[CLI] server accepted the connection %d from a new client\n", cli_cfg->cfd);
cli_cfg->exit = 0;
cli_start(); // init
cli_cfg->exit = 0;
cli_start(); // init
do {
clen = recv(cli_cfg->cfd, buffer, MAX_SOCK_BUFFER_SIZE, 0);
if (cli_server_handler)
cli_server_handler(buffer, clen);
}while (cli_cfg->exit == 0);
cli_server_handler(buffer, clen);
} while (cli_cfg->exit == 0);
cli_finish();
}
pthread_exit(NULL);
}
pthread_exit(NULL);
}
void cli_server_recv(const void * data, socklen_t len) {
void cli_server_recv(const void * data, socklen_t len)
{
char * msg = (char*) data;
//reomve the newlines
//reomve the newlines
msg[len]=0;
msg[len-1]=0;
msg[len-2]=0;
//Multiplex to the right handler if needed
//Multiplex to the right handler if needed
cli_loop(msg);
//sprintf(buffer, "%s_ACK", msg);
//len = send(fd, buffer, strlen(buffer), 0);
}
void cli_server_cleanup(void){
/* if (unlink(telnet_server_socket) < 0) {
perror("");
}
void cli_server_cleanup(void)
{
/* if (unlink(telnet_server_socket) < 0) {
perror("");
}
*/
printf("[CLI] server pthread exit ! \n");
if (cli_cfg->exit) close(cli_cfg->cfd);// close the client first
pthread_exit(NULL);
if (cli_cfg->exit) close(cli_cfg->cfd);// close the client first
pthread_exit(NULL);
pthread_cancel(cli_server_listener);
close(cli_cfg->sfd);
}
void cli_init (void) {
void cli_init (void)
{
cli_cfg = calloc(1, sizeof(cli_config));
memset(cli_cfg, 0, sizeof(cli_config));
cli_cfg->exit = 0;
cli_cfg->exit = 0;
cli_cfg->port = 1352;
cli_cfg->promptchar='\0';
cli_cfg->prompt[0]='\0';
snprintf(cli_cfg->prompt,200,"%s","oaicli");
cli_cfg->prompt[0]='\0';
snprintf(cli_cfg->prompt,200,"%s","oaicli");
}
#ifdef STANDALONE
int main() {
int main()
{
printf("start \n");
cli_init();
//Main process of telnet server
//Main process of telnet server
if (cli_server_init(cli_server_recv) < 0) {
printf("server init failed \n");
exit(-1);
}
while (cli_cfg->exit ==0) {
}
printf("server init done 1 \n");
cli_server_cleanup();
//pthread_join(telnet_server_listener, NULL);
printf("server init done \n");
return 0;
return 0;
}
#endif
+162 -90
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -43,21 +43,24 @@
//#include <mpi.h>
void job_list_init (Job_List_t * listP) {
void job_list_init (Job_List_t * listP)
{
listP->tail = NULL;
listP->head = NULL;
listP->nb_elements = 0;
}
void event_list_init (Event_List_t * listP) {
void event_list_init (Event_List_t * listP)
{
listP->tail = NULL;
listP->head = NULL;
listP->nb_elements = 0;
}
void pkt_list_init (Packet_OTG_List_t * listP) {
void pkt_list_init (Packet_OTG_List_t * listP)
{
listP->tail = NULL;
listP->head = NULL;
@@ -66,7 +69,8 @@ void pkt_list_init (Packet_OTG_List_t * listP) {
//-----------------------------------------------------------------------------
void job_list_free (Job_List_t * listP) {
void job_list_free (Job_List_t * listP)
{
Job_elt_t *le;
while ((le = job_list_remove_head (listP))) {
@@ -74,7 +78,8 @@ void job_list_free (Job_List_t * listP) {
}
}
void event_list_free (Event_List_t * listP) {
void event_list_free (Event_List_t * listP)
{
Event_elt_t *le;
while ((le = event_list_remove_head (listP))) {
@@ -82,7 +87,8 @@ void event_list_free (Event_List_t * listP) {
}
}
void pkt_list_free (Packet_OTG_List_t * listP) {
void pkt_list_free (Packet_OTG_List_t * listP)
{
Packet_otg_elt_t *le;
while ((le = pkt_list_remove_head (listP))) {
@@ -92,15 +98,18 @@ void pkt_list_free (Packet_OTG_List_t * listP) {
//-----------------------------------------------------------------------------
Job_elt_t * job_list_get_head (Job_List_t * listP) {
Job_elt_t * job_list_get_head (Job_List_t * listP)
{
return listP->head;
}
Event_elt_t * event_list_get_head (Event_List_t * listP) {
Event_elt_t * event_list_get_head (Event_List_t * listP)
{
return listP->head;
}
Packet_otg_elt_t * pkt_list_get_head (Packet_OTG_List_t * listP) {
Packet_otg_elt_t * pkt_list_get_head (Packet_OTG_List_t * listP)
{
return listP->head;
}
@@ -111,15 +120,18 @@ Packet_otg_elt_t * pkt_list_get_head (Packet_OTG_List_t * listP) {
* @param pointer on targeted list
* @return pointer on removed Job_elt_t
*/
Job_elt_t * job_list_remove_head (Job_List_t * listP) {
Job_elt_t * job_list_remove_head (Job_List_t * listP)
{
// access optimisation
Job_elt_t *head;
head = listP->head;
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -129,18 +141,22 @@ Job_elt_t * job_list_remove_head (Job_List_t * listP) {
} else {
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
}
return head;
}
Event_elt_t * event_list_remove_head (Event_List_t * listP) {
Event_elt_t * event_list_remove_head (Event_List_t * listP)
{
// access optimisation
Event_elt_t *head;
head = listP->head;
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -150,18 +166,22 @@ Event_elt_t * event_list_remove_head (Event_List_t * listP) {
} else {
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
}
return head;
}
Packet_otg_elt_t * pkt_list_remove_head (Packet_OTG_List_t * listP) {
Packet_otg_elt_t * pkt_list_remove_head (Packet_OTG_List_t * listP)
{
// access optimisation
Packet_otg_elt_t *head;
head = listP->head;
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -171,12 +191,14 @@ Packet_otg_elt_t * pkt_list_remove_head (Packet_OTG_List_t * listP) {
} else {
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
}
return head;
}
//-----------------------------------------------------------------------------
Job_elt_t * job_list_remove_element (Job_elt_t * elementP, Job_List_t * listP) {
Job_elt_t * job_list_remove_element (Job_elt_t * elementP, Job_List_t * listP)
{
// access optimisation;
Job_elt_t *head;
@@ -184,11 +206,13 @@ Job_elt_t * job_list_remove_element (Job_elt_t * elementP, Job_List_t * listP) {
if (elementP != NULL) {
// test head
head = listP->head;
if (listP->head == elementP) {
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -201,9 +225,11 @@ Job_elt_t * job_list_remove_element (Job_elt_t * elementP, Job_List_t * listP) {
if (head->next == elementP) {
head->next = elementP->next;
listP->nb_elements = listP->nb_elements - 1;
if (listP->tail == elementP) {
listP->tail = head;
}
return elementP;
} else {
head = head->next;
@@ -211,10 +237,12 @@ Job_elt_t * job_list_remove_element (Job_elt_t * elementP, Job_List_t * listP) {
}
}
}
return elementP;
}
Event_elt_t * event_list_remove_element (Event_elt_t * elementP, Event_List_t * listP) {
Event_elt_t * event_list_remove_element (Event_elt_t * elementP, Event_List_t * listP)
{
// access optimisation;
Event_elt_t *head;
@@ -222,11 +250,13 @@ Event_elt_t * event_list_remove_element (Event_elt_t * elementP, Event_List_t *
if (elementP != NULL) {
// test head
head = listP->head;
if (listP->head == elementP) {
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -239,9 +269,11 @@ Event_elt_t * event_list_remove_element (Event_elt_t * elementP, Event_List_t *
if (head->next == elementP) {
head->next = elementP->next;
listP->nb_elements = listP->nb_elements - 1;
if (listP->tail == elementP) {
listP->tail = head;
}
return elementP;
} else {
head = head->next;
@@ -249,10 +281,12 @@ Event_elt_t * event_list_remove_element (Event_elt_t * elementP, Event_List_t *
}
}
}
return elementP;
}
Packet_otg_elt_t * pkt_list_remove_element (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP) {
Packet_otg_elt_t * pkt_list_remove_element (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP)
{
// access optimisation;
Packet_otg_elt_t *head;
@@ -260,11 +294,13 @@ Packet_otg_elt_t * pkt_list_remove_element (Packet_otg_elt_t * elementP, Packet_
if (elementP != NULL) {
// test head
head = listP->head;
if (listP->head == elementP) {
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -277,9 +313,11 @@ Packet_otg_elt_t * pkt_list_remove_element (Packet_otg_elt_t * elementP, Packet_
if (head->next == elementP) {
head->next = elementP->next;
listP->nb_elements = listP->nb_elements - 1;
if (listP->tail == elementP) {
listP->tail = head;
}
return elementP;
} else {
head = head->next;
@@ -287,6 +325,7 @@ Packet_otg_elt_t * pkt_list_remove_element (Packet_otg_elt_t * elementP, Packet_
}
}
}
return elementP;
}
@@ -297,7 +336,8 @@ Packet_otg_elt_t * pkt_list_remove_element (Packet_otg_elt_t * elementP, Packet_
* @return pointer on removed Job_elt_t
*/
void job_list_add_head (Job_elt_t * elementP, Job_List_t * listP) {
void job_list_add_head (Job_elt_t * elementP, Job_List_t * listP)
{
// access optimisation;
Job_elt_t *head;
@@ -305,6 +345,7 @@ void job_list_add_head (Job_elt_t * elementP, Job_List_t * listP) {
if (elementP != NULL) {
head = listP->head;
listP->nb_elements = listP->nb_elements + 1;
// almost one element
if (head == NULL) {
listP->head = elementP;
@@ -316,7 +357,8 @@ void job_list_add_head (Job_elt_t * elementP, Job_List_t * listP) {
}
}
void event_list_add_head (Event_elt_t * elementP, Event_List_t * listP) {
void event_list_add_head (Event_elt_t * elementP, Event_List_t * listP)
{
// access optimisation;
Event_elt_t *head;
@@ -324,6 +366,7 @@ void event_list_add_head (Event_elt_t * elementP, Event_List_t * listP) {
if (elementP != NULL) {
head = listP->head;
listP->nb_elements = listP->nb_elements + 1;
// almost one element
if (head == NULL) {
listP->head = elementP;
@@ -335,7 +378,8 @@ void event_list_add_head (Event_elt_t * elementP, Event_List_t * listP) {
}
}
void pkt_list_add_head (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP) {
void pkt_list_add_head (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP)
{
// access optimisation;
Packet_otg_elt_t *head;
@@ -343,6 +387,7 @@ void pkt_list_add_head (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP)
if (elementP != NULL) {
head = listP->head;
listP->nb_elements = listP->nb_elements + 1;
// almost one element
if (head == NULL) {
listP->head = elementP;
@@ -354,7 +399,8 @@ void pkt_list_add_head (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP)
}
}
void event_list_add_element (Event_elt_t * elementP, Event_elt_t * previous, Event_List_t * listP) {
void event_list_add_element (Event_elt_t * elementP, Event_elt_t * previous, Event_List_t * listP)
{
// access optimisation;
Event_elt_t *next;
@@ -363,6 +409,7 @@ void event_list_add_element (Event_elt_t * elementP, Event_elt_t * previous, Eve
if (elementP != NULL && previous != NULL) {
next = previous->next;
listP->nb_elements = listP->nb_elements + 1;
// almost one element
if (next == NULL) {
previous->next = elementP;
@@ -381,7 +428,8 @@ void event_list_add_element (Event_elt_t * elementP, Event_elt_t * previous, Eve
* @param pointer on targeted list
* @return pointer on removed Job_elt_t
*/
void job_list_add_tail_eurecom (Job_elt_t * elementP, Job_List_t * listP) {
void job_list_add_tail_eurecom (Job_elt_t * elementP, Job_List_t * listP)
{
Job_elt_t *tail;
if (elementP != NULL) {
@@ -389,19 +437,22 @@ void job_list_add_tail_eurecom (Job_elt_t * elementP, Job_List_t * listP) {
listP->nb_elements = listP->nb_elements + 1;
elementP->next = NULL;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = elementP;
} else {
tail->next = elementP;
}
listP->tail = elementP;
} else {
//msg("[CNT_LIST][ERROR] add_cnt_tail() element NULL\n");
}
}
void event_list_add_tail_eurecom (Event_elt_t * elementP, Event_List_t * listP) {
void event_list_add_tail_eurecom (Event_elt_t * elementP, Event_List_t * listP)
{
Event_elt_t *tail;
if (elementP != NULL) {
@@ -409,19 +460,22 @@ void event_list_add_tail_eurecom (Event_elt_t * elementP, Event_List_t * listP)
listP->nb_elements = listP->nb_elements + 1;
elementP->next = NULL;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = elementP;
} else {
tail->next = elementP;
}
listP->tail = elementP;
} else {
//msg("[CNT_LIST][ERROR] add_cnt_tail() element NULL\n");
}
}
void pkt_list_add_tail_eurecom (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP) {
void pkt_list_add_tail_eurecom (Packet_otg_elt_t * elementP, Packet_OTG_List_t * listP)
{
Packet_otg_elt_t *tail;
if (elementP != NULL) {
@@ -429,12 +483,14 @@ void pkt_list_add_tail_eurecom (Packet_otg_elt_t * elementP, Packet_OTG_List_t *
listP->nb_elements = listP->nb_elements + 1;
elementP->next = NULL;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = elementP;
} else {
tail->next = elementP;
}
listP->tail = elementP;
} else {
//msg("[CNT_LIST][ERROR] add_cnt_tail() element NULL\n");
@@ -442,7 +498,8 @@ void pkt_list_add_tail_eurecom (Packet_otg_elt_t * elementP, Packet_OTG_List_t *
}
//-----------------------------------------------------------------------------
void job_list_add_list (Job_List_t * sublistP, Job_List_t * listP) {
void job_list_add_list (Job_List_t * sublistP, Job_List_t * listP)
{
if (sublistP) {
if (sublistP->head) {
@@ -450,12 +507,14 @@ void job_list_add_list (Job_List_t * sublistP, Job_List_t * listP) {
Job_elt_t *tail;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = sublistP->head;
} else {
tail->next = sublistP->head;
}
listP->tail = sublistP->tail;
// clear sublist
sublistP->head = NULL;
@@ -466,7 +525,8 @@ void job_list_add_list (Job_List_t * sublistP, Job_List_t * listP) {
}
}
void event_list_add_list (Event_List_t * sublistP, Event_List_t * listP) {
void event_list_add_list (Event_List_t * sublistP, Event_List_t * listP)
{
if (sublistP) {
if (sublistP->head) {
@@ -474,12 +534,14 @@ void event_list_add_list (Event_List_t * sublistP, Event_List_t * listP) {
Event_elt_t *tail;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = sublistP->head;
} else {
tail->next = sublistP->head;
}
listP->tail = sublistP->tail;
// clear sublist
sublistP->head = NULL;
@@ -490,7 +552,8 @@ void event_list_add_list (Event_List_t * sublistP, Event_List_t * listP) {
}
}
void pkt_list_add_list (Packet_OTG_List_t * sublistP, Packet_OTG_List_t * listP) {
void pkt_list_add_list (Packet_OTG_List_t * sublistP, Packet_OTG_List_t * listP)
{
if (sublistP) {
if (sublistP->head) {
@@ -498,12 +561,14 @@ void pkt_list_add_list (Packet_OTG_List_t * sublistP, Packet_OTG_List_t * listP)
Packet_otg_elt_t *tail;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = sublistP->head;
} else {
tail->next = sublistP->head;
}
listP->tail = sublistP->tail;
// clear sublist
sublistP->head = NULL;
@@ -515,78 +580,85 @@ void pkt_list_add_list (Packet_OTG_List_t * sublistP, Packet_OTG_List_t * listP)
}
//-----------------------------------------------------------------------------
void job_list_display (Job_List_t * listP) {
void job_list_display (Job_List_t * listP)
{
//Correct the output once the content of struct Job is fixed
//Correct the output once the content of struct Job is fixed
/*Job_elt_t *cursor;
unsigned short nb_elements = 0;
/*Job_elt_t *cursor;
unsigned short nb_elements = 0;
if (listP) {
cursor = listP->head;
if (cursor) {
while (cursor != NULL) {
if (cursor->job.type == eNB_DL)
printf ("DL eNB From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
else if (cursor->job.type == UE_DL)
printf ("DL UE From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
else if (cursor->job.type == UE_UL)
printf ("UL UE From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
else if (cursor->job.type == eNB_UL)
printf ("UL eNB From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
cursor = cursor->next;
nb_elements++;
}
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
if (listP) {
cursor = listP->head;
if (cursor) {
while (cursor != NULL) {
if (cursor->job.type == eNB_DL)
printf ("DL eNB From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
else if (cursor->job.type == UE_DL)
printf ("DL UE From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
else if (cursor->job.type == UE_UL)
printf ("UL UE From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
else if (cursor->job.type == eNB_UL)
printf ("UL eNB From (%d,%d)\n", (cursor->job).nid, (cursor->job).mid);
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
cursor = cursor->next;
nb_elements++;
}
} else {
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
}*/
}
void event_list_display (Event_List_t * listP) {
Event_elt_t *cursor;
unsigned short nb_elements = 0;
if (listP) {
cursor = listP->head;
if (cursor) {
while (cursor != NULL) {
printf ("Ev (%d,%d)\n", (cursor->event).type, (cursor->event).frame);
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
cursor = cursor->next;
nb_elements++;
}
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
}
} else {
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
}
} else {
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
}*/
}
void pkt_list_display (Packet_OTG_List_t * listP) {
Packet_otg_elt_t *cursor;
unsigned short nb_elements = 0;
void event_list_display (Event_List_t * listP)
{
Event_elt_t *cursor;
unsigned short nb_elements = 0;
if (listP) {
cursor = listP->head;
if (cursor) {
while (cursor != NULL) {
printf ("Pkt (DST %d, RB %d)\n", (cursor->otg_pkt).dst_id, (cursor->otg_pkt).rb_id);
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
cursor = cursor->next;
nb_elements++;
}
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
if (listP) {
cursor = listP->head;
if (cursor) {
while (cursor != NULL) {
printf ("Ev (%d,%d)\n", (cursor->event).type, (cursor->event).frame);
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
cursor = cursor->next;
nb_elements++;
}
} else {
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
}
} else {
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
}
}
void pkt_list_display (Packet_OTG_List_t * listP)
{
Packet_otg_elt_t *cursor;
unsigned short nb_elements = 0;
if (listP) {
cursor = listP->head;
if (cursor) {
while (cursor != NULL) {
printf ("Pkt (DST %d, RB %d)\n", (cursor->otg_pkt).dst_id, (cursor->otg_pkt).rb_id);
//msg ("From (%d,%d) To (%d,%d)\n", (cursor->job).node1, (cursor->job).master1, (cursor->job).node2, (cursor->job).master2);
cursor = cursor->next;
nb_elements++;
}
printf ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
//msg ("Found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
}
} else {
printf ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
//msg ("[SDU_MNGT][WARNING] display_cnt_dbl_lk_list_up() : list is NULL\n");
}
}
+2 -2
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -62,7 +62,7 @@ typedef struct Job_List_s {
int nb_elements;
} Job_List_t;
typedef struct Event_List_s{
typedef struct Event_List_s {
Event_elt_t *head;
Event_elt_t *tail;
int nb_elements;
+25 -25
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -42,15 +42,15 @@
/* Types regrouping both user-defined and regular events */
typedef enum {
MIN_ET=0,
OAI_ET=MIN_ET, // config events
OAI_ET=MIN_ET, // config events
SYS_ET,
TOPO_ET,
APP_ET,
EMU_ET,
DL_ET, // frame events
UL_ET,
S_ET,
PHY_ET, // protocol events
UL_ET,
S_ET,
PHY_ET, // protocol events
MAC_ET,
RLC_ET,
PDCP_ET,
@@ -64,14 +64,14 @@ typedef enum Job_type_e { JT_OTG, JT_PDCP, JT_PHY_MAC, JT_INIT_SYNC, JT_DL, JT_U
typedef enum Operation_Type_e { READ, WRITE, RESET} Operation_Type_t;
typedef struct Job_s {
enum Job_type_e type;
int exe_time; /* execution time at the worker*/
int nid; /* node id*/
eNB_flag_t eNB_flag;
frame_t frame;
int last_slot;
int next_slot;
int ctime;
enum Job_type_e type;
int exe_time; /* execution time at the worker*/
int nid; /* node id*/
eNB_flag_t eNB_flag;
frame_t frame;
int last_slot;
int next_slot;
int ctime;
} Job_t;
typedef struct Signal_buffers_s { // (s = transmit, r,r0 = receive)
@@ -96,13 +96,13 @@ typedef struct Packet_otg_s {
} Packet_otg_t;
typedef struct {
Event_Type_t type;
enum Operation_Type_e optype; //op
char *key;
void *value;
frame_t frame;
int ue;
int lcid;
Event_Type_t type;
enum Operation_Type_e optype; //op
char *key;
void *value;
frame_t frame;
int ue;
int lcid;
} Event_t;
/*typedef struct Global_Time {
@@ -117,9 +117,9 @@ typedef struct {
typedef struct Packet_otg_elt_s {
struct Packet_otg_elt_s *next;
struct Packet_otg_elt_s *previous;
Packet_otg_t otg_pkt;
struct Packet_otg_elt_s *next;
struct Packet_otg_elt_s *previous;
Packet_otg_t otg_pkt;
} Packet_otg_elt_t;
typedef struct Job_element_s {
@@ -128,8 +128,8 @@ typedef struct Job_element_s {
} Job_elt_t;
typedef struct Event_element_s {
struct Event_element *next;
struct Event_element *previous;
struct Event_element_s *next;
struct Event_element_s *previous;
Event_t event;
} Event_elt_t;
#endif
@@ -1,340 +1,334 @@
#ifndef __LIBLFDS611_H
/***** library header *****/
#define LFDS611_RELEASE_NUMBER_STRING "6.1.1"
/***** lfds611_abstraction *****/
/***** defines *****/
#if (defined _WIN64 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)
// TRD : 64-bit Windows user-mode with the Microsoft C compiler, any CPU
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <intrin.h>
typedef unsigned __int64 lfds611_atom_t;
#define LFDS611_INLINE __forceinline
#define LFDS611_ALIGN(alignment) __declspec( align(alignment) )
#define LFDS611_ALIGN_SINGLE_POINTER 8
#define LFDS611_ALIGN_DOUBLE_POINTER 16
#define LFDS611_BARRIER_COMPILER_LOAD _ReadBarrier()
#define LFDS611_BARRIER_COMPILER_STORE _WriteBarrier()
#define LFDS611_BARRIER_COMPILER_FULL _ReadWriteBarrier()
#define LFDS611_BARRIER_PROCESSOR_LOAD _mm_lfence()
#define LFDS611_BARRIER_PROCESSOR_STORE _mm_sfence()
#define LFDS611_BARRIER_PROCESSOR_FULL _mm_mfence()
#endif
#if (!defined _WIN64 && defined _WIN32 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)
// TRD : 32-bit Windows user-mode with the Microsoft C compiler, any CPU
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <intrin.h>
typedef unsigned long int lfds611_atom_t;
#define LFDS611_INLINE __forceinline
#define LFDS611_ALIGN(alignment) __declspec( align(alignment) )
#define LFDS611_ALIGN_SINGLE_POINTER 4
#define LFDS611_ALIGN_DOUBLE_POINTER 8
#define LFDS611_BARRIER_COMPILER_LOAD _ReadBarrier()
#define LFDS611_BARRIER_COMPILER_STORE _WriteBarrier()
#define LFDS611_BARRIER_COMPILER_FULL _ReadWriteBarrier()
#define LFDS611_BARRIER_PROCESSOR_LOAD _mm_lfence()
#define LFDS611_BARRIER_PROCESSOR_STORE _mm_sfence()
#define LFDS611_BARRIER_PROCESSOR_FULL _mm_mfence()
// TRD : this define is documented but missing in Microsoft Platform SDK v7.0
#define _InterlockedCompareExchangePointer(destination, exchange, compare) _InterlockedCompareExchange((volatile long *) destination, (long) exchange, (long) compare)
#endif
#if (defined _WIN64 && defined _MSC_VER && defined WIN_KERNEL_BUILD)
// TRD : 64-bit Windows kernel with the Microsoft C compiler, any CPU
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <wdm.h>
typedef unsigned __int64 lfds611_atom_t;
#define LFDS611_INLINE __forceinline
#define LFDS611_ALIGN(alignment) __declspec( align(alignment) )
#define LFDS611_ALIGN_SINGLE_POINTER 8
#define LFDS611_ALIGN_DOUBLE_POINTER 16
#define LFDS611_BARRIER_COMPILER_LOAD _ReadBarrier()
#define LFDS611_BARRIER_COMPILER_STORE _WriteBarrier()
#define LFDS611_BARRIER_COMPILER_FULL _ReadWriteBarrier()
#define LFDS611_BARRIER_PROCESSOR_LOAD _mm_lfence()
#define LFDS611_BARRIER_PROCESSOR_STORE _mm_sfence()
#define LFDS611_BARRIER_PROCESSOR_FULL _mm_mfence()
#endif
#if (!defined _WIN64 && defined _WIN32 && defined _MSC_VER && defined WIN_KERNEL_BUILD)
// TRD : 32-bit Windows kernel with the Microsoft C compiler, any CPU
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <wdm.h>
typedef unsigned long int lfds611_atom_t;
#define LFDS611_INLINE __forceinline
#define LFDS611_ALIGN(alignment) __declspec( align(alignment) )
#define LFDS611_ALIGN_SINGLE_POINTER 4
#define LFDS611_ALIGN_DOUBLE_POINTER 8
#define LFDS611_BARRIER_COMPILER_LOAD _ReadBarrier()
#define LFDS611_BARRIER_COMPILER_STORE _WriteBarrier()
#define LFDS611_BARRIER_COMPILER_FULL _ReadWriteBarrier()
#define LFDS611_BARRIER_PROCESSOR_LOAD _mm_lfence()
#define LFDS611_BARRIER_PROCESSOR_STORE _mm_sfence()
#define LFDS611_BARRIER_PROCESSOR_FULL _mm_mfence()
// TRD : this define is documented but missing in Microsoft Platform SDK v7.0
#define _InterlockedCompareExchangePointer(destination, exchange, compare) _InterlockedCompareExchange((volatile long *) destination, (long) exchange, (long) compare)
#endif
#if (defined __unix__ && defined __x86_64__ && __GNUC__)
// TRD : any UNIX with GCC on x64
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long int lfds611_atom_t;
#define LFDS611_INLINE inline
#define LFDS611_ALIGN(alignment) __attribute__( (aligned(alignment)) )
#define LFDS611_ALIGN_SINGLE_POINTER 8
#define LFDS611_ALIGN_DOUBLE_POINTER 16
#define LFDS611_BARRIER_COMPILER_LOAD __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_STORE __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_FULL __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_PROCESSOR_LOAD __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_STORE __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_FULL __sync_synchronize()
#endif
#if (defined __unix__ && defined __i386__ && __GNUC__)
// TRD : any UNIX with GCC on x86
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long int lfds611_atom_t;
#define LFDS611_INLINE inline
#define LFDS611_ALIGN(alignment) __attribute__( (aligned(alignment)) )
#define LFDS611_ALIGN_SINGLE_POINTER 4
#define LFDS611_ALIGN_DOUBLE_POINTER 8
#define LFDS611_BARRIER_COMPILER_LOAD __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_STORE __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_FULL __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_PROCESSOR_LOAD __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_STORE __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_FULL __sync_synchronize()
#endif
#if (defined __unix__ && defined __arm__ && __GNUC__)
// TRD : any UNIX with GCC on ARM
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long int lfds611_atom_t;
#define LFDS611_INLINE inline
#define LFDS611_ALIGN(alignment) __attribute__( (aligned(alignment)) )
#define LFDS611_ALIGN_SINGLE_POINTER 4
#define LFDS611_ALIGN_DOUBLE_POINTER 8
#define LFDS611_BARRIER_COMPILER_LOAD __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_STORE __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_FULL __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_PROCESSOR_LOAD __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_STORE __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_FULL __sync_synchronize()
#endif
#define LFDS611_BARRIER_LOAD LFDS611_BARRIER_COMPILER_LOAD; LFDS611_BARRIER_PROCESSOR_LOAD; LFDS611_BARRIER_COMPILER_LOAD
#define LFDS611_BARRIER_STORE LFDS611_BARRIER_COMPILER_STORE; LFDS611_BARRIER_PROCESSOR_STORE; LFDS611_BARRIER_COMPILER_STORE
#define LFDS611_BARRIER_FULL LFDS611_BARRIER_COMPILER_FULL; LFDS611_BARRIER_PROCESSOR_FULL; LFDS611_BARRIER_COMPILER_FULL
/***** enums *****/
enum lfds611_data_structure_validity
{
LFDS611_VALIDITY_VALID,
LFDS611_VALIDITY_INVALID_LOOP,
LFDS611_VALIDITY_INVALID_MISSING_ELEMENTS,
LFDS611_VALIDITY_INVALID_ADDITIONAL_ELEMENTS,
LFDS611_VALIDITY_INVALID_TEST_DATA
};
/***** structs *****/
struct lfds611_validation_info
{
lfds611_atom_t
min_elements,
max_elements;
};
/***** public prototypes *****/
void *lfds611_abstraction_malloc( size_t size );
void lfds611_abstraction_free( void *memory );
/***** library header *****/
#define LFDS611_RELEASE_NUMBER_STRING "6.1.1"
/***** lfds611_abstraction *****/
/***** defines *****/
#if (defined _WIN64 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)
// TRD : 64-bit Windows user-mode with the Microsoft C compiler, any CPU
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <intrin.h>
typedef unsigned __int64 lfds611_atom_t;
#define LFDS611_INLINE __forceinline
#define LFDS611_ALIGN(alignment) __declspec( align(alignment) )
#define LFDS611_ALIGN_SINGLE_POINTER 8
#define LFDS611_ALIGN_DOUBLE_POINTER 16
#define LFDS611_BARRIER_COMPILER_LOAD _ReadBarrier()
#define LFDS611_BARRIER_COMPILER_STORE _WriteBarrier()
#define LFDS611_BARRIER_COMPILER_FULL _ReadWriteBarrier()
#define LFDS611_BARRIER_PROCESSOR_LOAD _mm_lfence()
#define LFDS611_BARRIER_PROCESSOR_STORE _mm_sfence()
#define LFDS611_BARRIER_PROCESSOR_FULL _mm_mfence()
#endif
#if (!defined _WIN64 && defined _WIN32 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)
// TRD : 32-bit Windows user-mode with the Microsoft C compiler, any CPU
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <intrin.h>
typedef unsigned long int lfds611_atom_t;
#define LFDS611_INLINE __forceinline
#define LFDS611_ALIGN(alignment) __declspec( align(alignment) )
#define LFDS611_ALIGN_SINGLE_POINTER 4
#define LFDS611_ALIGN_DOUBLE_POINTER 8
#define LFDS611_BARRIER_COMPILER_LOAD _ReadBarrier()
#define LFDS611_BARRIER_COMPILER_STORE _WriteBarrier()
#define LFDS611_BARRIER_COMPILER_FULL _ReadWriteBarrier()
#define LFDS611_BARRIER_PROCESSOR_LOAD _mm_lfence()
#define LFDS611_BARRIER_PROCESSOR_STORE _mm_sfence()
#define LFDS611_BARRIER_PROCESSOR_FULL _mm_mfence()
// TRD : this define is documented but missing in Microsoft Platform SDK v7.0
#define _InterlockedCompareExchangePointer(destination, exchange, compare) _InterlockedCompareExchange((volatile long *) destination, (long) exchange, (long) compare)
#endif
#if (defined _WIN64 && defined _MSC_VER && defined WIN_KERNEL_BUILD)
// TRD : 64-bit Windows kernel with the Microsoft C compiler, any CPU
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <wdm.h>
typedef unsigned __int64 lfds611_atom_t;
#define LFDS611_INLINE __forceinline
#define LFDS611_ALIGN(alignment) __declspec( align(alignment) )
#define LFDS611_ALIGN_SINGLE_POINTER 8
#define LFDS611_ALIGN_DOUBLE_POINTER 16
#define LFDS611_BARRIER_COMPILER_LOAD _ReadBarrier()
#define LFDS611_BARRIER_COMPILER_STORE _WriteBarrier()
#define LFDS611_BARRIER_COMPILER_FULL _ReadWriteBarrier()
#define LFDS611_BARRIER_PROCESSOR_LOAD _mm_lfence()
#define LFDS611_BARRIER_PROCESSOR_STORE _mm_sfence()
#define LFDS611_BARRIER_PROCESSOR_FULL _mm_mfence()
#endif
#if (!defined _WIN64 && defined _WIN32 && defined _MSC_VER && defined WIN_KERNEL_BUILD)
// TRD : 32-bit Windows kernel with the Microsoft C compiler, any CPU
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <wdm.h>
typedef unsigned long int lfds611_atom_t;
#define LFDS611_INLINE __forceinline
#define LFDS611_ALIGN(alignment) __declspec( align(alignment) )
#define LFDS611_ALIGN_SINGLE_POINTER 4
#define LFDS611_ALIGN_DOUBLE_POINTER 8
#define LFDS611_BARRIER_COMPILER_LOAD _ReadBarrier()
#define LFDS611_BARRIER_COMPILER_STORE _WriteBarrier()
#define LFDS611_BARRIER_COMPILER_FULL _ReadWriteBarrier()
#define LFDS611_BARRIER_PROCESSOR_LOAD _mm_lfence()
#define LFDS611_BARRIER_PROCESSOR_STORE _mm_sfence()
#define LFDS611_BARRIER_PROCESSOR_FULL _mm_mfence()
// TRD : this define is documented but missing in Microsoft Platform SDK v7.0
#define _InterlockedCompareExchangePointer(destination, exchange, compare) _InterlockedCompareExchange((volatile long *) destination, (long) exchange, (long) compare)
#endif
#if (defined __unix__ && defined __x86_64__ && __GNUC__)
// TRD : any UNIX with GCC on x64
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long int lfds611_atom_t;
#define LFDS611_INLINE inline
#define LFDS611_ALIGN(alignment) __attribute__( (aligned(alignment)) )
#define LFDS611_ALIGN_SINGLE_POINTER 8
#define LFDS611_ALIGN_DOUBLE_POINTER 16
#define LFDS611_BARRIER_COMPILER_LOAD __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_STORE __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_FULL __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_PROCESSOR_LOAD __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_STORE __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_FULL __sync_synchronize()
#endif
#if (defined __unix__ && defined __i386__ && __GNUC__)
// TRD : any UNIX with GCC on x86
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long int lfds611_atom_t;
#define LFDS611_INLINE inline
#define LFDS611_ALIGN(alignment) __attribute__( (aligned(alignment)) )
#define LFDS611_ALIGN_SINGLE_POINTER 4
#define LFDS611_ALIGN_DOUBLE_POINTER 8
#define LFDS611_BARRIER_COMPILER_LOAD __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_STORE __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_FULL __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_PROCESSOR_LOAD __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_STORE __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_FULL __sync_synchronize()
#endif
#if (defined __unix__ && defined __arm__ && __GNUC__)
// TRD : any UNIX with GCC on ARM
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long int lfds611_atom_t;
#define LFDS611_INLINE inline
#define LFDS611_ALIGN(alignment) __attribute__( (aligned(alignment)) )
#define LFDS611_ALIGN_SINGLE_POINTER 4
#define LFDS611_ALIGN_DOUBLE_POINTER 8
#define LFDS611_BARRIER_COMPILER_LOAD __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_STORE __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_COMPILER_FULL __asm__ __volatile__ ( "" : : : "memory" )
#define LFDS611_BARRIER_PROCESSOR_LOAD __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_STORE __sync_synchronize()
#define LFDS611_BARRIER_PROCESSOR_FULL __sync_synchronize()
#endif
#define LFDS611_BARRIER_LOAD LFDS611_BARRIER_COMPILER_LOAD; LFDS611_BARRIER_PROCESSOR_LOAD; LFDS611_BARRIER_COMPILER_LOAD
#define LFDS611_BARRIER_STORE LFDS611_BARRIER_COMPILER_STORE; LFDS611_BARRIER_PROCESSOR_STORE; LFDS611_BARRIER_COMPILER_STORE
#define LFDS611_BARRIER_FULL LFDS611_BARRIER_COMPILER_FULL; LFDS611_BARRIER_PROCESSOR_FULL; LFDS611_BARRIER_COMPILER_FULL
/***** enums *****/
enum lfds611_data_structure_validity {
LFDS611_VALIDITY_VALID,
LFDS611_VALIDITY_INVALID_LOOP,
LFDS611_VALIDITY_INVALID_MISSING_ELEMENTS,
LFDS611_VALIDITY_INVALID_ADDITIONAL_ELEMENTS,
LFDS611_VALIDITY_INVALID_TEST_DATA
};
/***** structs *****/
struct lfds611_validation_info {
lfds611_atom_t
min_elements,
max_elements;
};
/***** public prototypes *****/
void *lfds611_abstraction_malloc( size_t size );
void lfds611_abstraction_free( void *memory );
/***** lfds611_freelist *****/
/***** enums *****/
enum lfds611_freelist_query_type
{
LFDS611_FREELIST_QUERY_ELEMENT_COUNT,
LFDS611_FREELIST_QUERY_VALIDATE
};
/***** incomplete types *****/
struct lfds611_freelist_state;
struct lfds611_freelist_element;
/***** lfds611_freelist *****/
/***** public prototypes *****/
int lfds611_freelist_new( struct lfds611_freelist_state **fs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state );
void lfds611_freelist_use( struct lfds611_freelist_state *fs );
void lfds611_freelist_delete( struct lfds611_freelist_state *fs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
/***** enums *****/
enum lfds611_freelist_query_type {
LFDS611_FREELIST_QUERY_ELEMENT_COUNT,
LFDS611_FREELIST_QUERY_VALIDATE
};
lfds611_atom_t lfds611_freelist_new_elements( struct lfds611_freelist_state *fs, lfds611_atom_t number_elements );
/***** incomplete types *****/
struct lfds611_freelist_state;
struct lfds611_freelist_element;
struct lfds611_freelist_element *lfds611_freelist_pop( struct lfds611_freelist_state *fs, struct lfds611_freelist_element **fe );
struct lfds611_freelist_element *lfds611_freelist_guaranteed_pop( struct lfds611_freelist_state *fs, struct lfds611_freelist_element **fe );
void lfds611_freelist_push( struct lfds611_freelist_state *fs, struct lfds611_freelist_element *fe );
/***** public prototypes *****/
int lfds611_freelist_new( struct lfds611_freelist_state **fs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state );
void lfds611_freelist_use( struct lfds611_freelist_state *fs );
void lfds611_freelist_delete( struct lfds611_freelist_state *fs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
void *lfds611_freelist_get_user_data_from_element( struct lfds611_freelist_element *fe, void **user_data );
void lfds611_freelist_set_user_data_in_element( struct lfds611_freelist_element *fe, void *user_data );
lfds611_atom_t lfds611_freelist_new_elements( struct lfds611_freelist_state *fs, lfds611_atom_t number_elements );
void lfds611_freelist_query( struct lfds611_freelist_state *fs, enum lfds611_freelist_query_type query_type, void *query_input, void *query_output );
struct lfds611_freelist_element *lfds611_freelist_pop( struct lfds611_freelist_state *fs, struct lfds611_freelist_element **fe );
struct lfds611_freelist_element *lfds611_freelist_guaranteed_pop( struct lfds611_freelist_state *fs, struct lfds611_freelist_element **fe );
void lfds611_freelist_push( struct lfds611_freelist_state *fs, struct lfds611_freelist_element *fe );
void *lfds611_freelist_get_user_data_from_element( struct lfds611_freelist_element *fe, void **user_data );
void lfds611_freelist_set_user_data_in_element( struct lfds611_freelist_element *fe, void *user_data );
void lfds611_freelist_query( struct lfds611_freelist_state *fs, enum lfds611_freelist_query_type query_type, void *query_input, void *query_output );
/***** lfds611_liblfds *****/
/***** public prototypes *****/
void lfds611_liblfds_abstraction_test_helper_increment_non_atomic( lfds611_atom_t *shared_counter );
void lfds611_liblfds_abstraction_test_helper_increment_atomic( volatile lfds611_atom_t *shared_counter );
void lfds611_liblfds_abstraction_test_helper_cas( volatile lfds611_atom_t *shared_counter, lfds611_atom_t *local_counter );
void lfds611_liblfds_abstraction_test_helper_dcas( volatile lfds611_atom_t *shared_counter, lfds611_atom_t *local_counter );
/***** lfds611_liblfds *****/
/***** public prototypes *****/
void lfds611_liblfds_abstraction_test_helper_increment_non_atomic( lfds611_atom_t *shared_counter );
void lfds611_liblfds_abstraction_test_helper_increment_atomic( volatile lfds611_atom_t *shared_counter );
void lfds611_liblfds_abstraction_test_helper_cas( volatile lfds611_atom_t *shared_counter, lfds611_atom_t *local_counter );
void lfds611_liblfds_abstraction_test_helper_dcas( volatile lfds611_atom_t *shared_counter, lfds611_atom_t *local_counter );
/***** lfds611_queue *****/
/***** enums *****/
enum lfds611_queue_query_type
{
LFDS611_QUEUE_QUERY_ELEMENT_COUNT,
LFDS611_QUEUE_QUERY_VALIDATE
};
/***** incomplete types *****/
struct lfds611_queue_state;
/***** lfds611_queue *****/
/***** public prototypes *****/
int lfds611_queue_new( struct lfds611_queue_state **sq, lfds611_atom_t number_elements );
void lfds611_queue_use( struct lfds611_queue_state *qs );
void lfds611_queue_delete( struct lfds611_queue_state *qs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
/***** enums *****/
enum lfds611_queue_query_type {
LFDS611_QUEUE_QUERY_ELEMENT_COUNT,
LFDS611_QUEUE_QUERY_VALIDATE
};
int lfds611_queue_enqueue( struct lfds611_queue_state *qs, void *user_data );
int lfds611_queue_guaranteed_enqueue( struct lfds611_queue_state *qs, void *user_data );
int lfds611_queue_dequeue( struct lfds611_queue_state *qs, void **user_data );
/***** incomplete types *****/
struct lfds611_queue_state;
void lfds611_queue_query( struct lfds611_queue_state *qs, enum lfds611_queue_query_type query_type, void *query_input, void *query_output );
/***** public prototypes *****/
int lfds611_queue_new( struct lfds611_queue_state **sq, lfds611_atom_t number_elements );
void lfds611_queue_use( struct lfds611_queue_state *qs );
void lfds611_queue_delete( struct lfds611_queue_state *qs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
int lfds611_queue_enqueue( struct lfds611_queue_state *qs, void *user_data );
int lfds611_queue_guaranteed_enqueue( struct lfds611_queue_state *qs, void *user_data );
int lfds611_queue_dequeue( struct lfds611_queue_state *qs, void **user_data );
void lfds611_queue_query( struct lfds611_queue_state *qs, enum lfds611_queue_query_type query_type, void *query_input, void *query_output );
/***** lfds611_ringbuffer *****/
/***** enums *****/
enum lfds611_ringbuffer_query_type
{
LFDS611_RINGBUFFER_QUERY_VALIDATE
};
/***** incomplete types *****/
struct lfds611_ringbuffer_state;
/***** lfds611_ringbuffer *****/
/***** public prototypes *****/
int lfds611_ringbuffer_new( struct lfds611_ringbuffer_state **rs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state );
void lfds611_ringbuffer_use( struct lfds611_ringbuffer_state *rs );
void lfds611_ringbuffer_delete( struct lfds611_ringbuffer_state *rs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
/***** enums *****/
enum lfds611_ringbuffer_query_type {
LFDS611_RINGBUFFER_QUERY_VALIDATE
};
struct lfds611_freelist_element *lfds611_ringbuffer_get_read_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element **fe );
struct lfds611_freelist_element *lfds611_ringbuffer_get_write_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element **fe, int *overwrite_flag );
/***** incomplete types *****/
struct lfds611_ringbuffer_state;
void lfds611_ringbuffer_put_read_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element *fe );
void lfds611_ringbuffer_put_write_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element *fe );
/***** public prototypes *****/
int lfds611_ringbuffer_new( struct lfds611_ringbuffer_state **rs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state );
void lfds611_ringbuffer_use( struct lfds611_ringbuffer_state *rs );
void lfds611_ringbuffer_delete( struct lfds611_ringbuffer_state *rs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
void lfds611_ringbuffer_query( struct lfds611_ringbuffer_state *rs, enum lfds611_ringbuffer_query_type query_type, void *query_input, void *query_output );
struct lfds611_freelist_element *lfds611_ringbuffer_get_read_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element **fe );
struct lfds611_freelist_element *lfds611_ringbuffer_get_write_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element **fe, int *overwrite_flag );
void lfds611_ringbuffer_put_read_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element *fe );
void lfds611_ringbuffer_put_write_element( struct lfds611_ringbuffer_state *rs, struct lfds611_freelist_element *fe );
void lfds611_ringbuffer_query( struct lfds611_ringbuffer_state *rs, enum lfds611_ringbuffer_query_type query_type, void *query_input, void *query_output );
/***** lfds611_slist *****/
/***** incomplete types *****/
struct lfds611_slist_state;
struct lfds611_slist_element;
/***** public prototypes *****/
int lfds611_slist_new( struct lfds611_slist_state **ss, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
void lfds611_slist_use( struct lfds611_slist_state *ss );
void lfds611_slist_delete( struct lfds611_slist_state *ss );
/***** lfds611_slist *****/
struct lfds611_slist_element *lfds611_slist_new_head( struct lfds611_slist_state *ss, void *user_data );
struct lfds611_slist_element *lfds611_slist_new_next( struct lfds611_slist_element *se, void *user_data );
/***** incomplete types *****/
struct lfds611_slist_state;
struct lfds611_slist_element;
int lfds611_slist_logically_delete_element( struct lfds611_slist_state *ss, struct lfds611_slist_element *se );
void lfds611_slist_single_threaded_physically_delete_all_elements( struct lfds611_slist_state *ss );
/***** public prototypes *****/
int lfds611_slist_new( struct lfds611_slist_state **ss, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
void lfds611_slist_use( struct lfds611_slist_state *ss );
void lfds611_slist_delete( struct lfds611_slist_state *ss );
int lfds611_slist_get_user_data_from_element( struct lfds611_slist_element *se, void **user_data );
int lfds611_slist_set_user_data_in_element( struct lfds611_slist_element *se, void *user_data );
struct lfds611_slist_element *lfds611_slist_new_head( struct lfds611_slist_state *ss, void *user_data );
struct lfds611_slist_element *lfds611_slist_new_next( struct lfds611_slist_element *se, void *user_data );
struct lfds611_slist_element *lfds611_slist_get_head( struct lfds611_slist_state *ss, struct lfds611_slist_element **se );
struct lfds611_slist_element *lfds611_slist_get_next( struct lfds611_slist_element *se, struct lfds611_slist_element **next_se );
struct lfds611_slist_element *lfds611_slist_get_head_and_then_next( struct lfds611_slist_state *ss, struct lfds611_slist_element **se );
int lfds611_slist_logically_delete_element( struct lfds611_slist_state *ss, struct lfds611_slist_element *se );
void lfds611_slist_single_threaded_physically_delete_all_elements( struct lfds611_slist_state *ss );
int lfds611_slist_get_user_data_from_element( struct lfds611_slist_element *se, void **user_data );
int lfds611_slist_set_user_data_in_element( struct lfds611_slist_element *se, void *user_data );
struct lfds611_slist_element *lfds611_slist_get_head( struct lfds611_slist_state *ss, struct lfds611_slist_element **se );
struct lfds611_slist_element *lfds611_slist_get_next( struct lfds611_slist_element *se, struct lfds611_slist_element **next_se );
struct lfds611_slist_element *lfds611_slist_get_head_and_then_next( struct lfds611_slist_state *ss, struct lfds611_slist_element **se );
/***** lfds611_stack *****/
/***** enums *****/
enum lfds611_stack_query_type
{
LFDS611_STACK_QUERY_ELEMENT_COUNT,
LFDS611_STACK_QUERY_VALIDATE
};
/***** incomplete types *****/
struct lfds611_stack_state;
/***** lfds611_stack *****/
/***** public prototypes *****/
int lfds611_stack_new( struct lfds611_stack_state **ss, lfds611_atom_t number_elements );
void lfds611_stack_use( struct lfds611_stack_state *ss );
void lfds611_stack_delete( struct lfds611_stack_state *ss, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
/***** enums *****/
enum lfds611_stack_query_type {
LFDS611_STACK_QUERY_ELEMENT_COUNT,
LFDS611_STACK_QUERY_VALIDATE
};
void lfds611_stack_clear( struct lfds611_stack_state *ss, void (*user_data_clear_function)(void *user_data, void *user_state), void *user_state );
/***** incomplete types *****/
struct lfds611_stack_state;
int lfds611_stack_push( struct lfds611_stack_state *ss, void *user_data );
int lfds611_stack_guaranteed_push( struct lfds611_stack_state *ss, void *user_data );
int lfds611_stack_pop( struct lfds611_stack_state *ss, void **user_data );
/***** public prototypes *****/
int lfds611_stack_new( struct lfds611_stack_state **ss, lfds611_atom_t number_elements );
void lfds611_stack_use( struct lfds611_stack_state *ss );
void lfds611_stack_delete( struct lfds611_stack_state *ss, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state );
void lfds611_stack_query( struct lfds611_stack_state *ss, enum lfds611_stack_query_type query_type, void *query_input, void *query_output );
void lfds611_stack_clear( struct lfds611_stack_state *ss, void (*user_data_clear_function)(void *user_data, void *user_state), void *user_state );
int lfds611_stack_push( struct lfds611_stack_state *ss, void *user_data );
int lfds611_stack_guaranteed_push( struct lfds611_stack_state *ss, void *user_data );
int lfds611_stack_pop( struct lfds611_stack_state *ss, void **user_data );
void lfds611_stack_query( struct lfds611_stack_state *ss, enum lfds611_stack_query_type query_type, void *query_input, void *query_output );
#define __LIBLFDS611_H
#define __LIBLFDS611_H
#endif
@@ -7,29 +7,29 @@
/****************************************************************************/
#if (defined _WIN32 && defined _MSC_VER)
/* TRD : 64 bit and 32 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
/* TRD : 64 bit and 32 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
*/
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_cas( volatile lfds611_atom_t *destination, lfds611_atom_t exchange, lfds611_atom_t compare )
{
lfds611_atom_t
rv;
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_cas( volatile lfds611_atom_t *destination, lfds611_atom_t exchange, lfds611_atom_t compare )
{
lfds611_atom_t
rv;
assert( destination != NULL );
// TRD : exchange can be any value in its range
// TRD : compare can be any value in its range
assert( destination != NULL );
// TRD : exchange can be any value in its range
// TRD : compare can be any value in its range
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
rv = (lfds611_atom_t) _InterlockedCompareExchangePointer( (void * volatile *) destination, (void *) exchange, (void *) compare );
rv = (lfds611_atom_t) _InterlockedCompareExchangePointer( (void * volatile *) destination, (void *) exchange, (void *) compare );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
return( rv );
}
return( rv );
}
#endif
@@ -40,32 +40,32 @@
/****************************************************************************/
#if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1 && __GNUC_PATCHLEVEL__ >= 0)
/* TRD : any OS on any CPU with GCC 4.1.0 or better
/* TRD : any OS on any CPU with GCC 4.1.0 or better
GCC 4.1.0 introduced the __sync_*() atomic intrinsics
GCC 4.1.0 introduced the __sync_*() atomic intrinsics
__GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ indicates GCC and which version
*/
__GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ indicates GCC and which version
*/
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_cas( volatile lfds611_atom_t *destination, lfds611_atom_t exchange, lfds611_atom_t compare )
{
lfds611_atom_t
rv;
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_cas( volatile lfds611_atom_t *destination, lfds611_atom_t exchange, lfds611_atom_t compare )
{
lfds611_atom_t
rv;
assert( destination != NULL );
// TRD : exchange can be any value in its range
// TRD : compare can be any value in its range
assert( destination != NULL );
// TRD : exchange can be any value in its range
// TRD : compare can be any value in its range
// TRD : note the different argument order for the GCC instrinsic to the MSVC instrinsic
// TRD : note the different argument order for the GCC instrinsic to the MSVC instrinsic
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
rv = (lfds611_atom_t) __sync_val_compare_and_swap( destination, compare, exchange );
rv = (lfds611_atom_t) __sync_val_compare_and_swap( destination, compare, exchange );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
return( rv );
}
return( rv );
}
#endif
@@ -7,29 +7,29 @@
/****************************************************************************/
#if (defined _WIN64 && defined _MSC_VER)
/* TRD : 64 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
/* TRD : 64 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
_WIN64 indicates 64 bit Windows
_MSC_VER indicates Microsoft C compiler
*/
_WIN64 indicates 64 bit Windows
_MSC_VER indicates Microsoft C compiler
*/
static LFDS611_INLINE unsigned char lfds611_abstraction_dcas( volatile lfds611_atom_t *destination, lfds611_atom_t *exchange, lfds611_atom_t *compare )
{
unsigned char
cas_result;
static LFDS611_INLINE unsigned char lfds611_abstraction_dcas( volatile lfds611_atom_t *destination, lfds611_atom_t *exchange, lfds611_atom_t *compare )
{
unsigned char
cas_result;
assert( destination != NULL );
assert( exchange != NULL );
assert( compare != NULL );
assert( destination != NULL );
assert( exchange != NULL );
assert( compare != NULL );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
cas_result = _InterlockedCompareExchange128( (volatile __int64 *) destination, (__int64) *(exchange+1), (__int64) *exchange, (__int64 *) compare );
cas_result = _InterlockedCompareExchange128( (volatile __int64 *) destination, (__int64) *(exchange+1), (__int64) *exchange, (__int64 *) compare );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
return( cas_result ) ;
}
return( cas_result ) ;
}
#endif
@@ -40,31 +40,31 @@
/****************************************************************************/
#if (!defined _WIN64 && defined _WIN32 && defined _MSC_VER)
/* TRD : 32 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
/* TRD : 32 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
(!defined _WIN64 && defined _WIN32) indicates 32 bit Windows
_MSC_VER indicates Microsoft C compiler
*/
(!defined _WIN64 && defined _WIN32) indicates 32 bit Windows
_MSC_VER indicates Microsoft C compiler
*/
static LFDS611_INLINE unsigned char lfds611_abstraction_dcas( volatile lfds611_atom_t *destination, lfds611_atom_t *exchange, lfds611_atom_t *compare )
{
__int64
original_compare;
static LFDS611_INLINE unsigned char lfds611_abstraction_dcas( volatile lfds611_atom_t *destination, lfds611_atom_t *exchange, lfds611_atom_t *compare )
{
__int64
original_compare;
assert( destination != NULL );
assert( exchange != NULL );
assert( compare != NULL );
assert( destination != NULL );
assert( exchange != NULL );
assert( compare != NULL );
*(__int64 *) &original_compare = *(__int64 *) compare;
*(__int64 *) &original_compare = *(__int64 *) compare;
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
*(__int64 *) compare = _InterlockedCompareExchange64( (volatile __int64 *) destination, *(__int64 *) exchange, *(__int64 *) compare );
*(__int64 *) compare = _InterlockedCompareExchange64( (volatile __int64 *) destination, *(__int64 *) exchange, *(__int64 *) compare );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
return( (unsigned char) (*(__int64 *) compare == *(__int64 *) &original_compare) );
}
return( (unsigned char) (*(__int64 *) compare == *(__int64 *) &original_compare) );
}
#endif
@@ -75,40 +75,40 @@
/****************************************************************************/
#if (defined __x86_64__ && defined __GNUC__)
/* TRD : any OS on x64 with GCC
/* TRD : any OS on x64 with GCC
__x86_64__ indicates x64
__GNUC__ indicates GCC
*/
__x86_64__ indicates x64
__GNUC__ indicates GCC
*/
static LFDS611_INLINE unsigned char lfds611_abstraction_dcas( volatile lfds611_atom_t *destination, lfds611_atom_t *exchange, lfds611_atom_t *compare )
{
unsigned char
cas_result;
static LFDS611_INLINE unsigned char lfds611_abstraction_dcas( volatile lfds611_atom_t *destination, lfds611_atom_t *exchange, lfds611_atom_t *compare )
{
unsigned char
cas_result;
assert( destination != NULL );
assert( exchange != NULL );
assert( compare != NULL );
assert( destination != NULL );
assert( exchange != NULL );
assert( compare != NULL );
// TRD : __asm__ with "memory" in the clobber list is for GCC a full compiler barrier
__asm__ __volatile__
(
"lock;" // make cmpxchg16b atomic
"cmpxchg16b %0;" // cmpxchg16b sets ZF on success
"setz %3;" // if ZF set, set cas_result to 1
// TRD : __asm__ with "memory" in the clobber list is for GCC a full compiler barrier
__asm__ __volatile__
(
"lock;" // make cmpxchg16b atomic
"cmpxchg16b %0;" // cmpxchg16b sets ZF on success
"setz %3;" // if ZF set, set cas_result to 1
// output
: "+m" (*(volatile lfds611_atom_t (*)[2]) destination), "+a" (*compare), "+d" (*(compare+1)), "=q" (cas_result)
// output
: "+m" (*(volatile lfds611_atom_t (*)[2]) destination), "+a" (*compare), "+d" (*(compare+1)), "=q" (cas_result)
// input
: "b" (*exchange), "c" (*(exchange+1))
// input
: "b" (*exchange), "c" (*(exchange+1))
// clobbered
: "cc", "memory"
);
// clobbered
: "cc", "memory"
);
return( cas_result );
}
return( cas_result );
}
#endif
@@ -119,38 +119,38 @@
/****************************************************************************/
#if ((defined __i686__ || defined __arm__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 1 && __GNUC_PATCHLEVEL__ >= 0)
/* TRD : any OS on x86 or ARM with GCC 4.1.0 or better
/* TRD : any OS on x86 or ARM with GCC 4.1.0 or better
GCC 4.1.0 introduced the __sync_*() atomic intrinsics
GCC 4.1.0 introduced the __sync_*() atomic intrinsics
__GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ indicates GCC and which version
*/
__GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ indicates GCC and which version
*/
static LFDS611_INLINE unsigned char lfds611_abstraction_dcas( volatile lfds611_atom_t *destination, lfds611_atom_t *exchange, lfds611_atom_t *compare )
{
unsigned char
cas_result = 0;
static LFDS611_INLINE unsigned char lfds611_abstraction_dcas( volatile lfds611_atom_t *destination, lfds611_atom_t *exchange, lfds611_atom_t *compare )
{
unsigned char
cas_result = 0;
unsigned long long int
original_destination;
unsigned long long int
original_destination;
assert( destination != NULL );
assert( exchange != NULL );
assert( compare != NULL );
assert( destination != NULL );
assert( exchange != NULL );
assert( compare != NULL );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
original_destination = __sync_val_compare_and_swap( (volatile unsigned long long int *) destination, *(unsigned long long int *) compare, *(unsigned long long int *) exchange );
original_destination = __sync_val_compare_and_swap( (volatile unsigned long long int *) destination, *(unsigned long long int *) compare, *(unsigned long long int *) exchange );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
if( original_destination == *(unsigned long long int *) compare )
cas_result = 1;
if( original_destination == *(unsigned long long int *) compare )
cas_result = 1;
*(unsigned long long int *) compare = original_destination;
*(unsigned long long int *) compare = original_destination;
return( cas_result );
}
return( cas_result );
}
#endif
@@ -7,17 +7,17 @@
/****************************************************************************/
#if (!defined WIN_KERNEL_BUILD)
/* TRD : any OS except Windows kernel on any CPU with any compiler
/* TRD : any OS except Windows kernel on any CPU with any compiler
!WIN_KERNEL_BUILD indicates not Windows kernel
*/
!WIN_KERNEL_BUILD indicates not Windows kernel
*/
void lfds611_abstraction_free( void *memory )
{
free( memory );
void lfds611_abstraction_free( void *memory )
{
free( memory );
return;
}
return;
}
#endif
@@ -28,17 +28,17 @@
/****************************************************************************/
#if (defined WIN_KERNEL_BUILD)
/* TRD : any Windows (kernel) on any CPU with the Microsoft C compiler
/* TRD : any Windows (kernel) on any CPU with the Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
WIN_KERNEL_BUILD indicates Windows kernel
*/
void lfds611_abstraction_free( void *memory )
{
ExFreePoolWithTag( memory, 'sdfl' );
void lfds611_abstraction_free( void *memory )
{
ExFreePoolWithTag( memory, 'sdfl' );
return;
}
return;
}
#endif
@@ -7,27 +7,27 @@
/****************************************************************************/
#if (defined _WIN64 && defined _MSC_VER)
/* TRD : 64 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
/* TRD : 64 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
_WIN64 indicates 64 bit Windows
_MSC_VER indicates Microsoft C compiler
*/
_WIN64 indicates 64 bit Windows
_MSC_VER indicates Microsoft C compiler
*/
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_increment( volatile lfds611_atom_t *value )
{
lfds611_atom_t
rv;
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_increment( volatile lfds611_atom_t *value )
{
lfds611_atom_t
rv;
assert( value != NULL );
assert( value != NULL );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
rv = (lfds611_atom_t) _InterlockedIncrement64( (__int64 *) value );
rv = (lfds611_atom_t) _InterlockedIncrement64( (__int64 *) value );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
return( rv );
}
return( rv );
}
#endif
@@ -38,27 +38,27 @@
/****************************************************************************/
#if (!defined _WIN64 && defined _WIN32 && defined _MSC_VER)
/* TRD : 32 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
/* TRD : 32 bit Windows (user-mode or kernel) on any CPU with the Microsoft C compiler
(!defined _WIN64 && defined _WIN32) indicates 32 bit Windows
_MSC_VER indicates Microsoft C compiler
*/
(!defined _WIN64 && defined _WIN32) indicates 32 bit Windows
_MSC_VER indicates Microsoft C compiler
*/
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_increment( volatile lfds611_atom_t *value )
{
lfds611_atom_t
rv;
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_increment( volatile lfds611_atom_t *value )
{
lfds611_atom_t
rv;
assert( value != NULL );
assert( value != NULL );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
rv = (lfds611_atom_t) _InterlockedIncrement( (long int *) value );
rv = (lfds611_atom_t) _InterlockedIncrement( (long int *) value );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
return( rv );
}
return( rv );
}
#endif
@@ -69,30 +69,30 @@
/****************************************************************************/
#if (__GNUC__ >= 4 && __GNUC_MINOR__ >= 1 && __GNUC_PATCHLEVEL__ >= 0)
/* TRD : any OS on any CPU with GCC 4.1.0 or better
/* TRD : any OS on any CPU with GCC 4.1.0 or better
GCC 4.1.0 introduced the __sync_*() atomic intrinsics
GCC 4.1.0 introduced the __sync_*() atomic intrinsics
__GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ indicates GCC and which version
*/
__GNUC__ / __GNUC_MINOR__ / __GNUC_PATCHLEVEL__ indicates GCC and which version
*/
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_increment( volatile lfds611_atom_t *value )
{
lfds611_atom_t
rv;
static LFDS611_INLINE lfds611_atom_t lfds611_abstraction_increment( volatile lfds611_atom_t *value )
{
lfds611_atom_t
rv;
assert( value != NULL );
assert( value != NULL );
// TRD : no need for casting here, GCC has a __sync_add_and_fetch() for all native types
// TRD : no need for casting here, GCC has a __sync_add_and_fetch() for all native types
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
rv = (lfds611_atom_t) __sync_add_and_fetch( value, 1 );
rv = (lfds611_atom_t) __sync_add_and_fetch( value, 1 );
LFDS611_BARRIER_COMPILER_FULL;
LFDS611_BARRIER_COMPILER_FULL;
return( rv );
}
return( rv );
}
#endif
@@ -7,15 +7,15 @@
/****************************************************************************/
#if (!defined WIN_KERNEL_BUILD)
/* TRD : any OS except Windows kernel on any CPU with any compiler
/* TRD : any OS except Windows kernel on any CPU with any compiler
!WIN_KERNEL_BUILD indicates not Windows kernel
*/
!WIN_KERNEL_BUILD indicates not Windows kernel
*/
void *lfds611_abstraction_malloc( size_t size )
{
return( malloc(size) );
}
void *lfds611_abstraction_malloc( size_t size )
{
return( malloc(size) );
}
#endif
@@ -26,15 +26,15 @@
/****************************************************************************/
#if (defined WIN_KERNEL_BUILD)
/* TRD : any Windows (kernel) on any CPU with the Microsoft C compiler
/* TRD : any Windows (kernel) on any CPU with the Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
WIN_KERNEL_BUILD indicates Windows kernel
*/
void *lfds611_abstraction_malloc( size_t size )
{
return( ExAllocatePoolWithTag(NonPagedPool, size, 'sdfl') );
}
void *lfds611_abstraction_malloc( size_t size )
{
return( ExAllocatePoolWithTag(NonPagedPool, size, 'sdfl') );
}
#endif
@@ -8,10 +8,10 @@
void lfds611_freelist_delete( struct lfds611_freelist_state *fs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state )
{
struct lfds611_freelist_element
*fe;
*fe;
void
*user_data;
*user_data;
assert( fs != NULL );
// TRD : user_data_delete_function can be NULL
@@ -19,10 +19,8 @@ void lfds611_freelist_delete( struct lfds611_freelist_state *fs, void (*user_dat
// TRD : leading load barrier not required as it will be performed by the pop
while( lfds611_freelist_pop(fs, &fe) )
{
if( user_data_delete_function != NULL )
{
while( lfds611_freelist_pop(fs, &fe) ) {
if( user_data_delete_function != NULL ) {
lfds611_freelist_get_user_data_from_element( fe, &user_data );
user_data_delete_function( user_data, user_state );
}
@@ -9,29 +9,27 @@
/***** structures *****/
#pragma pack( push, LFDS611_ALIGN_DOUBLE_POINTER )
struct lfds611_freelist_state
{
struct lfds611_freelist_state {
struct lfds611_freelist_element
*volatile top[LFDS611_FREELIST_PAC_SIZE];
*volatile top[LFDS611_FREELIST_PAC_SIZE];
int
(*user_data_init_function)( void **user_data, void *user_state );
(*user_data_init_function)( void **user_data, void *user_state );
void
*user_state;
*user_state;
lfds611_atom_t
aba_counter,
element_count;
aba_counter,
element_count;
};
struct lfds611_freelist_element
{
struct lfds611_freelist_element {
struct lfds611_freelist_element
*next[LFDS611_FREELIST_PAC_SIZE];
*next[LFDS611_FREELIST_PAC_SIZE];
void
*user_data;
*user_data;
};
#pragma pack( pop )
@@ -8,10 +8,10 @@
int lfds611_freelist_new( struct lfds611_freelist_state **fs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state )
{
int
rv = 0;
rv = 0;
lfds611_atom_t
element_count;
element_count;
assert( fs != NULL );
// TRD : number_elements can be any value in its range
@@ -19,8 +19,7 @@ int lfds611_freelist_new( struct lfds611_freelist_state **fs, lfds611_atom_t num
*fs = (struct lfds611_freelist_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_freelist_state), LFDS611_ALIGN_DOUBLE_POINTER );
if( (*fs) != NULL )
{
if( (*fs) != NULL ) {
(*fs)->top[LFDS611_FREELIST_POINTER] = NULL;
(*fs)->top[LFDS611_FREELIST_COUNTER] = 0;
(*fs)->user_data_init_function = user_data_init_function;
@@ -33,8 +32,7 @@ int lfds611_freelist_new( struct lfds611_freelist_state **fs, lfds611_atom_t num
if( element_count == number_elements )
rv = 1;
if( element_count != number_elements )
{
if( element_count != number_elements ) {
lfds611_liblfds_aligned_free( (*fs) );
*fs = NULL;
}
@@ -71,19 +69,18 @@ void lfds611_freelist_use( struct lfds611_freelist_state *fs )
lfds611_atom_t lfds611_freelist_new_elements( struct lfds611_freelist_state *fs, lfds611_atom_t number_elements )
{
struct lfds611_freelist_element
*fe;
*fe;
lfds611_atom_t
loop,
count = 0;
loop,
count = 0;
assert( fs != NULL );
// TRD : number_elements can be any value in its range
// TRD : user_data_init_function can be NULL
for( loop = 0 ; loop < number_elements ; loop++ )
if( lfds611_freelist_internal_new_element(fs, &fe) )
{
if( lfds611_freelist_internal_new_element(fs, &fe) ) {
lfds611_freelist_push( fs, fe );
count++;
}
@@ -99,7 +96,7 @@ lfds611_atom_t lfds611_freelist_new_elements( struct lfds611_freelist_state *fs,
lfds611_atom_t lfds611_freelist_internal_new_element( struct lfds611_freelist_state *fs, struct lfds611_freelist_element **fe )
{
lfds611_atom_t
rv = 0;
rv = 0;
assert( fs != NULL );
assert( fe != NULL );
@@ -115,20 +112,16 @@ lfds611_atom_t lfds611_freelist_internal_new_element( struct lfds611_freelist_st
*fe = (struct lfds611_freelist_element *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_freelist_element), LFDS611_ALIGN_DOUBLE_POINTER );
if( *fe != NULL )
{
if( fs->user_data_init_function == NULL )
{
if( *fe != NULL ) {
if( fs->user_data_init_function == NULL ) {
(*fe)->user_data = NULL;
rv = 1;
}
if( fs->user_data_init_function != NULL )
{
if( fs->user_data_init_function != NULL ) {
rv = fs->user_data_init_function( &(*fe)->user_data, fs->user_state );
if( rv == 0 )
{
if( rv == 0 ) {
lfds611_liblfds_aligned_free( *fe );
*fe = NULL;
}
@@ -8,7 +8,7 @@
struct lfds611_freelist_element *lfds611_freelist_pop( struct lfds611_freelist_state *fs, struct lfds611_freelist_element **fe )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_freelist_element
*fe_local[LFDS611_FREELIST_PAC_SIZE];
*fe_local[LFDS611_FREELIST_PAC_SIZE];
assert( fs != NULL );
assert( fe != NULL );
@@ -22,15 +22,12 @@ struct lfds611_freelist_element *lfds611_freelist_pop( struct lfds611_freelist_s
(this happens of course after the CAS itself has occurred inside lfds611_abstraction_dcas)
*/
do
{
if( fe_local[LFDS611_FREELIST_POINTER] == NULL )
{
do {
if( fe_local[LFDS611_FREELIST_POINTER] == NULL ) {
*fe = NULL;
return( *fe );
}
}
while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) fs->top, (lfds611_atom_t *) fe_local[LFDS611_FREELIST_POINTER]->next, (lfds611_atom_t *) fe_local) );
} while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) fs->top, (lfds611_atom_t *) fe_local[LFDS611_FREELIST_POINTER]->next, (lfds611_atom_t *) fe_local) );
*fe = (struct lfds611_freelist_element *) fe_local[LFDS611_FREELIST_POINTER];
@@ -60,8 +57,8 @@ struct lfds611_freelist_element *lfds611_freelist_guaranteed_pop( struct lfds611
void lfds611_freelist_push( struct lfds611_freelist_state *fs, struct lfds611_freelist_element *fe )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_freelist_element
*fe_local[LFDS611_FREELIST_PAC_SIZE],
*original_fe_next[LFDS611_FREELIST_PAC_SIZE];
*fe_local[LFDS611_FREELIST_PAC_SIZE],
*original_fe_next[LFDS611_FREELIST_PAC_SIZE];
assert( fs != NULL );
assert( fe != NULL );
@@ -80,12 +77,10 @@ void lfds611_freelist_push( struct lfds611_freelist_state *fs, struct lfds611_fr
up-to-date version of the head of the lfds611_freelist
*/
do
{
do {
fe_local[LFDS611_FREELIST_POINTER]->next[LFDS611_FREELIST_POINTER] = original_fe_next[LFDS611_FREELIST_POINTER];
fe_local[LFDS611_FREELIST_POINTER]->next[LFDS611_FREELIST_COUNTER] = original_fe_next[LFDS611_FREELIST_COUNTER];
}
while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) fs->top, (lfds611_atom_t *) fe_local, (lfds611_atom_t *) original_fe_next) );
} while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) fs->top, (lfds611_atom_t *) fe_local, (lfds611_atom_t *) original_fe_next) );
return;
}
@@ -14,18 +14,17 @@ void lfds611_freelist_query( struct lfds611_freelist_state *fs, enum lfds611_fre
LFDS611_BARRIER_LOAD;
switch( query_type )
{
case LFDS611_FREELIST_QUERY_ELEMENT_COUNT:
assert( query_input == NULL );
switch( query_type ) {
case LFDS611_FREELIST_QUERY_ELEMENT_COUNT:
assert( query_input == NULL );
*(lfds611_atom_t *) query_output = fs->element_count;
*(lfds611_atom_t *) query_output = fs->element_count;
break;
case LFDS611_FREELIST_QUERY_VALIDATE:
// TRD : query_input can be NULL
case LFDS611_FREELIST_QUERY_VALIDATE:
// TRD : query_input can be NULL
lfds611_freelist_internal_validate( fs, (struct lfds611_validation_info *) query_input, (enum lfds611_data_structure_validity *) query_output );
lfds611_freelist_internal_validate( fs, (struct lfds611_validation_info *) query_input, (enum lfds611_data_structure_validity *) query_output );
break;
}
@@ -40,12 +39,12 @@ void lfds611_freelist_query( struct lfds611_freelist_state *fs, enum lfds611_fre
void lfds611_freelist_internal_validate( struct lfds611_freelist_state *fs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_freelist_validity )
{
struct lfds611_freelist_element
*fe,
*fe_slow,
*fe_fast;
*fe,
*fe_slow,
*fe_fast;
lfds611_atom_t
element_count = 0;
element_count = 0;
assert( fs != NULL );
// TRD : vi can be NULL
@@ -73,8 +72,7 @@ void lfds611_freelist_internal_validate( struct lfds611_freelist_state *fs, stru
*/
if( fe_slow != NULL )
do
{
do {
fe_slow = fe_slow->next[LFDS611_FREELIST_POINTER];
if( fe_fast != NULL )
@@ -82,8 +80,7 @@ void lfds611_freelist_internal_validate( struct lfds611_freelist_state *fs, stru
if( fe_fast != NULL )
fe_fast = fe_fast->next[LFDS611_FREELIST_POINTER];
}
while( fe_slow != NULL and fe_fast != fe_slow );
} while( fe_slow != NULL and fe_fast != fe_slow );
if( fe_fast != NULL and fe_slow != NULL and fe_fast == fe_slow )
*lfds611_freelist_validity = LFDS611_VALIDITY_INVALID_LOOP;
@@ -93,12 +90,10 @@ void lfds611_freelist_internal_validate( struct lfds611_freelist_state *fs, stru
we know we don't have a loop from our earlier check
*/
if( *lfds611_freelist_validity == LFDS611_VALIDITY_VALID and vi != NULL )
{
if( *lfds611_freelist_validity == LFDS611_VALIDITY_VALID and vi != NULL ) {
fe = (struct lfds611_freelist_element *) fs->top[LFDS611_FREELIST_POINTER];
while( fe != NULL )
{
while( fe != NULL ) {
element_count++;
fe = (struct lfds611_freelist_element *) fe->next[LFDS611_FREELIST_POINTER];
}
@@ -12,7 +12,7 @@ void lfds611_liblfds_abstraction_test_helper_increment_non_atomic( lfds611_atom_
*/
volatile lfds611_atom_t
count = 0;
count = 0;
assert( shared_counter != NULL );
@@ -30,7 +30,7 @@ void lfds611_liblfds_abstraction_test_helper_increment_non_atomic( lfds611_atom_
void lfds611_liblfds_abstraction_test_helper_increment_atomic( volatile lfds611_atom_t *shared_counter )
{
lfds611_atom_t
count = 0;
count = 0;
assert( shared_counter != NULL );
@@ -48,26 +48,23 @@ void lfds611_liblfds_abstraction_test_helper_increment_atomic( volatile lfds611_
void lfds611_liblfds_abstraction_test_helper_cas( volatile lfds611_atom_t *shared_counter, lfds611_atom_t *local_counter )
{
lfds611_atom_t
loop = 0,
original_destination;
loop = 0,
original_destination;
LFDS611_ALIGN(LFDS611_ALIGN_SINGLE_POINTER) lfds611_atom_t
exchange,
compare;
exchange,
compare;
assert( shared_counter != NULL );
assert( local_counter != NULL );
while( loop++ < 1000000 )
{
do
{
while( loop++ < 1000000 ) {
do {
compare = *shared_counter;
exchange = compare + 1;
original_destination = lfds611_abstraction_cas( shared_counter, exchange, compare );
}
while( original_destination != compare );
} while( original_destination != compare );
(*local_counter)++;
}
@@ -83,26 +80,23 @@ void lfds611_liblfds_abstraction_test_helper_cas( volatile lfds611_atom_t *share
void lfds611_liblfds_abstraction_test_helper_dcas( volatile lfds611_atom_t *shared_counter, lfds611_atom_t *local_counter )
{
lfds611_atom_t
loop = 0;
loop = 0;
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) lfds611_atom_t
exchange[2],
compare[2];
exchange[2],
compare[2];
assert( shared_counter != NULL );
assert( local_counter != NULL );
while( loop++ < 1000000 )
{
while( loop++ < 1000000 ) {
compare[0] = *shared_counter;
compare[1] = *(shared_counter+1);
do
{
do {
exchange[0] = compare[0] + 1;
exchange[1] = compare[1];
}
while( 0 == lfds611_abstraction_dcas(shared_counter, exchange, compare) );
} while( 0 == lfds611_abstraction_dcas(shared_counter, exchange, compare) );
(*local_counter)++;
}
@@ -8,19 +8,18 @@
void *lfds611_liblfds_aligned_malloc( size_t size, size_t align_in_bytes )
{
void
*original_memory,
*memory;
*original_memory,
*memory;
size_t
offset;
offset;
// TRD : size can be any value in its range
// TRD : align_in_bytes can be any value in its range
original_memory = memory = lfds611_abstraction_malloc( size + sizeof(void *) + align_in_bytes );
if( memory != NULL )
{
if( memory != NULL ) {
memory = (void **) memory + 1;
offset = align_in_bytes - (size_t) memory % align_in_bytes;
memory = (unsigned char *) memory + offset;
@@ -8,7 +8,7 @@
void lfds611_queue_delete( struct lfds611_queue_state *qs, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state )
{
void
*user_data;
*user_data;
assert( qs != NULL );
// TRD : user_data_delete_function can be NULL
@@ -16,30 +16,28 @@
/***** structures *****/
#pragma pack( push, LFDS611_ALIGN_DOUBLE_POINTER )
struct lfds611_queue_state
{
struct lfds611_queue_state {
struct lfds611_queue_element
*volatile enqueue[LFDS611_QUEUE_PAC_SIZE],
*volatile dequeue[LFDS611_QUEUE_PAC_SIZE];
*volatile enqueue[LFDS611_QUEUE_PAC_SIZE],
*volatile dequeue[LFDS611_QUEUE_PAC_SIZE];
lfds611_atom_t
aba_counter;
aba_counter;
struct lfds611_freelist_state
*fs;
*fs;
};
struct lfds611_queue_element
{
struct lfds611_queue_element {
// TRD : next in a lfds611_queue requires volatile as it is target of CAS
struct lfds611_queue_element
*volatile next[LFDS611_QUEUE_PAC_SIZE];
*volatile next[LFDS611_QUEUE_PAC_SIZE];
struct lfds611_freelist_element
*fe;
*fe;
void
*user_data;
*user_data;
};
#pragma pack( pop )
@@ -56,5 +54,6 @@ void lfds611_queue_internal_init_element( struct lfds611_queue_state *qs, struct
void lfds611_queue_internal_queue( struct lfds611_queue_state *qs, struct lfds611_queue_element *qe[LFDS611_QUEUE_PAC_SIZE] );
void lfds611_queue_internal_validate( struct lfds611_queue_state *qs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_queue_validity, enum lfds611_data_structure_validity *lfds611_freelist_validity );
void lfds611_queue_internal_validate( struct lfds611_queue_state *qs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_queue_validity,
enum lfds611_data_structure_validity *lfds611_freelist_validity );
@@ -8,23 +8,21 @@
int lfds611_queue_new( struct lfds611_queue_state **qs, lfds611_atom_t number_elements )
{
int
rv = 0;
rv = 0;
struct lfds611_queue_element
*qe[LFDS611_QUEUE_PAC_SIZE];
*qe[LFDS611_QUEUE_PAC_SIZE];
assert( qs != NULL );
// TRD : number_elements can be any value in its range
*qs = (struct lfds611_queue_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_queue_state), LFDS611_ALIGN_DOUBLE_POINTER );
if( *qs != NULL )
{
if( *qs != NULL ) {
// TRD : the size of the lfds611_freelist is the size of the lfds611_queue (+1 for the leading dummy element, which is hidden from the caller)
lfds611_freelist_new( &(*qs)->fs, number_elements+1, lfds611_queue_internal_freelist_init_function, NULL );
if( (*qs)->fs != NULL )
{
if( (*qs)->fs != NULL ) {
lfds611_queue_internal_new_element_from_freelist( *qs, qe, NULL );
(*qs)->enqueue[LFDS611_QUEUE_POINTER] = (*qs)->dequeue[LFDS611_QUEUE_POINTER] = qe[LFDS611_QUEUE_POINTER];
(*qs)->enqueue[LFDS611_QUEUE_COUNTER] = (*qs)->dequeue[LFDS611_QUEUE_COUNTER] = 0;
@@ -32,8 +30,7 @@ int lfds611_queue_new( struct lfds611_queue_state **qs, lfds611_atom_t number_el
rv = 1;
}
if( (*qs)->fs == NULL )
{
if( (*qs)->fs == NULL ) {
lfds611_liblfds_aligned_free( *qs );
*qs = NULL;
}
@@ -72,7 +69,7 @@ void lfds611_queue_use( struct lfds611_queue_state *qs )
int lfds611_queue_internal_freelist_init_function( void **user_data, void *user_state )
{
int
rv = 0;
rv = 0;
assert( user_data != NULL );
assert( user_state == NULL );
@@ -95,7 +92,7 @@ int lfds611_queue_internal_freelist_init_function( void **user_data, void *user_
void lfds611_queue_internal_new_element_from_freelist( struct lfds611_queue_state *qs, struct lfds611_queue_element *qe[LFDS611_QUEUE_PAC_SIZE], void *user_data )
{
struct lfds611_freelist_element
*fe;
*fe;
assert( qs != NULL );
assert( qe != NULL );
@@ -119,7 +116,7 @@ void lfds611_queue_internal_new_element_from_freelist( struct lfds611_queue_stat
void lfds611_queue_internal_guaranteed_new_element_from_freelist( struct lfds611_queue_state *qs, struct lfds611_queue_element *qe[LFDS611_QUEUE_PAC_SIZE], void *user_data )
{
struct lfds611_freelist_element
*fe;
*fe;
assert( qs != NULL );
assert( qe != NULL );
@@ -14,18 +14,17 @@ void lfds611_queue_query( struct lfds611_queue_state *qs, enum lfds611_queue_que
// TRD : query_input can be NULL
assert( query_output != NULL );
switch( query_type )
{
case LFDS611_QUEUE_QUERY_ELEMENT_COUNT:
assert( query_input == NULL );
switch( query_type ) {
case LFDS611_QUEUE_QUERY_ELEMENT_COUNT:
assert( query_input == NULL );
lfds611_freelist_query( qs->fs, LFDS611_FREELIST_QUERY_ELEMENT_COUNT, NULL, query_output );
lfds611_freelist_query( qs->fs, LFDS611_FREELIST_QUERY_ELEMENT_COUNT, NULL, query_output );
break;
case LFDS611_QUEUE_QUERY_VALIDATE:
// TRD : query_input can be NULL
case LFDS611_QUEUE_QUERY_VALIDATE:
// TRD : query_input can be NULL
lfds611_queue_internal_validate( qs, (struct lfds611_validation_info *) query_input, (enum lfds611_data_structure_validity *) query_output, ((enum lfds611_data_structure_validity *) query_output)+1 );
lfds611_queue_internal_validate( qs, (struct lfds611_validation_info *) query_input, (enum lfds611_data_structure_validity *) query_output, ((enum lfds611_data_structure_validity *) query_output)+1 );
break;
}
@@ -39,19 +38,20 @@ void lfds611_queue_query( struct lfds611_queue_state *qs, enum lfds611_queue_que
/****************************************************************************/
void lfds611_queue_internal_validate( struct lfds611_queue_state *qs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_queue_validity, enum lfds611_data_structure_validity *lfds611_freelist_validity )
void lfds611_queue_internal_validate( struct lfds611_queue_state *qs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_queue_validity,
enum lfds611_data_structure_validity *lfds611_freelist_validity )
{
struct lfds611_queue_element
*qe,
*qe_slow,
*qe_fast;
*qe,
*qe_slow,
*qe_fast;
lfds611_atom_t
element_count = 0,
total_elements;
element_count = 0,
total_elements;
struct lfds611_validation_info
lfds611_freelist_vi;
lfds611_freelist_vi;
assert( qs != NULL );
// TRD : vi can be NULL
@@ -82,8 +82,7 @@ void lfds611_queue_internal_validate( struct lfds611_queue_state *qs, struct lfd
*/
if( qe_slow != NULL )
do
{
do {
qe_slow = qe_slow->next[LFDS611_QUEUE_POINTER];
if( qe_fast != NULL )
@@ -91,8 +90,7 @@ void lfds611_queue_internal_validate( struct lfds611_queue_state *qs, struct lfd
if( qe_fast != NULL )
qe_fast = qe_fast->next[LFDS611_QUEUE_POINTER];
}
while( qe_slow != NULL and qe_fast != qe_slow );
} while( qe_slow != NULL and qe_fast != qe_slow );
if( qe_fast != NULL and qe_slow != NULL and qe_fast == qe_slow )
*lfds611_queue_validity = LFDS611_VALIDITY_INVALID_LOOP;
@@ -102,12 +100,10 @@ void lfds611_queue_internal_validate( struct lfds611_queue_state *qs, struct lfd
we know we don't have a loop from our earlier check
*/
if( *lfds611_queue_validity == LFDS611_VALIDITY_VALID and vi != NULL )
{
if( *lfds611_queue_validity == LFDS611_VALIDITY_VALID and vi != NULL ) {
qe = (struct lfds611_queue_element *) qs->dequeue[LFDS611_QUEUE_POINTER];
while( qe != NULL )
{
while( qe != NULL ) {
element_count++;
qe = (struct lfds611_queue_element *) qe->next[LFDS611_QUEUE_POINTER];
}
@@ -134,8 +130,7 @@ void lfds611_queue_internal_validate( struct lfds611_queue_state *qs, struct lfd
lfds611_freelist
*/
if( vi != NULL )
{
if( vi != NULL ) {
lfds611_freelist_query( qs->fs, LFDS611_FREELIST_QUERY_ELEMENT_COUNT, NULL, (void *) &total_elements );
/* TRD : remember there is a dummy element in the lfds611_queue */
@@ -8,7 +8,7 @@
int lfds611_queue_enqueue( struct lfds611_queue_state *qs, void *user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_queue_element
*qe[LFDS611_QUEUE_PAC_SIZE];
*qe[LFDS611_QUEUE_PAC_SIZE];
assert( qs != NULL );
// TRD : user_data can be NULL
@@ -31,7 +31,7 @@ int lfds611_queue_enqueue( struct lfds611_queue_state *qs, void *user_data )
int lfds611_queue_guaranteed_enqueue( struct lfds611_queue_state *qs, void *user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_queue_element
*qe[LFDS611_QUEUE_PAC_SIZE];
*qe[LFDS611_QUEUE_PAC_SIZE];
assert( qs != NULL );
// TRD : user_data can be NULL
@@ -54,11 +54,11 @@ int lfds611_queue_guaranteed_enqueue( struct lfds611_queue_state *qs, void *user
void lfds611_queue_internal_queue( struct lfds611_queue_state *qs, struct lfds611_queue_element *qe[LFDS611_QUEUE_PAC_SIZE] )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_queue_element
*enqueue[LFDS611_QUEUE_PAC_SIZE],
*next[LFDS611_QUEUE_PAC_SIZE];
*enqueue[LFDS611_QUEUE_PAC_SIZE],
*next[LFDS611_QUEUE_PAC_SIZE];
unsigned char
cas_result = 0;
cas_result = 0;
assert( qs != NULL );
assert( qe != NULL );
@@ -67,8 +67,7 @@ void lfds611_queue_internal_queue( struct lfds611_queue_state *qs, struct lfds61
LFDS611_BARRIER_LOAD;
do
{
do {
enqueue[LFDS611_QUEUE_POINTER] = qs->enqueue[LFDS611_QUEUE_POINTER];
enqueue[LFDS611_QUEUE_COUNTER] = qs->enqueue[LFDS611_QUEUE_COUNTER];
@@ -81,21 +80,16 @@ void lfds611_queue_internal_queue( struct lfds611_queue_state *qs, struct lfds61
LFDS611_BARRIER_LOAD;
if( qs->enqueue[LFDS611_QUEUE_POINTER] == enqueue[LFDS611_QUEUE_POINTER] and qs->enqueue[LFDS611_QUEUE_COUNTER] == enqueue[LFDS611_QUEUE_COUNTER] )
{
if( next[LFDS611_QUEUE_POINTER] == NULL )
{
if( qs->enqueue[LFDS611_QUEUE_POINTER] == enqueue[LFDS611_QUEUE_POINTER] and qs->enqueue[LFDS611_QUEUE_COUNTER] == enqueue[LFDS611_QUEUE_COUNTER] ) {
if( next[LFDS611_QUEUE_POINTER] == NULL ) {
qe[LFDS611_QUEUE_COUNTER] = next[LFDS611_QUEUE_COUNTER] + 1;
cas_result = lfds611_abstraction_dcas( (volatile lfds611_atom_t *) enqueue[LFDS611_QUEUE_POINTER]->next, (lfds611_atom_t *) qe, (lfds611_atom_t *) next );
}
else
{
} else {
next[LFDS611_QUEUE_COUNTER] = enqueue[LFDS611_QUEUE_COUNTER] + 1;
lfds611_abstraction_dcas( (volatile lfds611_atom_t *) qs->enqueue, (lfds611_atom_t *) next, (lfds611_atom_t *) enqueue );
}
}
}
while( cas_result == 0 );
} while( cas_result == 0 );
qe[LFDS611_QUEUE_COUNTER] = enqueue[LFDS611_QUEUE_COUNTER] + 1;
lfds611_abstraction_dcas( (volatile lfds611_atom_t *) qs->enqueue, (lfds611_atom_t *) qe, (lfds611_atom_t *) enqueue );
@@ -111,17 +105,17 @@ void lfds611_queue_internal_queue( struct lfds611_queue_state *qs, struct lfds61
int lfds611_queue_dequeue( struct lfds611_queue_state *qs, void **user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_queue_element
*enqueue[LFDS611_QUEUE_PAC_SIZE],
*dequeue[LFDS611_QUEUE_PAC_SIZE],
*next[LFDS611_QUEUE_PAC_SIZE];
*enqueue[LFDS611_QUEUE_PAC_SIZE],
*dequeue[LFDS611_QUEUE_PAC_SIZE],
*next[LFDS611_QUEUE_PAC_SIZE];
unsigned char
cas_result = 0;
cas_result = 0;
int
rv = 1,
state = LFDS611_QUEUE_STATE_UNKNOWN,
finished_flag = LOWERED;
rv = 1,
state = LFDS611_QUEUE_STATE_UNKNOWN,
finished_flag = LOWERED;
assert( qs != NULL );
assert( user_data != NULL );
@@ -130,8 +124,7 @@ int lfds611_queue_dequeue( struct lfds611_queue_state *qs, void **user_data )
LFDS611_BARRIER_LOAD;
do
{
do {
dequeue[LFDS611_QUEUE_POINTER] = qs->dequeue[LFDS611_QUEUE_POINTER];
dequeue[LFDS611_QUEUE_COUNTER] = qs->dequeue[LFDS611_QUEUE_COUNTER];
@@ -147,8 +140,7 @@ int lfds611_queue_dequeue( struct lfds611_queue_state *qs, void **user_data )
LFDS611_BARRIER_LOAD;
if( dequeue[LFDS611_QUEUE_POINTER] == qs->dequeue[LFDS611_QUEUE_POINTER] and dequeue[LFDS611_QUEUE_COUNTER] == qs->dequeue[LFDS611_QUEUE_COUNTER] )
{
if( dequeue[LFDS611_QUEUE_POINTER] == qs->dequeue[LFDS611_QUEUE_POINTER] and dequeue[LFDS611_QUEUE_COUNTER] == qs->dequeue[LFDS611_QUEUE_COUNTER] ) {
if( enqueue[LFDS611_QUEUE_POINTER] == dequeue[LFDS611_QUEUE_POINTER] and next[LFDS611_QUEUE_POINTER] == NULL )
state = LFDS611_QUEUE_STATE_EMPTY;
@@ -158,32 +150,31 @@ int lfds611_queue_dequeue( struct lfds611_queue_state *qs, void **user_data )
if( enqueue[LFDS611_QUEUE_POINTER] != dequeue[LFDS611_QUEUE_POINTER] )
state = LFDS611_QUEUE_STATE_ATTEMPT_DELFDS611_QUEUE;
switch( state )
{
case LFDS611_QUEUE_STATE_EMPTY:
*user_data = NULL;
rv = 0;
switch( state ) {
case LFDS611_QUEUE_STATE_EMPTY:
*user_data = NULL;
rv = 0;
finished_flag = RAISED;
break;
case LFDS611_QUEUE_STATE_ENQUEUE_OUT_OF_PLACE:
next[LFDS611_QUEUE_COUNTER] = enqueue[LFDS611_QUEUE_COUNTER] + 1;
lfds611_abstraction_dcas( (volatile lfds611_atom_t *) qs->enqueue, (lfds611_atom_t *) next, (lfds611_atom_t *) enqueue );
break;
case LFDS611_QUEUE_STATE_ATTEMPT_DELFDS611_QUEUE:
*user_data = next[LFDS611_QUEUE_POINTER]->user_data;
next[LFDS611_QUEUE_COUNTER] = dequeue[LFDS611_QUEUE_COUNTER] + 1;
cas_result = lfds611_abstraction_dcas( (volatile lfds611_atom_t *) qs->dequeue, (lfds611_atom_t *) next, (lfds611_atom_t *) dequeue );
if( cas_result == 1 )
finished_flag = RAISED;
break;
case LFDS611_QUEUE_STATE_ENQUEUE_OUT_OF_PLACE:
next[LFDS611_QUEUE_COUNTER] = enqueue[LFDS611_QUEUE_COUNTER] + 1;
lfds611_abstraction_dcas( (volatile lfds611_atom_t *) qs->enqueue, (lfds611_atom_t *) next, (lfds611_atom_t *) enqueue );
break;
case LFDS611_QUEUE_STATE_ATTEMPT_DELFDS611_QUEUE:
*user_data = next[LFDS611_QUEUE_POINTER]->user_data;
next[LFDS611_QUEUE_COUNTER] = dequeue[LFDS611_QUEUE_COUNTER] + 1;
cas_result = lfds611_abstraction_dcas( (volatile lfds611_atom_t *) qs->dequeue, (lfds611_atom_t *) next, (lfds611_atom_t *) dequeue );
if( cas_result == 1 )
finished_flag = RAISED;
break;
}
}
}
while( finished_flag == LOWERED );
} while( finished_flag == LOWERED );
if( cas_result == 1 )
lfds611_freelist_push( qs->fs, dequeue[LFDS611_QUEUE_POINTER]->fe );
@@ -56,22 +56,19 @@ struct lfds611_freelist_element *lfds611_ringbuffer_get_write_element( struct lf
stole an element from the lfds611_queue
*/
do
{
do {
if( overwrite_flag != NULL )
*overwrite_flag = 0;
lfds611_freelist_pop( rs->fs, fe );
if( *fe == NULL )
{
if( *fe == NULL ) {
lfds611_ringbuffer_get_read_element( rs, fe );
if( overwrite_flag != NULL and *fe != NULL )
*overwrite_flag = 1;
}
}
while( *fe == NULL );
} while( *fe == NULL );
return( *fe );
}
@@ -6,13 +6,12 @@
/***** structures *****/
#pragma pack( push, LFDS611_ALIGN_DOUBLE_POINTER )
struct lfds611_ringbuffer_state
{
struct lfds611_ringbuffer_state {
struct lfds611_queue_state
*qs;
*qs;
struct lfds611_freelist_state
*fs;
*fs;
};
#pragma pack( pop )
@@ -20,5 +19,6 @@ struct lfds611_ringbuffer_state
/***** externs *****/
/***** private prototypes *****/
void lfds611_ringbuffer_internal_validate( struct lfds611_ringbuffer_state *rs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_queue_validity, enum lfds611_data_structure_validity *lfds611_freelist_validity );
void lfds611_ringbuffer_internal_validate( struct lfds611_ringbuffer_state *rs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_queue_validity,
enum lfds611_data_structure_validity *lfds611_freelist_validity );
@@ -8,7 +8,7 @@
int lfds611_ringbuffer_new( struct lfds611_ringbuffer_state **rs, lfds611_atom_t number_elements, int (*user_data_init_function)(void **user_data, void *user_state), void *user_state )
{
int
rv = 0;
rv = 0;
assert( rs != NULL );
// TRD : number_elements can be any value in its range
@@ -17,26 +17,22 @@ int lfds611_ringbuffer_new( struct lfds611_ringbuffer_state **rs, lfds611_atom_t
*rs = (struct lfds611_ringbuffer_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_ringbuffer_state), LFDS611_ALIGN_DOUBLE_POINTER );
if( *rs != NULL )
{
if( *rs != NULL ) {
lfds611_freelist_new( &(*rs)->fs, number_elements, user_data_init_function, user_state );
if( (*rs)->fs != NULL )
{
if( (*rs)->fs != NULL ) {
lfds611_queue_new( &(*rs)->qs, number_elements );
if( (*rs)->qs != NULL )
rv = 1;
if( (*rs)->qs == NULL )
{
if( (*rs)->qs == NULL ) {
lfds611_liblfds_aligned_free( *rs );
*rs = NULL;
}
}
if( (*rs)->fs == NULL )
{
if( (*rs)->fs == NULL ) {
lfds611_liblfds_aligned_free( *rs );
*rs = NULL;
}
@@ -14,12 +14,12 @@ void lfds611_ringbuffer_query( struct lfds611_ringbuffer_state *rs, enum lfds611
// TRD : query_input can be NULL
assert( query_output != NULL );
switch( query_type )
{
case LFDS611_RINGBUFFER_QUERY_VALIDATE:
// TRD : query_input can be NULL
switch( query_type ) {
case LFDS611_RINGBUFFER_QUERY_VALIDATE:
// TRD : query_input can be NULL
lfds611_ringbuffer_internal_validate( rs, (struct lfds611_validation_info *) query_input, (enum lfds611_data_structure_validity *) query_output, ((enum lfds611_data_structure_validity *) query_output)+2 );
lfds611_ringbuffer_internal_validate( rs, (struct lfds611_validation_info *) query_input, (enum lfds611_data_structure_validity *) query_output,
((enum lfds611_data_structure_validity *) query_output)+2 );
break;
}
@@ -33,7 +33,8 @@ void lfds611_ringbuffer_query( struct lfds611_ringbuffer_state *rs, enum lfds611
/****************************************************************************/
void lfds611_ringbuffer_internal_validate( struct lfds611_ringbuffer_state *rs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_queue_validity, enum lfds611_data_structure_validity *lfds611_freelist_validity )
void lfds611_ringbuffer_internal_validate( struct lfds611_ringbuffer_state *rs, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *lfds611_queue_validity,
enum lfds611_data_structure_validity *lfds611_freelist_validity )
{
assert( rs != NULL );
// TRD : vi can be NULL
@@ -42,13 +43,12 @@ void lfds611_ringbuffer_internal_validate( struct lfds611_ringbuffer_state *rs,
lfds611_queue_query( rs->qs, LFDS611_QUEUE_QUERY_VALIDATE, vi, lfds611_queue_validity );
if( vi != NULL )
{
if( vi != NULL ) {
struct lfds611_validation_info
lfds611_freelist_vi;
lfds611_freelist_vi;
lfds611_atom_t
total_elements;
total_elements;
lfds611_freelist_query( rs->fs, LFDS611_FREELIST_QUERY_ELEMENT_COUNT, NULL, (void *) &total_elements );
lfds611_freelist_vi.min_elements = total_elements - vi->max_elements;
@@ -22,11 +22,11 @@ void lfds611_slist_delete( struct lfds611_slist_state *ss )
int lfds611_slist_logically_delete_element( struct lfds611_slist_state *ss, struct lfds611_slist_element *se )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) void
*volatile user_data_and_flags[2],
*volatile new_user_data_and_flags[2];
*volatile user_data_and_flags[2],
*volatile new_user_data_and_flags[2];
unsigned char
cas_rv = 0;
cas_rv = 0;
assert( ss != NULL );
assert( se != NULL );
@@ -36,12 +36,11 @@ int lfds611_slist_logically_delete_element( struct lfds611_slist_state *ss, stru
user_data_and_flags[LFDS611_SLIST_USER_DATA] = se->user_data_and_flags[LFDS611_SLIST_USER_DATA];
user_data_and_flags[LFDS611_SLIST_FLAGS] = se->user_data_and_flags[LFDS611_SLIST_FLAGS];
do
{
do {
new_user_data_and_flags[LFDS611_SLIST_USER_DATA] = user_data_and_flags[LFDS611_SLIST_USER_DATA];
new_user_data_and_flags[LFDS611_SLIST_FLAGS] = (void *) ((lfds611_atom_t) user_data_and_flags[LFDS611_SLIST_FLAGS] | LFDS611_SLIST_FLAG_DELETED);
}
while( !((lfds611_atom_t) user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED) and 0 == (cas_rv = lfds611_abstraction_dcas((volatile lfds611_atom_t *) se->user_data_and_flags, (lfds611_atom_t *) new_user_data_and_flags, (lfds611_atom_t *) user_data_and_flags)) );
} while( !((lfds611_atom_t) user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED)
and 0 == (cas_rv = lfds611_abstraction_dcas((volatile lfds611_atom_t *) se->user_data_and_flags, (lfds611_atom_t *) new_user_data_and_flags, (lfds611_atom_t *) user_data_and_flags)) );
if( cas_rv == 1 )
if( ss->user_data_delete_function != NULL )
@@ -58,15 +57,14 @@ int lfds611_slist_logically_delete_element( struct lfds611_slist_state *ss, stru
void lfds611_slist_single_threaded_physically_delete_all_elements( struct lfds611_slist_state *ss )
{
struct lfds611_slist_element
*volatile se,
*volatile se_temp;
*volatile se,
*volatile se_temp;
LFDS611_BARRIER_LOAD;
se = ss->head;
while( se != NULL )
{
while( se != NULL ) {
// TRD : if a non-deleted element and there is a delete function, call the delete function
if( ss->user_data_delete_function != NULL )
ss->user_data_delete_function( (void *) se->user_data_and_flags[LFDS611_SLIST_USER_DATA], ss->user_state );
@@ -8,7 +8,7 @@
int lfds611_slist_get_user_data_from_element( struct lfds611_slist_element *se, void **user_data )
{
int
rv = 1;
rv = 1;
assert( se != NULL );
assert( user_data != NULL );
@@ -31,11 +31,11 @@ int lfds611_slist_get_user_data_from_element( struct lfds611_slist_element *se,
int lfds611_slist_set_user_data_in_element( struct lfds611_slist_element *se, void *user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) void
*user_data_and_flags[2],
*new_user_data_and_flags[2];
*user_data_and_flags[2],
*new_user_data_and_flags[2];
int
rv = 1;
rv = 1;
assert( se != NULL );
// TRD : user_data can be NULL
@@ -47,12 +47,10 @@ int lfds611_slist_set_user_data_in_element( struct lfds611_slist_element *se, vo
new_user_data_and_flags[LFDS611_SLIST_USER_DATA] = user_data;
do
{
do {
new_user_data_and_flags[LFDS611_SLIST_FLAGS] = user_data_and_flags[LFDS611_SLIST_FLAGS];
}
while( !((lfds611_atom_t) user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED) and
0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) se->user_data_and_flags, (lfds611_atom_t *) new_user_data_and_flags, (lfds611_atom_t *) user_data_and_flags) );
} while( !((lfds611_atom_t) user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED) and
0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) se->user_data_and_flags, (lfds611_atom_t *) new_user_data_and_flags, (lfds611_atom_t *) user_data_and_flags) );
if( (lfds611_atom_t) user_data_and_flags[LFDS611_SLIST_FLAGS] & LFDS611_SLIST_FLAG_DELETED )
rv = 0;
@@ -11,14 +11,13 @@
/***** structures *****/
#pragma pack( push, LFDS611_ALIGN_SINGLE_POINTER )
struct lfds611_slist_state
{
struct lfds611_slist_state {
struct lfds611_slist_element
*volatile head;
*volatile head;
void
(*user_data_delete_function)( void *user_data, void *user_state ),
*user_state;
(*user_data_delete_function)( void *user_data, void *user_state ),
*user_state;
};
#pragma pack( pop )
@@ -33,14 +32,13 @@ struct lfds611_slist_state
accordingly, I've moved user_data_and_flags first
*/
struct lfds611_slist_element
{
struct lfds611_slist_element {
void
*volatile user_data_and_flags[2];
*volatile user_data_and_flags[2];
// TRD : requires volatile as is target of CAS
struct lfds611_slist_element
*volatile next;
*volatile next;
};
#pragma pack( pop )
@@ -8,7 +8,7 @@
void lfds611_slist_internal_link_element_to_head( struct lfds611_slist_state *ss, struct lfds611_slist_element *volatile se )
{
LFDS611_ALIGN(LFDS611_ALIGN_SINGLE_POINTER) struct lfds611_slist_element
*se_next;
*se_next;
assert( ss != NULL );
assert( se != NULL );
@@ -17,11 +17,9 @@ void lfds611_slist_internal_link_element_to_head( struct lfds611_slist_state *ss
se_next = ss->head;
do
{
do {
se->next = se_next;
}
while( se->next != (se_next = (struct lfds611_slist_element *) lfds611_abstraction_cas((volatile lfds611_atom_t *) &ss->head, (lfds611_atom_t) se, (lfds611_atom_t) se->next)) );
} while( se->next != (se_next = (struct lfds611_slist_element *) lfds611_abstraction_cas((volatile lfds611_atom_t *) &ss->head, (lfds611_atom_t) se, (lfds611_atom_t) se->next)) );
return;
}
@@ -34,8 +32,8 @@ void lfds611_slist_internal_link_element_to_head( struct lfds611_slist_state *ss
void lfds611_slist_internal_link_element_after_element( struct lfds611_slist_element *volatile lfds611_slist_in_list_element, struct lfds611_slist_element *volatile se )
{
LFDS611_ALIGN(LFDS611_ALIGN_SINGLE_POINTER) struct lfds611_slist_element
*se_prev,
*se_next;
*se_prev,
*se_next;
assert( lfds611_slist_in_list_element != NULL );
assert( se != NULL );
@@ -46,11 +44,9 @@ void lfds611_slist_internal_link_element_after_element( struct lfds611_slist_ele
se_next = se_prev->next;
do
{
do {
se->next = se_next;
}
while( se->next != (se_next = (struct lfds611_slist_element *) lfds611_abstraction_cas((volatile lfds611_atom_t *) &se_prev->next, (lfds611_atom_t) se, (lfds611_atom_t) se->next)) );
} while( se->next != (se_next = (struct lfds611_slist_element *) lfds611_abstraction_cas((volatile lfds611_atom_t *) &se_prev->next, (lfds611_atom_t) se, (lfds611_atom_t) se->next)) );
return;
}
@@ -8,7 +8,7 @@
int lfds611_slist_new( struct lfds611_slist_state **ss, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state )
{
int
rv = 0;
rv = 0;
assert( ss != NULL );
// TRD : user_data_delete_function can be NULL
@@ -16,8 +16,7 @@ int lfds611_slist_new( struct lfds611_slist_state **ss, void (*user_data_delete_
*ss = (struct lfds611_slist_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_slist_state), LFDS611_ALIGN_SINGLE_POINTER );
if( *ss != NULL )
{
if( *ss != NULL ) {
lfds611_slist_internal_init_slist( *ss, user_data_delete_function, user_state );
rv = 1;
}
@@ -71,15 +70,14 @@ void lfds611_slist_internal_init_slist( struct lfds611_slist_state *ss, void (*u
struct lfds611_slist_element *lfds611_slist_new_head( struct lfds611_slist_state *ss, void *user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_SINGLE_POINTER) struct lfds611_slist_element
*volatile se;
*volatile se;
assert( ss != NULL );
// TRD : user_data can be NULL
se = (struct lfds611_slist_element *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_slist_element), LFDS611_ALIGN_DOUBLE_POINTER );
if( se != NULL )
{
if( se != NULL ) {
se->user_data_and_flags[LFDS611_SLIST_USER_DATA] = user_data;
se->user_data_and_flags[LFDS611_SLIST_FLAGS] = LFDS611_SLIST_NO_FLAGS;
@@ -97,15 +95,14 @@ struct lfds611_slist_element *lfds611_slist_new_head( struct lfds611_slist_state
struct lfds611_slist_element *lfds611_slist_new_next( struct lfds611_slist_element *se, void *user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_SINGLE_POINTER) struct lfds611_slist_element
*volatile se_next;
*volatile se_next;
assert( se != NULL );
// TRD : user_data can be NULL
se_next = (struct lfds611_slist_element *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_slist_element), LFDS611_ALIGN_DOUBLE_POINTER );
if( se_next != NULL )
{
if( se_next != NULL ) {
se_next->user_data_and_flags[LFDS611_SLIST_USER_DATA] = user_data;
se_next->user_data_and_flags[LFDS611_SLIST_FLAGS] = LFDS611_SLIST_NO_FLAGS;
@@ -8,7 +8,7 @@
void lfds611_stack_delete( struct lfds611_stack_state *ss, void (*user_data_delete_function)(void *user_data, void *user_state), void *user_state )
{
void
*user_data;
*user_data;
assert( ss != NULL );
// TRD : user_data_delete_function can be NULL
@@ -33,7 +33,7 @@ void lfds611_stack_delete( struct lfds611_stack_state *ss, void (*user_data_dele
void lfds611_stack_clear( struct lfds611_stack_state *ss, void (*user_data_clear_function)(void *user_data, void *user_state), void *user_state )
{
void
*user_data;
*user_data;
assert( ss != NULL );
// TRD : user_data_clear_function can be NULL
@@ -11,29 +11,27 @@
/***** structures *****/
#pragma pack( push, LFDS611_ALIGN_DOUBLE_POINTER )
struct lfds611_stack_state
{
struct lfds611_stack_state {
// TRD : must come first for alignment
struct lfds611_stack_element
*volatile top[LFDS611_STACK_PAC_SIZE];
*volatile top[LFDS611_STACK_PAC_SIZE];
lfds611_atom_t
aba_counter;
aba_counter;
struct lfds611_freelist_state
*fs;
*fs;
};
struct lfds611_stack_element
{
struct lfds611_stack_element {
struct lfds611_stack_element
*next[LFDS611_STACK_PAC_SIZE];
*next[LFDS611_STACK_PAC_SIZE];
struct lfds611_freelist_element
*fe;
*fe;
void
*user_data;
*user_data;
};
#pragma pack( pop )
@@ -48,5 +46,6 @@ void lfds611_stack_internal_init_element( struct lfds611_stack_state *ss, struct
void lfds611_stack_internal_push( struct lfds611_stack_state *ss, struct lfds611_stack_element *se[LFDS611_STACK_PAC_SIZE] );
void lfds611_stack_internal_validate( struct lfds611_stack_state *ss, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *stack_validity, enum lfds611_data_structure_validity *freelist_validity );
void lfds611_stack_internal_validate( struct lfds611_stack_state *ss, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *stack_validity,
enum lfds611_data_structure_validity *freelist_validity );
@@ -8,26 +8,23 @@
int lfds611_stack_new( struct lfds611_stack_state **ss, lfds611_atom_t number_elements )
{
int
rv = 0;
rv = 0;
assert( ss != NULL );
// TRD : number_elements can be any value in its range
*ss = (struct lfds611_stack_state *) lfds611_liblfds_aligned_malloc( sizeof(struct lfds611_stack_state), LFDS611_ALIGN_DOUBLE_POINTER );
if( *ss != NULL )
{
if( *ss != NULL ) {
// TRD : the size of the lfds611_freelist is the size of the lfds611_stack
lfds611_freelist_new( &(*ss)->fs, number_elements, lfds611_stack_internal_freelist_init_function, NULL );
if( (*ss)->fs == NULL )
{
if( (*ss)->fs == NULL ) {
lfds611_liblfds_aligned_free( *ss );
*ss = NULL;
}
if( (*ss)->fs != NULL )
{
if( (*ss)->fs != NULL ) {
(*ss)->top[LFDS611_STACK_POINTER] = NULL;
(*ss)->top[LFDS611_STACK_COUNTER] = 0;
(*ss)->aba_counter = 0;
@@ -68,7 +65,7 @@ void lfds611_stack_use( struct lfds611_stack_state *ss )
int lfds611_stack_internal_freelist_init_function( void **user_data, void *user_state )
{
int
rv = 0;
rv = 0;
assert( user_data != NULL );
assert( user_state == NULL );
@@ -91,7 +88,7 @@ int lfds611_stack_internal_freelist_init_function( void **user_data, void *user_
void lfds611_stack_internal_new_element_from_freelist( struct lfds611_stack_state *ss, struct lfds611_stack_element *se[LFDS611_STACK_PAC_SIZE], void *user_data )
{
struct lfds611_freelist_element
*fe;
*fe;
assert( ss != NULL );
assert( se != NULL );
@@ -116,7 +113,7 @@ void lfds611_stack_internal_new_element_from_freelist( struct lfds611_stack_stat
void lfds611_stack_internal_new_element( struct lfds611_stack_state *ss, struct lfds611_stack_element *se[LFDS611_STACK_PAC_SIZE], void *user_data )
{
struct lfds611_freelist_element
*fe;
*fe;
assert( ss != NULL );
assert( se != NULL );
@@ -8,7 +8,7 @@
int lfds611_stack_push( struct lfds611_stack_state *ss, void *user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element
*se[LFDS611_STACK_PAC_SIZE];
*se[LFDS611_STACK_PAC_SIZE];
assert( ss != NULL );
// TRD : user_data can be NULL
@@ -31,7 +31,7 @@ int lfds611_stack_push( struct lfds611_stack_state *ss, void *user_data )
int lfds611_stack_guaranteed_push( struct lfds611_stack_state *ss, void *user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element
*se[LFDS611_STACK_PAC_SIZE];
*se[LFDS611_STACK_PAC_SIZE];
assert( ss != NULL );
// TRD : user_data can be NULL
@@ -60,7 +60,7 @@ int lfds611_stack_guaranteed_push( struct lfds611_stack_state *ss, void *user_da
void lfds611_stack_internal_push( struct lfds611_stack_state *ss, struct lfds611_stack_element *se[LFDS611_STACK_PAC_SIZE] )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element
*original_se_next[LFDS611_STACK_PAC_SIZE];
*original_se_next[LFDS611_STACK_PAC_SIZE];
assert( ss != NULL );
assert( se != NULL );
@@ -70,12 +70,10 @@ void lfds611_stack_internal_push( struct lfds611_stack_state *ss, struct lfds611
original_se_next[LFDS611_STACK_POINTER] = ss->top[LFDS611_STACK_POINTER];
original_se_next[LFDS611_STACK_COUNTER] = ss->top[LFDS611_STACK_COUNTER];
do
{
do {
se[LFDS611_STACK_POINTER]->next[LFDS611_STACK_POINTER] = original_se_next[LFDS611_STACK_POINTER];
se[LFDS611_STACK_POINTER]->next[LFDS611_STACK_COUNTER] = original_se_next[LFDS611_STACK_COUNTER];
}
while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) ss->top, (lfds611_atom_t *) se, (lfds611_atom_t *) original_se_next) );
} while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) ss->top, (lfds611_atom_t *) se, (lfds611_atom_t *) original_se_next) );
return;
}
@@ -88,7 +86,7 @@ void lfds611_stack_internal_push( struct lfds611_stack_state *ss, struct lfds611
int lfds611_stack_pop( struct lfds611_stack_state *ss, void **user_data )
{
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) struct lfds611_stack_element
*se[LFDS611_STACK_PAC_SIZE];
*se[LFDS611_STACK_PAC_SIZE];
assert( ss != NULL );
assert( user_data != NULL );
@@ -98,12 +96,10 @@ int lfds611_stack_pop( struct lfds611_stack_state *ss, void **user_data )
se[LFDS611_STACK_COUNTER] = ss->top[LFDS611_STACK_COUNTER];
se[LFDS611_STACK_POINTER] = ss->top[LFDS611_STACK_POINTER];
do
{
do {
if( se[LFDS611_STACK_POINTER] == NULL )
return( 0 );
}
while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) ss->top, (lfds611_atom_t *) se[LFDS611_STACK_POINTER]->next, (lfds611_atom_t *) se) );
} while( 0 == lfds611_abstraction_dcas((volatile lfds611_atom_t *) ss->top, (lfds611_atom_t *) se[LFDS611_STACK_POINTER]->next, (lfds611_atom_t *) se) );
*user_data = se[LFDS611_STACK_POINTER]->user_data;
@@ -14,32 +14,32 @@ void lfds611_stack_query( struct lfds611_stack_state *ss, enum lfds611_stack_que
LFDS611_BARRIER_LOAD;
switch( query_type )
{
case LFDS611_STACK_QUERY_ELEMENT_COUNT:
assert( query_input == NULL );
switch( query_type ) {
case LFDS611_STACK_QUERY_ELEMENT_COUNT:
assert( query_input == NULL );
lfds611_freelist_query( ss->fs, LFDS611_FREELIST_QUERY_ELEMENT_COUNT, NULL, query_output );
lfds611_freelist_query( ss->fs, LFDS611_FREELIST_QUERY_ELEMENT_COUNT, NULL, query_output );
break;
case LFDS611_STACK_QUERY_VALIDATE:
// TRD : query_input can be NULL
case LFDS611_STACK_QUERY_VALIDATE:
// TRD : query_input can be NULL
/* TRD : the validation info passed in is for the stack
it indicates the minimum and maximum number of elements
which should be present
/* TRD : the validation info passed in is for the stack
it indicates the minimum and maximum number of elements
which should be present
we need to validate the freelist
and validate the stack
we need to validate the freelist
and validate the stack
we cannot know the min/max for the freelist, given only
the min/max for the stack
*/
we cannot know the min/max for the freelist, given only
the min/max for the stack
*/
lfds611_freelist_query( ss->fs, LFDS611_FREELIST_QUERY_VALIDATE, NULL, (enum lfds611_data_structure_validity *) query_output );
lfds611_freelist_query( ss->fs, LFDS611_FREELIST_QUERY_VALIDATE, NULL, (enum lfds611_data_structure_validity *) query_output );
if( *(enum lfds611_data_structure_validity *) query_output == LFDS611_VALIDITY_VALID )
lfds611_stack_internal_validate( ss, (struct lfds611_validation_info *) query_input, (enum lfds611_data_structure_validity *) query_output, ((enum lfds611_data_structure_validity *) query_output)+1 );
if( *(enum lfds611_data_structure_validity *) query_output == LFDS611_VALIDITY_VALID )
lfds611_stack_internal_validate( ss, (struct lfds611_validation_info *) query_input, (enum lfds611_data_structure_validity *) query_output, ((enum lfds611_data_structure_validity *) query_output)+1 );
break;
}
@@ -51,19 +51,20 @@ void lfds611_stack_query( struct lfds611_stack_state *ss, enum lfds611_stack_que
/****************************************************************************/
void lfds611_stack_internal_validate( struct lfds611_stack_state *ss, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *stack_validity, enum lfds611_data_structure_validity *freelist_validity )
void lfds611_stack_internal_validate( struct lfds611_stack_state *ss, struct lfds611_validation_info *vi, enum lfds611_data_structure_validity *stack_validity,
enum lfds611_data_structure_validity *freelist_validity )
{
struct lfds611_stack_element
*se,
*se_slow,
*se_fast;
*se,
*se_slow,
*se_fast;
lfds611_atom_t
element_count = 0,
total_elements;
element_count = 0,
total_elements;
struct lfds611_validation_info
freelist_vi;
freelist_vi;
assert( ss != NULL );
// TRD : vi can be NULL
@@ -91,8 +92,7 @@ void lfds611_stack_internal_validate( struct lfds611_stack_state *ss, struct lfd
*/
if( se_slow != NULL )
do
{
do {
se_slow = se_slow->next[LFDS611_STACK_POINTER];
if( se_fast != NULL )
@@ -100,8 +100,7 @@ void lfds611_stack_internal_validate( struct lfds611_stack_state *ss, struct lfd
if( se_fast != NULL )
se_fast = se_fast->next[LFDS611_STACK_POINTER];
}
while( se_slow != NULL and se_fast != se_slow );
} while( se_slow != NULL and se_fast != se_slow );
if( se_fast != NULL and se_slow != NULL and se_fast == se_slow )
*stack_validity = LFDS611_VALIDITY_INVALID_LOOP;
@@ -111,12 +110,10 @@ void lfds611_stack_internal_validate( struct lfds611_stack_state *ss, struct lfd
we know we don't have a loop from our earlier check
*/
if( *stack_validity == LFDS611_VALIDITY_VALID and vi != NULL )
{
if( *stack_validity == LFDS611_VALIDITY_VALID and vi != NULL ) {
se = (struct lfds611_stack_element *) ss->top[LFDS611_STACK_POINTER];
while( se != NULL )
{
while( se != NULL ) {
element_count++;
se = (struct lfds611_stack_element *) se->next[LFDS611_STACK_POINTER];
}
@@ -140,8 +137,7 @@ void lfds611_stack_internal_validate( struct lfds611_stack_state *ss, struct lfd
freelist
*/
if( vi != NULL )
{
if( vi != NULL ) {
lfds611_freelist_query( ss->fs, LFDS611_FREELIST_QUERY_ELEMENT_COUNT, NULL, (void *) &total_elements );
freelist_vi.min_elements = total_elements - vi->max_elements;
@@ -1,44 +1,44 @@
/***** defines *****/
#if (defined _WIN32 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)
/* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler
/* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
!WIN_KERNEL_BUILD indicates Windows user-mode
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
!WIN_KERNEL_BUILD indicates Windows user-mode
*/
#include <windows.h>
typedef HANDLE thread_state_t;
typedef DWORD thread_return_t;
#define CALLING_CONVENTION WINAPI
#include <windows.h>
typedef HANDLE thread_state_t;
typedef DWORD thread_return_t;
#define CALLING_CONVENTION WINAPI
#endif
#if (defined _WIN32 && defined _MSC_VER && defined WIN_KERNEL_BUILD)
/* TRD : any Windows (kernel-mode) on any CPU with the Microsoft C compiler
/* TRD : any Windows (kernel-mode) on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
#include <wdm.h>
typedef HANDLE thread_state_t;
typedef VOID thread_return_t;
#define CALLING_CONVENTION
#include <wdm.h>
typedef HANDLE thread_state_t;
typedef VOID thread_return_t;
#define CALLING_CONVENTION
#endif
#if (defined __unix__ && defined __GNUC__)
/* TRD : any UNIX on any CPU with GCC
/* TRD : any UNIX on any CPU with GCC
__unix__ indicates Solaris, Linux, HPUX, etc
__GNUC__ indicates GCC
*/
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
typedef pthread_t thread_state_t;
typedef void * thread_return_t;
#define CALLING_CONVENTION
__unix__ indicates Solaris, Linux, HPUX, etc
__GNUC__ indicates GCC
*/
#include <unistd.h>
#include <pthread.h>
#include <sched.h>
typedef pthread_t thread_state_t;
typedef void * thread_return_t;
#define CALLING_CONVENTION
#endif
typedef thread_return_t (CALLING_CONVENTION *thread_function_t)( void *thread_user_state );
@@ -7,22 +7,22 @@
/****************************************************************************/
#if (defined _WIN32 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)
/* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler
/* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
!WIN_KERNEL_BUILD indicates Windows user-mode
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
!WIN_KERNEL_BUILD indicates Windows user-mode
*/
unsigned int abstraction_cpu_count()
{
SYSTEM_INFO
si;
unsigned int abstraction_cpu_count()
{
SYSTEM_INFO
si;
GetNativeSystemInfo( &si );
GetNativeSystemInfo( &si );
return( (unsigned int) si.dwNumberOfProcessors );
}
return( (unsigned int) si.dwNumberOfProcessors );
}
#endif
@@ -33,22 +33,22 @@
/****************************************************************************/
#if (defined _WIN32 && defined _MSC_VER && defined WIN_KERNEL_BUILD)
/* TRD : any Windows on any CPU with the Microsoft C compiler
/* TRD : any Windows on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
unsigned int abstraction_cpu_count()
{
unsigned int
active_processor_count;
unsigned int abstraction_cpu_count()
{
unsigned int
active_processor_count;
active_processor_count = KeQueryActiveProcessorCount( NULL );
active_processor_count = KeQueryActiveProcessorCount( NULL );
return( active_processor_count );
}
return( active_processor_count );
}
#endif
@@ -59,23 +59,23 @@
/****************************************************************************/
#if (defined __linux__ && defined __GNUC__)
/* TRD : Linux on any CPU with GCC
/* TRD : Linux on any CPU with GCC
this function I believe is Linux specific and varies by UNIX flavour
this function I believe is Linux specific and varies by UNIX flavour
__linux__ indicates Linux
__GNUC__ indicates GCC
*/
__linux__ indicates Linux
__GNUC__ indicates GCC
*/
unsigned int abstraction_cpu_count()
{
long int
cpu_count;
unsigned int abstraction_cpu_count()
{
long int
cpu_count;
cpu_count = sysconf( _SC_NPROCESSORS_ONLN );
cpu_count = sysconf( _SC_NPROCESSORS_ONLN );
return( (unsigned int) cpu_count );
}
return( (unsigned int) cpu_count );
}
#endif
@@ -7,41 +7,41 @@
/****************************************************************************/
#if (defined _WIN32 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)
/* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler
/* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
!WIN_KERNEL_BUILD indicates Windows user-mode
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
!WIN_KERNEL_BUILD indicates Windows user-mode
*/
int abstraction_thread_start( thread_state_t *thread_state, unsigned int cpu, thread_function_t thread_function, void *thread_user_state )
{
int
rv = 0;
int abstraction_thread_start( thread_state_t *thread_state, unsigned int cpu, thread_function_t thread_function, void *thread_user_state )
{
int
rv = 0;
DWORD
thread_id;
DWORD
thread_id;
DWORD_PTR
affinity_mask,
result;
DWORD_PTR
affinity_mask,
result;
assert( thread_state != NULL );
// TRD : cpu can be any value in its range
assert( thread_function != NULL );
// TRD : thread_user_state can be NULL
assert( thread_state != NULL );
// TRD : cpu can be any value in its range
assert( thread_function != NULL );
// TRD : thread_user_state can be NULL
affinity_mask = (DWORD_PTR) (1 << cpu);
affinity_mask = (DWORD_PTR) (1 << cpu);
*thread_state = CreateThread( NULL, 0, thread_function, thread_user_state, NO_FLAGS, &thread_id );
*thread_state = CreateThread( NULL, 0, thread_function, thread_user_state, NO_FLAGS, &thread_id );
result = SetThreadAffinityMask( *thread_state, affinity_mask );
result = SetThreadAffinityMask( *thread_state, affinity_mask );
if( *thread_state != NULL and result != 0 )
rv = 1;
if( *thread_state != NULL and result != 0 )
rv = 1;
return( rv );
}
return( rv );
}
#endif
@@ -52,41 +52,41 @@
/****************************************************************************/
#if (defined _WIN32 && defined _MSC_VER && defined WIN_KERNEL_BUILD)
/* TRD : any Windows on any CPU with the Microsoft C compiler
/* TRD : any Windows on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
int abstraction_thread_start( thread_state_t *thread_state, unsigned int cpu, thread_function_t thread_function, void *thread_user_state )
{
int
rv = 0;
int abstraction_thread_start( thread_state_t *thread_state, unsigned int cpu, thread_function_t thread_function, void *thread_user_state )
{
int
rv = 0;
KAFFINITY
affinity_mask
KAFFINITY
affinity_mask
NTSTATUS
nts_create,
nts_affinity;
NTSTATUS
nts_create,
nts_affinity;
assert( thread_state != NULL );
// TRD : cpu can be any value in its range
assert( thread_function != NULL );
// TRD : thread_user_state can be NULL
assert( thread_state != NULL );
// TRD : cpu can be any value in its range
assert( thread_function != NULL );
// TRD : thread_user_state can be NULL
affinity_mask = 1 << cpu;
affinity_mask = 1 << cpu;
nts_create = PsCreateSystemThread( thread_state, THREAD_ALL_ACCESS, NULL, NULL, NULL, thread_function, thread_user_state );
nts_create = PsCreateSystemThread( thread_state, THREAD_ALL_ACCESS, NULL, NULL, NULL, thread_function, thread_user_state );
nts_affinity = ZwSetInformationThread( thread_state, ThreadAffinityMask, &affinity_mask, sizeof(KAFFINITY) );
nts_affinity = ZwSetInformationThread( thread_state, ThreadAffinityMask, &affinity_mask, sizeof(KAFFINITY) );
if( nts_create == STATUS_SUCCESS and nts_affinity == STATUS_SUCCESS )
rv = 1;
if( nts_create == STATUS_SUCCESS and nts_affinity == STATUS_SUCCESS )
rv = 1;
return( rv );
}
return( rv );
}
#endif
@@ -97,45 +97,45 @@
/****************************************************************************/
#if (defined __unix__)
/* TRD : any UNIX on any CPU with any compiler
/* TRD : any UNIX on any CPU with any compiler
I assumed pthreads is available on any UNIX.
I assumed pthreads is available on any UNIX.
__unix__ indicates Solaris, Linux, HPUX, etc
*/
__unix__ indicates Solaris, Linux, HPUX, etc
*/
int abstraction_thread_start( thread_state_t *thread_state, unsigned int cpu, thread_function_t thread_function, void *thread_user_state )
{
int
rv = 0,
rv_create;
int abstraction_thread_start( thread_state_t *thread_state, unsigned int cpu, thread_function_t thread_function, void *thread_user_state )
{
int
rv = 0,
rv_create;
pthread_attr_t
attr;
pthread_attr_t
attr;
cpu_set_t
cpuset;
cpu_set_t
cpuset;
assert( thread_state != NULL );
// TRD : cpu can be any value in its range
assert( thread_function != NULL );
// TRD : thread_user_state can be NULL
assert( thread_state != NULL );
// TRD : cpu can be any value in its range
assert( thread_function != NULL );
// TRD : thread_user_state can be NULL
pthread_attr_init( &attr );
pthread_attr_init( &attr );
CPU_ZERO( &cpuset );
CPU_SET( cpu, &cpuset );
pthread_attr_setaffinity_np( &attr, sizeof(cpuset), &cpuset );
CPU_ZERO( &cpuset );
CPU_SET( cpu, &cpuset );
pthread_attr_setaffinity_np( &attr, sizeof(cpuset), &cpuset );
rv_create = pthread_create( thread_state, &attr, thread_function, thread_user_state );
rv_create = pthread_create( thread_state, &attr, thread_function, thread_user_state );
if( rv_create == 0 )
rv = 1;
if( rv_create == 0 )
rv = 1;
pthread_attr_destroy( &attr );
pthread_attr_destroy( &attr );
return( rv );
}
return( rv );
}
#endif
@@ -7,19 +7,19 @@
/****************************************************************************/
#if (defined _WIN32 && defined _MSC_VER && !defined WIN_KERNEL_BUILD)
/* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler
/* TRD : any Windows (user-mode) on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
!WIN_KERNEL_BUILD indicates Windows user-mode
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
!WIN_KERNEL_BUILD indicates Windows user-mode
*/
void abstraction_thread_wait( thread_state_t thread_state )
{
WaitForSingleObject( thread_state, INFINITE );
void abstraction_thread_wait( thread_state_t thread_state )
{
WaitForSingleObject( thread_state, INFINITE );
return;
}
return;
}
#endif
@@ -30,19 +30,19 @@
/****************************************************************************/
#if (defined _WIN32 && defined _MSC_VER && defined WIN_KERNEL_BUILD)
/* TRD : any Windows on any CPU with the Microsoft C compiler
/* TRD : any Windows on any CPU with the Microsoft C compiler
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
_WIN32 indicates 64-bit or 32-bit Windows
_MSC_VER indicates Microsoft C compiler
WIN_KERNEL_BUILD indicates Windows kernel
*/
void abstraction_thread_wait( thread_state_t thread_state )
{
KeWaitForSingleObject( thread_state, Executive, KernelMode, FALSE, NULL );
void abstraction_thread_wait( thread_state_t thread_state )
{
KeWaitForSingleObject( thread_state, Executive, KernelMode, FALSE, NULL );
return;
}
return;
}
#endif
@@ -53,19 +53,19 @@
/****************************************************************************/
#if (defined __unix__)
/* TRD : any UNIX on any CPU with any compiler
/* TRD : any UNIX on any CPU with any compiler
I assumed pthreads is available on any UNIX.
I assumed pthreads is available on any UNIX.
__unix__ indicates Solaris, Linux, HPUX, etc
*/
__unix__ indicates Solaris, Linux, HPUX, etc
*/
void abstraction_thread_wait( thread_state_t thread_state )
{
pthread_join( thread_state, NULL );
void abstraction_thread_wait( thread_state_t thread_state )
{
pthread_join( thread_state, NULL );
return;
}
return;
}
#endif
@@ -8,29 +8,29 @@
void benchmark_lfds611_freelist( void )
{
unsigned int
loop,
thread_count,
cpu_count;
loop,
thread_count,
cpu_count;
struct lfds611_freelist_state
*fs;
*fs;
struct lfds611_freelist_benchmark
*fb;
*fb;
thread_state_t
*thread_handles;
*thread_handles;
lfds611_atom_t
total_operations_for_full_test_for_all_cpus,
total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
total_operations_for_full_test_for_all_cpus,
total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
double
mean_operations_per_second_per_cpu,
difference_per_second_per_cpu,
total_difference_per_second_per_cpu,
std_dev_per_second_per_cpu,
scalability;
mean_operations_per_second_per_cpu,
difference_per_second_per_cpu,
total_difference_per_second_per_cpu,
std_dev_per_second_per_cpu,
scalability;
/* TRD : here we benchmark the freelist
@@ -50,13 +50,11 @@ void benchmark_lfds611_freelist( void )
"CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LFDS611_RELEASE_NUMBER_STRING );
// TRD : we run CPU count times for scalability
for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ )
{
for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ ) {
// TRD : initialisation
lfds611_freelist_new( &fs, 1000, NULL, NULL );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(fb+loop)->fs = fs;
(fb+loop)->operation_count = 0;
}
@@ -80,8 +78,7 @@ void benchmark_lfds611_freelist( void )
if( thread_count == 1 )
total_operations_for_full_test_for_all_cpus_for_one_cpu = total_operations_for_full_test_for_all_cpus;
for( loop = 0 ; loop < thread_count ; loop++ )
{
for( loop = 0 ; loop < thread_count ; loop++ ) {
difference_per_second_per_cpu = ((double) (fb+loop)->operation_count / (double) 10) - mean_operations_per_second_per_cpu;
total_difference_per_second_per_cpu += difference_per_second_per_cpu * difference_per_second_per_cpu;
}
@@ -111,13 +108,13 @@ void benchmark_lfds611_freelist( void )
thread_return_t CALLING_CONVENTION benchmark_lfds611_freelist_thread_pop_and_push( void *freelist_benchmark )
{
struct lfds611_freelist_benchmark
*fb;
*fb;
struct lfds611_freelist_element
*fe;
*fe;
time_t
start_time;
start_time;
assert( freelist_benchmark != NULL );
@@ -125,8 +122,7 @@ thread_return_t CALLING_CONVENTION benchmark_lfds611_freelist_thread_pop_and_pus
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_freelist_pop( fb->fs, &fe );
lfds611_freelist_push( fb->fs, fe );
@@ -8,29 +8,29 @@
void benchmark_lfds611_queue( void )
{
unsigned int
loop,
thread_count,
cpu_count;
loop,
thread_count,
cpu_count;
struct lfds611_queue_state
*qs;
*qs;
struct lfds611_queue_benchmark
*qb;
*qb;
thread_state_t
*thread_handles;
*thread_handles;
lfds611_atom_t
total_operations_for_full_test_for_all_cpus,
total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
total_operations_for_full_test_for_all_cpus,
total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
double
mean_operations_per_second_per_cpu,
difference_per_second_per_cpu,
total_difference_per_second_per_cpu,
std_dev_per_second_per_cpu,
scalability;
mean_operations_per_second_per_cpu,
difference_per_second_per_cpu,
total_difference_per_second_per_cpu,
std_dev_per_second_per_cpu,
scalability;
/* TRD : here we benchmark the queue
@@ -50,13 +50,11 @@ void benchmark_lfds611_queue( void )
"CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LFDS611_RELEASE_NUMBER_STRING );
// TRD : we run CPU count times for scalability
for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ )
{
for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ ) {
// TRD : initialisation
lfds611_queue_new( &qs, 1000 );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(qb+loop)->qs = qs;
(qb+loop)->operation_count = 0;
}
@@ -84,8 +82,7 @@ void benchmark_lfds611_queue( void )
if( thread_count == 1 )
total_operations_for_full_test_for_all_cpus_for_one_cpu = total_operations_for_full_test_for_all_cpus;
for( loop = 0 ; loop < thread_count ; loop++ )
{
for( loop = 0 ; loop < thread_count ; loop++ ) {
difference_per_second_per_cpu = ((double) (qb+loop)->operation_count / (double) 10) - mean_operations_per_second_per_cpu;
total_difference_per_second_per_cpu += difference_per_second_per_cpu * difference_per_second_per_cpu;
}
@@ -115,13 +112,13 @@ void benchmark_lfds611_queue( void )
thread_return_t CALLING_CONVENTION benchmark_lfds611_queue_thread_delfds611_queue_and_enqueue( void *queue_benchmark )
{
struct lfds611_queue_benchmark
*qb;
*qb;
void
*user_data;
*user_data;
time_t
start_time;
start_time;
assert( queue_benchmark != NULL );
@@ -129,8 +126,7 @@ thread_return_t CALLING_CONVENTION benchmark_lfds611_queue_thread_delfds611_queu
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_queue_dequeue( qb->qs, &user_data );
lfds611_queue_enqueue( qb->qs, user_data );
@@ -8,29 +8,29 @@
void benchmark_lfds611_ringbuffer( void )
{
unsigned int
loop,
thread_count,
cpu_count;
loop,
thread_count,
cpu_count;
struct lfds611_ringbuffer_state
*rs;
*rs;
struct lfds611_ringbuffer_benchmark
*rb;
*rb;
thread_state_t
*thread_handles;
*thread_handles;
lfds611_atom_t
total_operations_for_full_test_for_all_cpus,
total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
total_operations_for_full_test_for_all_cpus,
total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
double
mean_operations_per_second_per_cpu,
difference_per_second_per_cpu,
total_difference_per_second_per_cpu,
std_dev_per_second_per_cpu,
scalability;
mean_operations_per_second_per_cpu,
difference_per_second_per_cpu,
total_difference_per_second_per_cpu,
std_dev_per_second_per_cpu,
scalability;
/* TRD : here we benchmark the ringbuffer
@@ -50,13 +50,11 @@ void benchmark_lfds611_ringbuffer( void )
"CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LFDS611_RELEASE_NUMBER_STRING );
// TRD : we run CPU count times for scalability
for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ )
{
for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ ) {
// TRD : initialisation
lfds611_ringbuffer_new( &rs, 1000, NULL, NULL );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(rb+loop)->rs = rs;
(rb+loop)->operation_count = 0;
}
@@ -80,8 +78,7 @@ void benchmark_lfds611_ringbuffer( void )
if( thread_count == 1 )
total_operations_for_full_test_for_all_cpus_for_one_cpu = total_operations_for_full_test_for_all_cpus;
for( loop = 0 ; loop < thread_count ; loop++ )
{
for( loop = 0 ; loop < thread_count ; loop++ ) {
difference_per_second_per_cpu = ((double) (rb+loop)->operation_count / (double) 10) - mean_operations_per_second_per_cpu;
total_difference_per_second_per_cpu += difference_per_second_per_cpu * difference_per_second_per_cpu;
}
@@ -111,13 +108,13 @@ void benchmark_lfds611_ringbuffer( void )
thread_return_t CALLING_CONVENTION benchmark_lfds611_ringbuffer_thread_write_and_read( void *ringbuffer_benchmark )
{
struct lfds611_ringbuffer_benchmark
*rb;
*rb;
struct lfds611_freelist_element
*fe;
*fe;
time_t
start_time;
start_time;
assert( ringbuffer_benchmark != NULL );
@@ -125,8 +122,7 @@ thread_return_t CALLING_CONVENTION benchmark_lfds611_ringbuffer_thread_write_and
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_ringbuffer_get_write_element( rb->rs, &fe, NULL );
lfds611_ringbuffer_put_write_element( rb->rs, fe );
@@ -8,29 +8,29 @@
void benchmark_lfds611_stack( void )
{
unsigned int
loop,
thread_count,
cpu_count;
loop,
thread_count,
cpu_count;
struct lfds611_stack_state
*ss;
*ss;
struct lfds611_stack_benchmark
*sb;
*sb;
thread_state_t
*thread_handles;
*thread_handles;
lfds611_atom_t
total_operations_for_full_test_for_all_cpus,
total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
total_operations_for_full_test_for_all_cpus,
total_operations_for_full_test_for_all_cpus_for_one_cpu = 0;
double
mean_operations_per_second_per_cpu,
difference_per_second_per_cpu,
total_difference_per_second_per_cpu,
std_dev_per_second_per_cpu,
scalability;
mean_operations_per_second_per_cpu,
difference_per_second_per_cpu,
total_difference_per_second_per_cpu,
std_dev_per_second_per_cpu,
scalability;
/* TRD : here we benchmark the stack
@@ -50,13 +50,11 @@ void benchmark_lfds611_stack( void )
"CPUs,total ops,mean ops/sec per CPU,standard deviation,scalability\n", LFDS611_RELEASE_NUMBER_STRING );
// TRD : we run CPU count times for scalability
for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ )
{
for( thread_count = 1 ; thread_count <= cpu_count ; thread_count++ ) {
// TRD : initialisation
lfds611_stack_new( &ss, 1000 );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(sb+loop)->ss = ss;
(sb+loop)->operation_count = 0;
}
@@ -80,8 +78,7 @@ void benchmark_lfds611_stack( void )
if( thread_count == 1 )
total_operations_for_full_test_for_all_cpus_for_one_cpu = total_operations_for_full_test_for_all_cpus;
for( loop = 0 ; loop < thread_count ; loop++ )
{
for( loop = 0 ; loop < thread_count ; loop++ ) {
difference_per_second_per_cpu = ((double) (sb+loop)->operation_count / (double) 10) - mean_operations_per_second_per_cpu;
total_difference_per_second_per_cpu += difference_per_second_per_cpu * difference_per_second_per_cpu;
}
@@ -111,13 +108,13 @@ void benchmark_lfds611_stack( void )
thread_return_t CALLING_CONVENTION benchmark_lfds611_stack_thread_push_and_pop( void *stack_benchmark )
{
struct lfds611_stack_benchmark
*sb;
*sb;
void
*user_data = NULL;
*user_data = NULL;
time_t
start_time;
start_time;
assert( stack_benchmark != NULL );
@@ -125,8 +122,7 @@ thread_return_t CALLING_CONVENTION benchmark_lfds611_stack_thread_push_and_pop(
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_stack_push( sb->ss, user_data );
lfds611_stack_pop( sb->ss, &user_data );
@@ -32,8 +32,7 @@
#define NO_FLAGS 0x0
/***** enums *****/
enum lfds611_test_operation
{
enum lfds611_test_operation {
UNKNOWN,
HELP,
TEST,
@@ -51,74 +50,74 @@ void internal_display_test_result( unsigned int number_name_dvs_pairs, ... );
void internal_display_lfds611_data_structure_validity( enum lfds611_data_structure_validity dvs );
void benchmark_lfds611_freelist( void );
thread_return_t CALLING_CONVENTION benchmark_lfds611_freelist_thread_pop_and_push( void *freelist_benchmark );
thread_return_t CALLING_CONVENTION benchmark_lfds611_freelist_thread_pop_and_push( void *freelist_benchmark );
void benchmark_lfds611_queue( void );
thread_return_t CALLING_CONVENTION benchmark_lfds611_queue_thread_delfds611_queue_and_enqueue( void *queue_benchmark );
thread_return_t CALLING_CONVENTION benchmark_lfds611_queue_thread_delfds611_queue_and_enqueue( void *queue_benchmark );
void benchmark_lfds611_ringbuffer( void );
thread_return_t CALLING_CONVENTION benchmark_lfds611_ringbuffer_thread_write_and_read( void *ringbuffer_benchmark );
thread_return_t CALLING_CONVENTION benchmark_lfds611_ringbuffer_thread_write_and_read( void *ringbuffer_benchmark );
void benchmark_lfds611_stack( void );
thread_return_t CALLING_CONVENTION benchmark_lfds611_stack_thread_push_and_pop( void *stack_benchmark );
thread_return_t CALLING_CONVENTION benchmark_lfds611_stack_thread_push_and_pop( void *stack_benchmark );
void test_lfds611_abstraction( void );
void abstraction_test_increment( void );
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_increment( void *shared_counter );
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_atomic_increment( void *shared_counter );
void abstraction_test_cas( void );
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_cas( void *abstraction_test_cas_state );
void abstraction_test_dcas( void );
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_dcas( void *abstraction_test_dcas_state );
void abstraction_test_increment( void );
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_increment( void *shared_counter );
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_atomic_increment( void *shared_counter );
void abstraction_test_cas( void );
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_cas( void *abstraction_test_cas_state );
void abstraction_test_dcas( void );
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_dcas( void *abstraction_test_dcas_state );
void test_lfds611_freelist( void );
void freelist_test_internal_popping( void );
int freelist_test_internal_popping_init( void **user_data, void *user_state );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping( void *freelist_test_popping_state );
void freelist_test_internal_pushing( void );
int freelist_test_internal_pushing_init( void **user_data, void *user_state );
void freelist_test_internal_pushing_delete( void *user_data, void *user_state );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_pushing( void *freelist_test_pushing_state );
void freelist_test_internal_popping_and_pushing( void );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pushing_start_popping( void *freelist_test_popping_and_pushing_state );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pushing_start_pushing( void *freelist_test_popping_and_pushing_state );
void freelist_test_internal_rapid_popping_and_pushing( void );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_rapid_popping_and_pushing( void *lfds611_freelist_state );
void freelist_test_internal_popping( void );
int freelist_test_internal_popping_init( void **user_data, void *user_state );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping( void *freelist_test_popping_state );
void freelist_test_internal_pushing( void );
int freelist_test_internal_pushing_init( void **user_data, void *user_state );
void freelist_test_internal_pushing_delete( void *user_data, void *user_state );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_pushing( void *freelist_test_pushing_state );
void freelist_test_internal_popping_and_pushing( void );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pushing_start_popping( void *freelist_test_popping_and_pushing_state );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pushing_start_pushing( void *freelist_test_popping_and_pushing_state );
void freelist_test_internal_rapid_popping_and_pushing( void );
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_rapid_popping_and_pushing( void *lfds611_freelist_state );
void test_lfds611_queue( void );
void queue_test_enqueuing( void );
thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_enqueuer( void *queue_test_enqueuing_state );
void queue_test_dequeuing( void );
thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_dequeuer( void *queue_test_dequeuing_state );
void queue_test_enqueuing_and_dequeuing( void );
thread_return_t CALLING_CONVENTION queue_test_internal_thread_enqueuer_and_dequeuer( void *queue_test_rapid_enqueuing_and_dequeuing_state );
void queue_test_rapid_enqueuing_and_dequeuing( void );
thread_return_t CALLING_CONVENTION queue_test_internal_thread_rapid_enqueuer_and_dequeuer( void *queue_test_rapid_enqueuing_and_dequeuing_state );
void queue_test_enqueuing( void );
thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_enqueuer( void *queue_test_enqueuing_state );
void queue_test_dequeuing( void );
thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_dequeuer( void *queue_test_dequeuing_state );
void queue_test_enqueuing_and_dequeuing( void );
thread_return_t CALLING_CONVENTION queue_test_internal_thread_enqueuer_and_dequeuer( void *queue_test_rapid_enqueuing_and_dequeuing_state );
void queue_test_rapid_enqueuing_and_dequeuing( void );
thread_return_t CALLING_CONVENTION queue_test_internal_thread_rapid_enqueuer_and_dequeuer( void *queue_test_rapid_enqueuing_and_dequeuing_state );
void test_lfds611_ringbuffer( void );
void ringbuffer_test_reading( void );
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_reader( void *ringbuffer_test_reading_state );
void ringbuffer_test_writing( void );
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_writer( void *ringbuffer_test_writing_state );
void ringbuffer_test_reading_and_writing( void );
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_reader_writer( void *ringbuffer_test_reading_and_writing_state );
void ringbuffer_test_reading( void );
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_reader( void *ringbuffer_test_reading_state );
void ringbuffer_test_writing( void );
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_writer( void *ringbuffer_test_writing_state );
void ringbuffer_test_reading_and_writing( void );
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_reader_writer( void *ringbuffer_test_reading_and_writing_state );
void test_lfds611_slist( void );
void test_slist_new_delete_get( void );
thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_new_head_and_next( void *slist_test_state );
thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_delete_and_get( void *slist_test_state );
void test_slist_get_set_user_data( void );
thread_return_t CALLING_CONVENTION slist_test_internal_thread_get_set_user_data( void *slist_test_state );
void test_slist_delete_all_elements( void );
void test_slist_new_delete_get( void );
thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_new_head_and_next( void *slist_test_state );
thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_delete_and_get( void *slist_test_state );
void test_slist_get_set_user_data( void );
thread_return_t CALLING_CONVENTION slist_test_internal_thread_get_set_user_data( void *slist_test_state );
void test_slist_delete_all_elements( void );
void test_lfds611_stack( void );
void stack_test_internal_popping( void );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping( void *stack_test_popping_state );
void stack_test_internal_pushing( void );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_pushing( void *stack_test_pushing_state );
void stack_test_internal_popping_and_pushing( void );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushing_start_popping( void *stack_test_popping_and_pushing_state );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushing_start_pushing( void *stack_test_popping_and_pushing_state );
void stack_test_internal_rapid_popping_and_pushing( void );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_rapid_popping_and_pushing( void *stack_state );
void stack_test_internal_popping( void );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping( void *stack_test_popping_state );
void stack_test_internal_pushing( void );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_pushing( void *stack_test_pushing_state );
void stack_test_internal_popping_and_pushing( void );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushing_start_popping( void *stack_test_popping_and_pushing_state );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushing_start_pushing( void *stack_test_popping_and_pushing_state );
void stack_test_internal_rapid_popping_and_pushing( void );
thread_return_t CALLING_CONVENTION stack_test_internal_thread_rapid_popping_and_pushing( void *stack_state );
+37 -41
View File
@@ -8,11 +8,11 @@
int main( int argc, char **argv )
{
enum lfds611_test_operation
operation = UNKNOWN;
operation = UNKNOWN;
unsigned int
loop,
iterations = 1;
loop,
iterations = 1;
assert( argc >= 1 );
assert( argv != NULL );
@@ -20,10 +20,8 @@ int main( int argc, char **argv )
if( argc == 1 or argc >= 4 )
operation = HELP;
if( operation == UNKNOWN )
{
if( 0 == strcmp(*(argv+1), "test") )
{
if( operation == UNKNOWN ) {
if( 0 == strcmp(*(argv+1), "test") ) {
operation = TEST;
// TRD : sscanf() may fail, but iterations is initialised to 1, so it's okay
@@ -31,8 +29,7 @@ int main( int argc, char **argv )
sscanf( *(argv+2), "%u", &iterations );
}
if( 0 == strcmp(*(argv+1), "benchmark") )
{
if( 0 == strcmp(*(argv+1), "benchmark") ) {
operation = BENCHMARK;
// TRD : sscanf() may fail, but iterations is initialised to 1, so it's okay
@@ -41,44 +38,43 @@ int main( int argc, char **argv )
}
}
switch( operation )
{
case UNKNOWN:
case HELP:
printf( "test [test|benchmark] [iterations]\n"
" test : run the test suite\n"
" benchmark : run the benchmark suite\n"
" iterations : optional, default is 1\n" );
switch( operation ) {
case UNKNOWN:
case HELP:
printf( "test [test|benchmark] [iterations]\n"
" test : run the test suite\n"
" benchmark : run the benchmark suite\n"
" iterations : optional, default is 1\n" );
break;
case TEST:
for( loop = 1 ; loop < iterations+1 ; loop++ )
{
printf( "\n"
"Test Iteration %02u\n"
"=================\n", loop );
case TEST:
for( loop = 1 ; loop < iterations+1 ; loop++ ) {
printf( "\n"
"Test Iteration %02u\n"
"=================\n", loop );
test_lfds611_abstraction();
test_lfds611_freelist();
test_lfds611_queue();
test_lfds611_ringbuffer();
test_lfds611_slist();
test_lfds611_stack();
}
test_lfds611_abstraction();
test_lfds611_freelist();
test_lfds611_queue();
test_lfds611_ringbuffer();
test_lfds611_slist();
test_lfds611_stack();
}
break;
case BENCHMARK:
for( loop = 1 ; loop < iterations+1 ; loop++ )
{
printf( "\n"
"Benchmark Iteration %02u\n"
"========================\n", loop );
case BENCHMARK:
for( loop = 1 ; loop < iterations+1 ; loop++ ) {
printf( "\n"
"Benchmark Iteration %02u\n"
"========================\n", loop );
benchmark_lfds611_freelist();
benchmark_lfds611_queue();
benchmark_lfds611_ringbuffer();
benchmark_lfds611_stack();
}
benchmark_lfds611_freelist();
benchmark_lfds611_queue();
benchmark_lfds611_ringbuffer();
benchmark_lfds611_stack();
}
break;
}
+21 -26
View File
@@ -23,31 +23,29 @@ void internal_display_test_name( char *test_name )
void internal_display_test_result( unsigned int number_name_dvs_pairs, ... )
{
va_list
va;
va;
int
passed_flag = RAISED;
passed_flag = RAISED;
unsigned int
loop;
loop;
char
*name;
*name;
enum lfds611_data_structure_validity
dvs;
dvs;
// TRD : number_name_dvs_pairs can be any value in its range
va_start( va, number_name_dvs_pairs );
for( loop = 0 ; loop < number_name_dvs_pairs ; loop++ )
{
for( loop = 0 ; loop < number_name_dvs_pairs ; loop++ ) {
name = va_arg( va, char * );
dvs = va_arg( va, enum lfds611_data_structure_validity );
if( dvs != LFDS611_VALIDITY_VALID )
{
if( dvs != LFDS611_VALIDITY_VALID ) {
passed_flag = LOWERED;
break;
}
@@ -58,14 +56,12 @@ void internal_display_test_result( unsigned int number_name_dvs_pairs, ... )
if( passed_flag == RAISED )
puts( "passed" );
if( passed_flag == LOWERED )
{
if( passed_flag == LOWERED ) {
printf( "failed (" );
va_start( va, number_name_dvs_pairs );
for( loop = 0 ; loop < number_name_dvs_pairs ; loop++ )
{
for( loop = 0 ; loop < number_name_dvs_pairs ; loop++ ) {
name = va_arg( va, char * );
dvs = va_arg( va, enum lfds611_data_structure_validity );
@@ -92,28 +88,27 @@ void internal_display_test_result( unsigned int number_name_dvs_pairs, ... )
void internal_display_lfds611_data_structure_validity( enum lfds611_data_structure_validity dvs )
{
char
*string = NULL;
*string = NULL;
switch( dvs )
{
case LFDS611_VALIDITY_VALID:
string = "valid";
switch( dvs ) {
case LFDS611_VALIDITY_VALID:
string = "valid";
break;
case LFDS611_VALIDITY_INVALID_LOOP:
string = "invalid - loop detected";
case LFDS611_VALIDITY_INVALID_LOOP:
string = "invalid - loop detected";
break;
case LFDS611_VALIDITY_INVALID_MISSING_ELEMENTS:
string = "invalid - missing elements";
case LFDS611_VALIDITY_INVALID_MISSING_ELEMENTS:
string = "invalid - missing elements";
break;
case LFDS611_VALIDITY_INVALID_ADDITIONAL_ELEMENTS:
string = "invalid - additional elements";
case LFDS611_VALIDITY_INVALID_ADDITIONAL_ELEMENTS:
string = "invalid - additional elements";
break;
case LFDS611_VALIDITY_INVALID_TEST_DATA:
string = "invalid - invalid test data";
case LFDS611_VALIDITY_INVALID_TEST_DATA:
string = "invalid - invalid test data";
break;
}
@@ -2,225 +2,203 @@
#pragma pack( push, LFDS611_ALIGN_DOUBLE_POINTER )
/***** abstraction tests *****/
struct abstraction_test_cas_state
{
struct abstraction_test_cas_state {
volatile lfds611_atom_t
*shared_counter;
*shared_counter;
lfds611_atom_t
local_counter;
local_counter;
};
struct abstraction_test_dcas_state
{
struct abstraction_test_dcas_state {
volatile lfds611_atom_t
*shared_counter;
*shared_counter;
lfds611_atom_t
local_counter;
local_counter;
};
/***** freelist tests *****/
struct freelist_test_popping_state
{
struct freelist_test_popping_state {
struct lfds611_freelist_state
*fs,
*fs_thread_local;
*fs,
*fs_thread_local;
};
struct freelist_test_pushing_state
{
struct freelist_test_pushing_state {
lfds611_atom_t
*count,
thread_number;
*count,
thread_number;
struct lfds611_freelist_state
*source_fs,
*fs;
*source_fs,
*fs;
};
struct freelist_test_popping_and_pushing_state
{
struct freelist_test_popping_and_pushing_state {
struct lfds611_freelist_state
*local_fs,
*fs;
*local_fs,
*fs;
};
struct freelist_test_counter_and_thread_number
{
struct freelist_test_counter_and_thread_number {
lfds611_atom_t
thread_number;
thread_number;
unsigned long long int
counter;
counter;
};
/***** queue tests *****/
struct queue_test_enqueuing_state
{
struct queue_test_enqueuing_state {
struct lfds611_queue_state
*qs;
*qs;
lfds611_atom_t
counter;
counter;
};
struct queue_test_dequeuing_state
{
struct queue_test_dequeuing_state {
struct lfds611_queue_state
*qs;
*qs;
int
error_flag;
error_flag;
};
struct queue_test_enqueuing_and_dequeuing_state
{
struct queue_test_enqueuing_and_dequeuing_state {
struct lfds611_queue_state
*qs;
*qs;
lfds611_atom_t
counter,
thread_number,
*per_thread_counters;
counter,
thread_number,
*per_thread_counters;
unsigned int
cpu_count;
cpu_count;
int
error_flag;
error_flag;
};
struct queue_test_rapid_enqueuing_and_dequeuing_state
{
struct queue_test_rapid_enqueuing_and_dequeuing_state {
struct lfds611_queue_state
*qs;
*qs;
lfds611_atom_t
counter;
counter;
};
/***** ringbuffer tests *****/
struct ringbuffer_test_reading_state
{
struct ringbuffer_test_reading_state {
struct lfds611_ringbuffer_state
*rs;
*rs;
int
error_flag;
error_flag;
lfds611_atom_t
read_count;
read_count;
};
struct ringbuffer_test_writing_state
{
struct ringbuffer_test_writing_state {
struct lfds611_ringbuffer_state
*rs;
*rs;
lfds611_atom_t
write_count;
write_count;
};
struct ringbuffer_test_reading_and_writing_state
{
struct ringbuffer_test_reading_and_writing_state {
struct lfds611_ringbuffer_state
*rs;
*rs;
lfds611_atom_t
counter,
*per_thread_counters;
counter,
*per_thread_counters;
unsigned int
cpu_count;
cpu_count;
int
error_flag;
error_flag;
};
/***** slist tests *****/
struct slist_test_state
{
struct slist_test_state {
struct lfds611_slist_state
*ss;
*ss;
size_t
create_count,
delete_count;
create_count,
delete_count;
lfds611_atom_t
thread_and_count;
thread_and_count;
};
/***** stack tests *****/
struct stack_test_popping_state
{
struct stack_test_popping_state {
struct lfds611_stack_state
*ss,
*ss_thread_local;
*ss,
*ss_thread_local;
};
struct stack_test_pushing_state
{
struct stack_test_pushing_state {
lfds611_atom_t
thread_number;
thread_number;
struct lfds611_stack_state
*ss;
*ss;
};
struct stack_test_popping_and_pushing_state
{
struct stack_test_popping_and_pushing_state {
struct lfds611_stack_state
*local_ss,
*ss;
*local_ss,
*ss;
};
struct stack_test_counter_and_thread_number
{
struct stack_test_counter_and_thread_number {
lfds611_atom_t
thread_number,
counter;
thread_number,
counter;
};
/***** freelist benchmarks *****/
struct lfds611_freelist_benchmark
{
struct lfds611_freelist_benchmark {
struct lfds611_freelist_state
*fs;
*fs;
lfds611_atom_t
operation_count;
operation_count;
};
/***** queue benchmarks *****/
struct lfds611_queue_benchmark
{
struct lfds611_queue_benchmark {
struct lfds611_queue_state
*qs;
*qs;
lfds611_atom_t
operation_count;
operation_count;
};
/***** ringbuffer benchmarks *****/
struct lfds611_ringbuffer_benchmark
{
struct lfds611_ringbuffer_benchmark {
struct lfds611_ringbuffer_state
*rs;
*rs;
lfds611_atom_t
operation_count;
operation_count;
};
/***** stack benchmarks *****/
struct lfds611_stack_benchmark
{
struct lfds611_stack_benchmark {
struct lfds611_stack_state
*ss;
*ss;
lfds611_atom_t
operation_count;
operation_count;
};
#pragma pack( pop )
@@ -26,15 +26,15 @@ void test_lfds611_abstraction( void )
void abstraction_test_increment( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
LFDS611_ALIGN(LFDS611_ALIGN_SINGLE_POINTER) volatile lfds611_atom_t
shared_counter,
atomic_shared_counter;
shared_counter,
atomic_shared_counter;
/* TRD : here we test lfds611_abstraction_increment
@@ -137,20 +137,20 @@ thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_atomic_incre
void abstraction_test_cas( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct abstraction_test_cas_state
*atcs;
*atcs;
LFDS611_ALIGN(LFDS611_ALIGN_SINGLE_POINTER) volatile lfds611_atom_t
shared_counter;
shared_counter;
lfds611_atom_t
local_total = 0;
local_total = 0;
// TRD : number_logical_processors can be any value in its range
@@ -175,8 +175,7 @@ void abstraction_test_cas( void )
atcs = malloc( sizeof(struct abstraction_test_cas_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(atcs+loop)->shared_counter = &shared_counter;
(atcs+loop)->local_counter = 0;
}
@@ -215,7 +214,7 @@ void abstraction_test_cas( void )
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_cas( void *abstraction_test_cas_state )
{
struct abstraction_test_cas_state
*atcs;
*atcs;
assert( abstraction_test_cas_state != NULL );
@@ -236,20 +235,20 @@ thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_cas( void *a
void abstraction_test_dcas( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct abstraction_test_dcas_state
*atds;
*atds;
LFDS611_ALIGN(LFDS611_ALIGN_DOUBLE_POINTER) volatile lfds611_atom_t
shared_counter[2] = { 0, 0 };
shared_counter[2] = { 0, 0 };
lfds611_atom_t
local_total = 0;
local_total = 0;
/* TRD : here we test lfds611_abstraction_dcas
@@ -268,8 +267,7 @@ void abstraction_test_dcas( void )
atds = malloc( sizeof(struct abstraction_test_dcas_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(atds+loop)->shared_counter = shared_counter;
(atds+loop)->local_counter = 0;
}
@@ -310,7 +308,7 @@ void abstraction_test_dcas( void )
thread_return_t CALLING_CONVENTION abstraction_test_internal_thread_dcas( void *abstraction_test_dcas_state )
{
struct abstraction_test_dcas_state
*atds;
*atds;
assert( abstraction_test_dcas_state != NULL );
@@ -27,29 +27,29 @@ void test_lfds611_freelist( void )
void freelist_test_internal_popping( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
lfds611_atom_t
count = 0;
count = 0;
thread_state_t
*thread_handles;
*thread_handles;
enum lfds611_data_structure_validity
dvs = LFDS611_VALIDITY_VALID;
dvs = LFDS611_VALIDITY_VALID;
struct lfds611_freelist_state
*fs;
*fs;
struct lfds611_freelist_element
*fe;
*fe;
struct freelist_test_popping_state
*ftps;
*ftps;
unsigned int
*found_count;
*found_count;
/* TRD : we create a freelist with 1,000,000 elements
@@ -76,8 +76,8 @@ void freelist_test_internal_popping( void )
lfds611_freelist_new( &fs, 1000000, freelist_test_internal_popping_init, &count );
ftps = malloc( sizeof(struct freelist_test_popping_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(ftps+loop)->fs = fs;
lfds611_freelist_new( &(ftps+loop)->fs_thread_local, 0, NULL, NULL );
}
@@ -94,21 +94,19 @@ void freelist_test_internal_popping( void )
// TRD : now we check the thread-local freelists
found_count = malloc( sizeof(unsigned int) * 1000000 );
for( loop = 0 ; loop < 1000000 ; loop++ )
*(found_count+loop) = 0;
for( loop = 0 ; loop < cpu_count ; loop++ )
{
while( lfds611_freelist_pop((ftps+loop)->fs_thread_local, &fe) )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
while( lfds611_freelist_pop((ftps+loop)->fs_thread_local, &fe) ) {
lfds611_freelist_get_user_data_from_element( fe, (void **) &count );
(*(found_count+count))++;
lfds611_freelist_push( fs, fe );
}
}
for( loop = 0 ; loop < 1000000 and dvs == LFDS611_VALIDITY_VALID ; loop++ )
{
for( loop = 0 ; loop < 1000000 and dvs == LFDS611_VALIDITY_VALID ; loop++ ) {
if( *(found_count+loop) == 0 )
dvs = LFDS611_VALIDITY_INVALID_MISSING_ELEMENTS;
@@ -118,8 +116,10 @@ void freelist_test_internal_popping( void )
// TRD : cleanup
free( found_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
lfds611_freelist_delete( (ftps+loop)->fs_thread_local, NULL, NULL );
free( ftps );
lfds611_freelist_delete( fs, NULL, NULL );
@@ -139,7 +139,7 @@ void freelist_test_internal_popping( void )
int freelist_test_internal_popping_init( void **user_data, void *user_state )
{
lfds611_atom_t
*count;
*count;
assert( user_data != NULL );
assert( user_state != NULL );
@@ -161,10 +161,10 @@ int freelist_test_internal_popping_init( void **user_data, void *user_state )
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping( void *freelist_test_popping_state )
{
struct freelist_test_popping_state
*ftps;
*ftps;
struct lfds611_freelist_element
*fe;
*fe;
assert( freelist_test_popping_state != NULL );
@@ -187,34 +187,34 @@ thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping( void *
void freelist_test_internal_pushing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
lfds611_atom_t
count = 0;
count = 0;
thread_state_t
*thread_handles;
*thread_handles;
enum lfds611_data_structure_validity
dvs;
dvs;
struct freelist_test_pushing_state
*ftps;
*ftps;
struct lfds611_freelist_element
*fe;
*fe;
struct lfds611_freelist_state
*fs,
*cleanup_fs;
*fs,
*cleanup_fs;
struct freelist_test_counter_and_thread_number
*cnt,
*counter_and_number_trackers;
*cnt,
*counter_and_number_trackers;
struct lfds611_validation_info
vi;
vi;
/* TRD : we create an empty freelist, which we will push to
@@ -249,8 +249,7 @@ void freelist_test_internal_pushing( void )
lfds611_freelist_new( &fs, 0, NULL, NULL );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(ftps+loop)->thread_number = (lfds611_atom_t) loop;
// TRD : note count is shared across threads, so thread 0 is 0-100000, thread 1 is 100000-200000, etc
(ftps+loop)->count = &count;
@@ -273,8 +272,7 @@ void freelist_test_internal_pushing( void )
counter_and_number_trackers = malloc( sizeof(struct freelist_test_counter_and_thread_number) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(counter_and_number_trackers+loop)->counter = 100000 * loop;
(counter_and_number_trackers+loop)->thread_number = (lfds611_atom_t) loop;
}
@@ -283,8 +281,7 @@ void freelist_test_internal_pushing( void )
lfds611_freelist_query( fs, LFDS611_FREELIST_QUERY_VALIDATE, &vi, (void *) &dvs );
while( dvs == LFDS611_VALIDITY_VALID and lfds611_freelist_pop(fs, &fe) )
{
while( dvs == LFDS611_VALIDITY_VALID and lfds611_freelist_pop(fs, &fe) ) {
lfds611_freelist_get_user_data_from_element( fe, (void **) &cnt );
if( cnt->counter != (counter_and_number_trackers+cnt->thread_number)->counter++ )
@@ -318,10 +315,10 @@ void freelist_test_internal_pushing( void )
int freelist_test_internal_pushing_init( void **user_data, void *user_state )
{
struct freelist_test_counter_and_thread_number
*ftcatn;
*ftcatn;
struct freelist_test_pushing_state
*ftps;
*ftps;
assert( user_data != NULL );
// TRD : user_state is being used as an integer type
@@ -364,10 +361,10 @@ void freelist_test_internal_pushing_delete( void *user_data, void *user_state )
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_pushing( void *freelist_test_pushing_state )
{
struct freelist_test_pushing_state
*ftps;
*ftps;
struct lfds611_freelist_element
*fe;
*fe;
assert( freelist_test_pushing_state != NULL );
@@ -390,23 +387,23 @@ thread_return_t CALLING_CONVENTION freelist_test_internal_thread_pushing( void *
void freelist_test_internal_popping_and_pushing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
enum lfds611_data_structure_validity
dvs;
dvs;
struct lfds611_freelist_state
*fs;
*fs;
struct freelist_test_popping_and_pushing_state
*pps;
*pps;
struct lfds611_validation_info
vi;
vi;
/* TRD : we have two threads per CPU
the threads loop for ten seconds
@@ -428,8 +425,7 @@ void freelist_test_internal_popping_and_pushing( void )
pps = malloc( sizeof(struct freelist_test_popping_and_pushing_state) * cpu_count * 2 );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(pps+loop)->fs = fs;
lfds611_freelist_new( &(pps+loop)->local_fs, 0, NULL, NULL );
@@ -439,8 +435,7 @@ void freelist_test_internal_popping_and_pushing( void )
thread_handles = malloc( sizeof(thread_state_t) * cpu_count * 2 );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
abstraction_thread_start( &thread_handles[loop], loop, freelist_test_internal_thread_popping_and_pushing_start_popping, pps+loop );
abstraction_thread_start( &thread_handles[loop+cpu_count], loop, freelist_test_internal_thread_popping_and_pushing_start_pushing, pps+loop+cpu_count );
}
@@ -476,16 +471,16 @@ void freelist_test_internal_popping_and_pushing( void )
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pushing_start_popping( void *freelist_test_popping_and_pushing_state )
{
struct freelist_test_popping_and_pushing_state
*pps;
*pps;
struct lfds611_freelist_element
*fe;
*fe;
time_t
start_time;
start_time;
unsigned int
count;
count;
assert( freelist_test_popping_and_pushing_state != NULL );
@@ -496,16 +491,13 @@ thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pus
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
count = 0;
while( count < 100000 )
{
while( count < 100000 ) {
lfds611_freelist_pop( pps->fs, &fe );
if( fe != NULL )
{
if( fe != NULL ) {
lfds611_freelist_push( pps->local_fs, fe );
count++;
}
@@ -526,16 +518,16 @@ thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pus
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pushing_start_pushing( void *freelist_test_popping_and_pushing_state )
{
struct freelist_test_popping_and_pushing_state
*pps;
*pps;
struct lfds611_freelist_element
*fe;
*fe;
time_t
start_time;
start_time;
unsigned int
count;
count;
assert( freelist_test_popping_and_pushing_state != NULL );
@@ -546,19 +538,16 @@ thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pus
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
while( lfds611_freelist_pop(pps->local_fs, &fe) )
lfds611_freelist_push( pps->fs, fe );
count = 0;
while( count < 1000 )
{
while( count < 1000 ) {
lfds611_freelist_pop( pps->fs, &fe );
if( fe != NULL )
{
if( fe != NULL ) {
lfds611_freelist_push( pps->local_fs, fe );
count++;
}
@@ -580,20 +569,20 @@ thread_return_t CALLING_CONVENTION freelist_test_internal_thread_popping_and_pus
void freelist_test_internal_rapid_popping_and_pushing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_freelist_state
*fs;
*fs;
struct lfds611_validation_info
vi;
vi;
enum lfds611_data_structure_validity
dvs;
dvs;
/* TRD : in these tests there is a fundamental antagonism between
how much checking/memory clean up that we do and the
@@ -658,13 +647,13 @@ void freelist_test_internal_rapid_popping_and_pushing( void )
thread_return_t CALLING_CONVENTION freelist_test_internal_thread_rapid_popping_and_pushing( void *lfds611_freelist_state )
{
struct lfds611_freelist_state
*fs;
*fs;
struct lfds611_freelist_element
*fe;
*fe;
time_t
start_time;
start_time;
assert( lfds611_freelist_state != NULL );
@@ -674,8 +663,7 @@ thread_return_t CALLING_CONVENTION freelist_test_internal_thread_rapid_popping_a
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_freelist_pop( fs, &fe );
lfds611_freelist_push( fs, fe );
}
@@ -27,29 +27,29 @@ void test_lfds611_queue( void )
void queue_test_enqueuing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_queue_state
*qs;
*qs;
struct queue_test_enqueuing_state
*qtes;
*qtes;
lfds611_atom_t
user_data,
thread,
count,
*per_thread_counters;
user_data,
thread,
count,
*per_thread_counters;
struct lfds611_validation_info
vi = { 1000000, 1000000 };
vi = { 1000000, 1000000 };
enum lfds611_data_structure_validity
dvs[2];
dvs[2];
/* TRD : create an empty queue with 1,000,000 elements in its freelist
then run one thread per CPU
@@ -70,8 +70,7 @@ void queue_test_enqueuing( void )
qtes = malloc( sizeof(struct queue_test_enqueuing_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(qtes+loop)->qs = qs;
(qtes+loop)->counter = (lfds611_atom_t) loop << (sizeof(lfds611_atom_t)*8-8);
}
@@ -101,13 +100,11 @@ void queue_test_enqueuing( void )
for( loop = 0 ; loop < cpu_count ; loop++ )
*(per_thread_counters+loop) = 0;
while( dvs[0] == LFDS611_VALIDITY_VALID and dvs[1] == LFDS611_VALIDITY_VALID and lfds611_queue_dequeue(qs, (void *) &user_data) )
{
while( dvs[0] == LFDS611_VALIDITY_VALID and dvs[1] == LFDS611_VALIDITY_VALID and lfds611_queue_dequeue(qs, (void *) &user_data) ) {
thread = user_data >> (sizeof(lfds611_atom_t)*8-8);
count = (user_data << 8) >> 8;
if( thread >= cpu_count )
{
if( thread >= cpu_count ) {
dvs[0] = LFDS611_VALIDITY_INVALID_TEST_DATA;
break;
}
@@ -139,7 +136,7 @@ void queue_test_enqueuing( void )
thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_enqueuer( void *queue_test_enqueuing_state )
{
struct queue_test_enqueuing_state
*qtes;
*qtes;
assert( queue_test_enqueuing_state != NULL );
@@ -161,23 +158,23 @@ thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_enqueuer( v
void queue_test_dequeuing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_queue_state
*qs;
*qs;
struct queue_test_dequeuing_state
*qtds;
*qtds;
struct lfds611_validation_info
vi = { 0, 0 };
vi = { 0, 0 };
enum lfds611_data_structure_validity
dvs[2];
dvs[2];
/* TRD : create a queue with 1,000,000 elements
@@ -202,8 +199,7 @@ void queue_test_dequeuing( void )
qtds = malloc( sizeof(struct queue_test_dequeuing_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(qtds+loop)->qs = qs;
(qtds+loop)->error_flag = LOWERED;
}
@@ -243,11 +239,11 @@ void queue_test_dequeuing( void )
thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_dequeuer( void *queue_test_dequeuing_state )
{
struct queue_test_dequeuing_state
*qtds;
*qtds;
lfds611_atom_t
*prev_user_data,
*user_data;
*prev_user_data,
*user_data;
assert( queue_test_dequeuing_state != NULL );
@@ -257,8 +253,7 @@ thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_dequeuer( v
lfds611_queue_dequeue( qtds->qs, (void *) &prev_user_data );
while( lfds611_queue_dequeue(qtds->qs, (void *) &user_data) )
{
while( lfds611_queue_dequeue(qtds->qs, (void *) &user_data) ) {
if( user_data <= prev_user_data )
qtds->error_flag = RAISED;
@@ -276,24 +271,24 @@ thread_return_t CALLING_CONVENTION queue_test_internal_thread_simple_dequeuer( v
void queue_test_enqueuing_and_dequeuing( void )
{
unsigned int
loop,
subloop,
cpu_count;
loop,
subloop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_queue_state
*qs;
*qs;
struct queue_test_enqueuing_and_dequeuing_state
*qteds;
*qteds;
struct lfds611_validation_info
vi = { 0, 0 };
vi = { 0, 0 };
enum lfds611_data_structure_validity
dvs[2];
dvs[2];
internal_display_test_name( "Enqueuing and dequeuing (10 seconds)" );
@@ -303,8 +298,7 @@ void queue_test_enqueuing_and_dequeuing( void )
qteds = malloc( sizeof(struct queue_test_enqueuing_and_dequeuing_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(qteds+loop)->qs = qs;
(qteds+loop)->thread_number = loop;
(qteds+loop)->counter = (lfds611_atom_t) loop << (sizeof(lfds611_atom_t)*8-8);
@@ -352,15 +346,15 @@ void queue_test_enqueuing_and_dequeuing( void )
thread_return_t CALLING_CONVENTION queue_test_internal_thread_enqueuer_and_dequeuer( void *queue_test_enqueuing_and_dequeuing_state )
{
struct queue_test_enqueuing_and_dequeuing_state
*qteds;
*qteds;
time_t
start_time;
start_time;
lfds611_atom_t
thread,
count,
user_data;
thread,
count,
user_data;
assert( queue_test_enqueuing_and_dequeuing_state != NULL );
@@ -370,8 +364,7 @@ thread_return_t CALLING_CONVENTION queue_test_internal_thread_enqueuer_and_deque
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_queue_enqueue( qteds->qs, (void *) (qteds->counter++) );
lfds611_queue_dequeue( qteds->qs, (void *) &user_data );
@@ -380,8 +373,7 @@ thread_return_t CALLING_CONVENTION queue_test_internal_thread_enqueuer_and_deque
if( thread >= qteds->cpu_count )
qteds->error_flag = RAISED;
else
{
else {
if( count < qteds->per_thread_counters[thread] )
qteds->error_flag = RAISED;
@@ -401,29 +393,29 @@ thread_return_t CALLING_CONVENTION queue_test_internal_thread_enqueuer_and_deque
void queue_test_rapid_enqueuing_and_dequeuing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_queue_state
*qs;
*qs;
struct queue_test_rapid_enqueuing_and_dequeuing_state
*qtreds;
*qtreds;
struct lfds611_validation_info
vi = { 50000, 50000 };
vi = { 50000, 50000 };
lfds611_atom_t
user_data,
thread,
count,
*per_thread_counters;
user_data,
thread,
count,
*per_thread_counters;
enum lfds611_data_structure_validity
dvs[2];
dvs[2];
internal_display_test_name( "Rapid enqueuing and dequeuing (10 seconds)" );
@@ -436,8 +428,7 @@ void queue_test_rapid_enqueuing_and_dequeuing( void )
qtreds = malloc( sizeof(struct queue_test_rapid_enqueuing_and_dequeuing_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(qtreds+loop)->qs = qs;
(qtreds+loop)->counter = (lfds611_atom_t) loop << (sizeof(lfds611_atom_t)*8-8);
}
@@ -460,13 +451,11 @@ void queue_test_rapid_enqueuing_and_dequeuing( void )
for( loop = 0 ; loop < cpu_count ; loop++ )
*(per_thread_counters+loop) = 0;
while( dvs[0] == LFDS611_VALIDITY_VALID and dvs[1] == LFDS611_VALIDITY_VALID and lfds611_queue_dequeue(qs, (void *) &user_data) )
{
while( dvs[0] == LFDS611_VALIDITY_VALID and dvs[1] == LFDS611_VALIDITY_VALID and lfds611_queue_dequeue(qs, (void *) &user_data) ) {
thread = user_data >> (sizeof(lfds611_atom_t)*8-8);
count = (user_data << 8) >> 8;
if( thread >= cpu_count )
{
if( thread >= cpu_count ) {
dvs[0] = LFDS611_VALIDITY_INVALID_TEST_DATA;
break;
}
@@ -500,13 +489,13 @@ void queue_test_rapid_enqueuing_and_dequeuing( void )
thread_return_t CALLING_CONVENTION queue_test_internal_thread_rapid_enqueuer_and_dequeuer( void *queue_test_rapid_enqueuing_and_dequeuing_state )
{
struct queue_test_rapid_enqueuing_and_dequeuing_state
*qtreds;
*qtreds;
time_t
start_time;
start_time;
lfds611_atom_t
user_data;
user_data;
assert( queue_test_rapid_enqueuing_and_dequeuing_state != NULL );
@@ -516,8 +505,7 @@ thread_return_t CALLING_CONVENTION queue_test_internal_thread_rapid_enqueuer_and
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_queue_enqueue( qtreds->qs, (void *) (qtreds->counter++) );
lfds611_queue_dequeue( qtreds->qs, (void *) &user_data );
}
@@ -26,29 +26,29 @@ void test_lfds611_ringbuffer( void )
void ringbuffer_test_reading( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_ringbuffer_state
*rs;
*rs;
struct lfds611_freelist_element
*fe;
*fe;
struct ringbuffer_test_reading_state
*rtrs;
*rtrs;
struct lfds611_validation_info
vi = { 0, 0 };
vi = { 0, 0 };
enum lfds611_data_structure_validity
dvs[3];
dvs[3];
lfds611_atom_t
total_read = 0;
total_read = 0;
/* TRD : we create a single ringbuffer
with 1,000,000 elements
@@ -70,8 +70,7 @@ void ringbuffer_test_reading( void )
lfds611_ringbuffer_new( &rs, 1000000, NULL, NULL );
for( loop = 0 ; loop < 1000000 ; loop++ )
{
for( loop = 0 ; loop < 1000000 ; loop++ ) {
lfds611_ringbuffer_get_write_element( rs, &fe, NULL );
lfds611_freelist_set_user_data_in_element( fe, (void *) (lfds611_atom_t) loop );
lfds611_ringbuffer_put_write_element( rs, fe );
@@ -79,8 +78,7 @@ void ringbuffer_test_reading( void )
rtrs = malloc( sizeof(struct ringbuffer_test_reading_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(rtrs+loop)->rs = rs;
(rtrs+loop)->read_count = 0;
(rtrs+loop)->error_flag = LOWERED;
@@ -130,14 +128,14 @@ void ringbuffer_test_reading( void )
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_reader( void *ringbuffer_test_reading_state )
{
struct ringbuffer_test_reading_state
*rtrs;
*rtrs;
struct lfds611_freelist_element
*fe;
*fe;
lfds611_atom_t
*prev_user_data,
*user_data;
*prev_user_data,
*user_data;
assert( ringbuffer_test_reading_state != NULL );
@@ -151,15 +149,16 @@ thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_reader( void *r
*/
lfds611_ringbuffer_get_read_element( rtrs->rs, &fe );
if( fe == NULL )
return( (thread_return_t) EXIT_SUCCESS );
lfds611_freelist_get_user_data_from_element( fe, (void **) &prev_user_data );
lfds611_ringbuffer_put_read_element( rtrs->rs, fe );
rtrs->read_count++;
while( lfds611_ringbuffer_get_read_element(rtrs->rs, &fe) )
{
while( lfds611_ringbuffer_get_read_element(rtrs->rs, &fe) ) {
lfds611_freelist_get_user_data_from_element( fe, (void **) &user_data );
lfds611_ringbuffer_put_read_element( rtrs->rs, fe );
@@ -182,32 +181,32 @@ thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_reader( void *r
void ringbuffer_test_writing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_ringbuffer_state
*rs;
*rs;
struct lfds611_freelist_element
*fe;
*fe;
struct ringbuffer_test_writing_state
*rtws;
*rtws;
struct lfds611_validation_info
vi = { 100000, 100000 };
vi = { 100000, 100000 };
enum lfds611_data_structure_validity
dvs[3];
dvs[3];
lfds611_atom_t
thread,
count,
user_data,
*per_thread_counters;
thread,
count,
user_data,
*per_thread_counters;
/* TRD : we create a single ringbuffer
with 100000 elements
@@ -233,8 +232,7 @@ void ringbuffer_test_writing( void )
rtws = malloc( sizeof(struct ringbuffer_test_writing_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(rtws+loop)->rs = rs;
(rtws+loop)->write_count = (lfds611_atom_t) loop << (sizeof(lfds611_atom_t)*8-8);
}
@@ -257,15 +255,13 @@ void ringbuffer_test_writing( void )
lfds611_ringbuffer_query( rs, LFDS611_RINGBUFFER_QUERY_VALIDATE, (void *) &vi, (void *) dvs );
while( dvs[0] == LFDS611_VALIDITY_VALID and dvs[1] == LFDS611_VALIDITY_VALID and dvs[2] == LFDS611_VALIDITY_VALID and lfds611_ringbuffer_get_read_element(rs, &fe) )
{
while( dvs[0] == LFDS611_VALIDITY_VALID and dvs[1] == LFDS611_VALIDITY_VALID and dvs[2] == LFDS611_VALIDITY_VALID and lfds611_ringbuffer_get_read_element(rs, &fe) ) {
lfds611_freelist_get_user_data_from_element( fe, (void *) &user_data );
thread = user_data >> (sizeof(lfds611_atom_t)*8-8);
count = (user_data << 8) >> 8;
if( thread >= cpu_count )
{
if( thread >= cpu_count ) {
dvs[0] = LFDS611_VALIDITY_INVALID_TEST_DATA;
lfds611_ringbuffer_put_read_element( rs, fe );
break;
@@ -302,13 +298,13 @@ void ringbuffer_test_writing( void )
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_writer( void *ringbuffer_test_writing_state )
{
struct ringbuffer_test_writing_state
*rtws;
*rtws;
struct lfds611_freelist_element
*fe;
*fe;
time_t
start_time;
start_time;
assert( ringbuffer_test_writing_state != NULL );
@@ -318,8 +314,7 @@ thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_writer( void *r
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_ringbuffer_get_write_element( rtws->rs, &fe, NULL );
lfds611_freelist_set_user_data_in_element( fe, (void *) (lfds611_atom_t) (rtws->write_count++) );
lfds611_ringbuffer_put_write_element( rtws->rs, fe );
@@ -336,24 +331,24 @@ thread_return_t CALLING_CONVENTION ringbuffer_test_thread_simple_writer( void *r
void ringbuffer_test_reading_and_writing( void )
{
unsigned int
loop,
subloop,
cpu_count;
loop,
subloop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_ringbuffer_state
*rs;
*rs;
struct ringbuffer_test_reading_and_writing_state
*rtrws;
*rtrws;
struct lfds611_validation_info
vi = { 0, 0 };
vi = { 0, 0 };
enum lfds611_data_structure_validity
dvs[3];
dvs[3];
/* TRD : we create a single ringbuffer
with 100000 elements
@@ -380,8 +375,7 @@ void ringbuffer_test_reading_and_writing( void )
rtrws = malloc( sizeof(struct ringbuffer_test_reading_and_writing_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(rtrws+loop)->rs = rs;
(rtrws+loop)->counter = (lfds611_atom_t) loop << (sizeof(lfds611_atom_t)*8-8);
(rtrws+loop)->cpu_count = cpu_count;
@@ -428,18 +422,18 @@ void ringbuffer_test_reading_and_writing( void )
thread_return_t CALLING_CONVENTION ringbuffer_test_thread_reader_writer( void *ringbuffer_test_reading_and_writing_state )
{
struct ringbuffer_test_reading_and_writing_state
*rtrws;
*rtrws;
struct lfds611_freelist_element
*fe;
*fe;
lfds611_atom_t
user_data,
thread,
count;
user_data,
thread,
count;
time_t
start_time;
start_time;
assert( ringbuffer_test_reading_and_writing_state != NULL );
@@ -449,8 +443,7 @@ thread_return_t CALLING_CONVENTION ringbuffer_test_thread_reader_writer( void *r
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_ringbuffer_get_write_element( rtrws->rs, &fe, NULL );
lfds611_freelist_set_user_data_in_element( fe, (void *) (lfds611_atom_t) (rtrws->counter++) );
lfds611_ringbuffer_put_write_element( rtrws->rs, fe );
@@ -463,8 +456,7 @@ thread_return_t CALLING_CONVENTION ringbuffer_test_thread_reader_writer( void *r
if( thread >= rtrws->cpu_count )
rtrws->error_flag = RAISED;
else
{
else {
if( count < rtrws->per_thread_counters[thread] )
rtrws->error_flag = RAISED;
@@ -26,28 +26,28 @@ void test_lfds611_slist( void )
void test_slist_new_delete_get( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
struct lfds611_slist_state
*ss;
*ss;
struct lfds611_slist_element
*se = NULL;
*se = NULL;
struct slist_test_state
*sts;
*sts;
thread_state_t
*thread_handles;
*thread_handles;
size_t
total_create_count = 0,
total_delete_count = 0,
element_count = 0;
total_create_count = 0,
total_delete_count = 0,
element_count = 0;
enum lfds611_data_structure_validity
dvs = LFDS611_VALIDITY_VALID;
dvs = LFDS611_VALIDITY_VALID;
/* TRD : two threads per CPU
first simply alternates between new_head() and new_next() (next on element created by head)
@@ -64,8 +64,7 @@ void test_slist_new_delete_get( void )
sts = malloc( sizeof(struct slist_test_state) * cpu_count * 2 );
for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
{
for( loop = 0 ; loop < cpu_count * 2 ; loop++ ) {
(sts+loop)->ss = ss;
(sts+loop)->create_count = 0;
(sts+loop)->delete_count = 0;
@@ -73,8 +72,7 @@ void test_slist_new_delete_get( void )
thread_handles = malloc( sizeof(thread_state_t) * cpu_count * 2 );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
abstraction_thread_start( &thread_handles[loop], loop, slist_test_internal_thread_new_delete_get_new_head_and_next, sts+loop );
abstraction_thread_start( &thread_handles[loop+cpu_count], loop, slist_test_internal_thread_new_delete_get_delete_and_get, sts+loop+cpu_count );
}
@@ -85,8 +83,7 @@ void test_slist_new_delete_get( void )
free( thread_handles );
// TRD : now validate
for( loop = 0 ; loop < cpu_count * 2 ; loop++ )
{
for( loop = 0 ; loop < cpu_count * 2 ; loop++ ) {
total_create_count += (sts+loop)->create_count;
total_delete_count += (sts+loop)->delete_count;
}
@@ -114,13 +111,13 @@ void test_slist_new_delete_get( void )
thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_new_head_and_next( void *slist_test_state )
{
struct slist_test_state
*sts;
*sts;
time_t
start_time;
start_time;
struct lfds611_slist_element
*se = NULL;
*se = NULL;
assert( slist_test_state != NULL );
@@ -130,8 +127,7 @@ thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_new
time( &start_time );
while( time(NULL) < start_time + 1 )
{
while( time(NULL) < start_time + 1 ) {
if( sts->create_count % 2 == 0 )
se = lfds611_slist_new_head( sts->ss, NULL );
else
@@ -151,13 +147,13 @@ thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_new
thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_delete_and_get( void *slist_test_state )
{
struct slist_test_state
*sts;
*sts;
time_t
start_time;
start_time;
struct lfds611_slist_element
*se = NULL;
*se = NULL;
assert( slist_test_state != NULL );
@@ -167,15 +163,13 @@ thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_del
time( &start_time );
while( time(NULL) < start_time + 1 )
{
while( time(NULL) < start_time + 1 ) {
if( se == NULL )
lfds611_slist_get_head( sts->ss, &se );
else
lfds611_slist_get_next( se, &se );
if( se != NULL )
{
if( se != NULL ) {
if( 1 == lfds611_slist_logically_delete_element(sts->ss, se) )
sts->delete_count++;
}
@@ -192,30 +186,30 @@ thread_return_t CALLING_CONVENTION slist_test_internal_thread_new_delete_get_del
void test_slist_get_set_user_data( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
struct lfds611_slist_state
*ss;
*ss;
struct lfds611_slist_element
*se = NULL;
*se = NULL;
struct slist_test_state
*sts;
*sts;
thread_state_t
*thread_handles;
*thread_handles;
lfds611_atom_t
thread_and_count,
thread,
count,
*per_thread_counters,
*per_thread_drop_flags;
thread_and_count,
thread,
count,
*per_thread_counters,
*per_thread_drop_flags;
enum lfds611_data_structure_validity
dvs = LFDS611_VALIDITY_VALID;
dvs = LFDS611_VALIDITY_VALID;
/* TRD : create a list of (cpu_count*10) elements, user data 0
one thread per CPU
@@ -234,8 +228,7 @@ void test_slist_get_set_user_data( void )
sts = malloc( sizeof(struct slist_test_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(sts+loop)->ss = ss;
(sts+loop)->thread_and_count = (lfds611_atom_t) loop << (sizeof(lfds611_atom_t)*8-8);
}
@@ -254,41 +247,35 @@ void test_slist_get_set_user_data( void )
per_thread_counters = malloc( sizeof(lfds611_atom_t) * cpu_count );
per_thread_drop_flags = malloc( sizeof(lfds611_atom_t) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
*(per_thread_counters+loop) = 0;
*(per_thread_drop_flags+loop) = 0;
}
while( dvs == LFDS611_VALIDITY_VALID and NULL != lfds611_slist_get_head_and_then_next(ss, &se) )
{
while( dvs == LFDS611_VALIDITY_VALID and NULL != lfds611_slist_get_head_and_then_next(ss, &se) ) {
lfds611_slist_get_user_data_from_element( se, (void **) &thread_and_count );
thread = thread_and_count >> (sizeof(lfds611_atom_t)*8-8);
count = (thread_and_count << 8) >> 8;
if( thread >= cpu_count )
{
if( thread >= cpu_count ) {
dvs = LFDS611_VALIDITY_INVALID_TEST_DATA;
break;
}
if( per_thread_counters[thread] == 0 )
{
if( per_thread_counters[thread] == 0 ) {
per_thread_counters[thread] = count;
continue;
}
per_thread_counters[thread]++;
if( count < per_thread_counters[thread] and per_thread_drop_flags[thread] == 1 )
{
if( count < per_thread_counters[thread] and per_thread_drop_flags[thread] == 1 ) {
dvs = LFDS611_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
break;
}
if( count < per_thread_counters[thread] and per_thread_drop_flags[thread] == 0 )
{
if( count < per_thread_counters[thread] and per_thread_drop_flags[thread] == 0 ) {
per_thread_drop_flags[thread] = 1;
per_thread_counters[thread] = count;
continue;
@@ -321,13 +308,13 @@ void test_slist_get_set_user_data( void )
thread_return_t CALLING_CONVENTION slist_test_internal_thread_get_set_user_data( void *slist_test_state )
{
struct slist_test_state
*sts;
*sts;
time_t
start_time;
start_time;
struct lfds611_slist_element
*se = NULL;
*se = NULL;
assert( slist_test_state != NULL );
@@ -337,8 +324,7 @@ thread_return_t CALLING_CONVENTION slist_test_internal_thread_get_set_user_data(
time( &start_time );
while( time(NULL) < start_time + 1 )
{
while( time(NULL) < start_time + 1 ) {
if( se == NULL )
lfds611_slist_get_head( sts->ss, &se );
@@ -358,19 +344,19 @@ thread_return_t CALLING_CONVENTION slist_test_internal_thread_get_set_user_data(
void test_slist_delete_all_elements( void )
{
struct lfds611_slist_state
*ss;
*ss;
struct lfds611_slist_element
*se = NULL;
*se = NULL;
size_t
element_count = 0;
element_count = 0;
unsigned int
loop;
loop;
enum lfds611_data_structure_validity
dvs = LFDS611_VALIDITY_VALID;
dvs = LFDS611_VALIDITY_VALID;
/* TRD : this test creates a list of 100,000 elements
then simply calls delete_all_elements()
@@ -27,24 +27,24 @@ void test_lfds611_stack( void )
void stack_test_internal_popping( void )
{
unsigned int
loop,
*found_count,
cpu_count;
loop,
*found_count,
cpu_count;
lfds611_atom_t
count;
count;
thread_state_t
*thread_handles;
*thread_handles;
enum lfds611_data_structure_validity
dvs = LFDS611_VALIDITY_VALID;
dvs = LFDS611_VALIDITY_VALID;
struct lfds611_stack_state
*ss;
*ss;
struct stack_test_popping_state
*stps;
*stps;
/* TRD : we create a stack with 1,000,000 elements
@@ -73,8 +73,8 @@ void stack_test_internal_popping( void )
lfds611_stack_push( ss, (void *) (lfds611_atom_t) loop );
stps = malloc( sizeof(struct stack_test_popping_state) * cpu_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(stps+loop)->ss = ss;
lfds611_stack_new( &(stps+loop)->ss_thread_local, 1000000 );
}
@@ -91,6 +91,7 @@ void stack_test_internal_popping( void )
// TRD : now we check the thread-local stacks
found_count = malloc( sizeof(unsigned int) * 1000000 );
for( loop = 0 ; loop < 1000000 ; loop++ )
*(found_count+loop) = 0;
@@ -98,8 +99,7 @@ void stack_test_internal_popping( void )
while( lfds611_stack_pop((stps+loop)->ss_thread_local, (void **) &count) )
(*(found_count+count))++;
for( loop = 0 ; loop < 1000000 and dvs == LFDS611_VALIDITY_VALID ; loop++ )
{
for( loop = 0 ; loop < 1000000 and dvs == LFDS611_VALIDITY_VALID ; loop++ ) {
if( *(found_count+loop) == 0 )
dvs = LFDS611_VALIDITY_INVALID_MISSING_ELEMENTS;
@@ -109,8 +109,10 @@ void stack_test_internal_popping( void )
// TRD : cleanup
free( found_count );
for( loop = 0 ; loop < cpu_count ; loop++ )
lfds611_stack_delete( (stps+loop)->ss_thread_local, NULL, NULL );
free( stps );
lfds611_stack_delete( ss, NULL, NULL );
@@ -128,10 +130,10 @@ void stack_test_internal_popping( void )
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping( void *stack_test_popping_state )
{
struct stack_test_popping_state
*stps;
*stps;
lfds611_atom_t
count;
count;
assert( stack_test_popping_state != NULL );
@@ -153,29 +155,29 @@ thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping( void *sta
void stack_test_internal_pushing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
enum lfds611_data_structure_validity
dvs[2];
dvs[2];
struct stack_test_pushing_state
*stps;
*stps;
struct lfds611_stack_state
*ss;
*ss;
lfds611_atom_t
user_data,
thread,
count,
*per_thread_counters;
user_data,
thread,
count,
*per_thread_counters;
struct lfds611_validation_info
vi = { 1000000, 1000000 };
vi = { 1000000, 1000000 };
/* TRD : we create a stack with 1,000,000 elements
@@ -204,8 +206,7 @@ void stack_test_internal_pushing( void )
// TRD : the main stack
lfds611_stack_new( &ss, 1000000 );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(stps+loop)->thread_number = (lfds611_atom_t) loop;
(stps+loop)->ss = ss;
}
@@ -228,13 +229,11 @@ void stack_test_internal_pushing( void )
lfds611_stack_query( ss, LFDS611_STACK_QUERY_VALIDATE, &vi, (void *) dvs );
while( dvs[0] == LFDS611_VALIDITY_VALID and lfds611_stack_pop(ss, (void **) &user_data) )
{
while( dvs[0] == LFDS611_VALIDITY_VALID and lfds611_stack_pop(ss, (void **) &user_data) ) {
thread = user_data >> (sizeof(lfds611_atom_t)*8-8);
count = (user_data << 8) >> 8;
if( thread >= cpu_count )
{
if( thread >= cpu_count ) {
dvs[0] = LFDS611_VALIDITY_INVALID_TEST_DATA;
break;
}
@@ -267,10 +266,10 @@ void stack_test_internal_pushing( void )
thread_return_t CALLING_CONVENTION stack_test_internal_thread_pushing( void *stack_test_pushing_state )
{
struct stack_test_pushing_state
*stps;
*stps;
lfds611_atom_t
counter = 0;
counter = 0;
assert( stack_test_pushing_state != NULL );
@@ -292,24 +291,24 @@ thread_return_t CALLING_CONVENTION stack_test_internal_thread_pushing( void *sta
void stack_test_internal_popping_and_pushing( void )
{
unsigned int
loop,
subloop,
cpu_count;
loop,
subloop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
enum lfds611_data_structure_validity
dvs[2];
dvs[2];
struct lfds611_stack_state
*ss;
*ss;
struct stack_test_popping_and_pushing_state
*stpps;
*stpps;
struct lfds611_validation_info
vi;
vi;
/* TRD : we have two threads per CPU
the threads loop for ten seconds
@@ -335,8 +334,7 @@ void stack_test_internal_popping_and_pushing( void )
stpps = malloc( sizeof(struct stack_test_popping_and_pushing_state) * cpu_count * 2 );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
(stpps+loop)->ss = ss;
lfds611_stack_new( &(stpps+loop)->local_ss, 100000 );
@@ -350,8 +348,7 @@ void stack_test_internal_popping_and_pushing( void )
thread_handles = malloc( sizeof(thread_state_t) * cpu_count * 2 );
for( loop = 0 ; loop < cpu_count ; loop++ )
{
for( loop = 0 ; loop < cpu_count ; loop++ ) {
abstraction_thread_start( &thread_handles[loop], loop, stack_test_internal_thread_popping_and_pushing_start_popping, stpps+loop );
abstraction_thread_start( &thread_handles[loop+cpu_count], loop, stack_test_internal_thread_popping_and_pushing_start_pushing, stpps+loop+cpu_count );
}
@@ -387,16 +384,16 @@ void stack_test_internal_popping_and_pushing( void )
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushing_start_popping( void *stack_test_popping_and_pushing_state )
{
struct stack_test_popping_and_pushing_state
*stpps;
*stpps;
void
*user_data;
*user_data;
time_t
start_time;
start_time;
unsigned int
count;
count;
assert( stack_test_popping_and_pushing_state != NULL );
@@ -407,13 +404,11 @@ thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushin
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
count = 0;
while( count < 100000 )
if( lfds611_stack_pop(stpps->ss, &user_data) )
{
if( lfds611_stack_pop(stpps->ss, &user_data) ) {
lfds611_stack_push( stpps->local_ss, user_data );
count++;
}
@@ -434,16 +429,16 @@ thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushin
thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushing_start_pushing( void *stack_test_popping_and_pushing_state )
{
struct stack_test_popping_and_pushing_state
*stpps;
*stpps;
void
*user_data;
*user_data;
time_t
start_time;
start_time;
unsigned int
count;
count;
assert( stack_test_popping_and_pushing_state != NULL );
@@ -454,8 +449,7 @@ thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushin
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
// TRD : return our local stack to the main stack
while( lfds611_stack_pop(stpps->local_ss, &user_data) )
lfds611_stack_push( stpps->ss, user_data );
@@ -463,8 +457,7 @@ thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushin
count = 0;
while( count < 100000 )
if( lfds611_stack_pop(stpps->ss, &user_data) )
{
if( lfds611_stack_pop(stpps->ss, &user_data) ) {
lfds611_stack_push( stpps->local_ss, user_data );
count++;
}
@@ -485,20 +478,20 @@ thread_return_t CALLING_CONVENTION stack_test_internal_thread_popping_and_pushin
void stack_test_internal_rapid_popping_and_pushing( void )
{
unsigned int
loop,
cpu_count;
loop,
cpu_count;
thread_state_t
*thread_handles;
*thread_handles;
struct lfds611_stack_state
*ss;
*ss;
struct lfds611_validation_info
vi;
vi;
enum lfds611_data_structure_validity
dvs[2];
dvs[2];
/* TRD : in these tests there is a fundamental antagonism between
how much checking/memory clean up that we do and the
@@ -563,13 +556,13 @@ void stack_test_internal_rapid_popping_and_pushing( void )
thread_return_t CALLING_CONVENTION stack_test_internal_thread_rapid_popping_and_pushing( void *stack_state )
{
struct lfds611_stack_state
*ss;
*ss;
void
*user_data = NULL;
*user_data = NULL;
time_t
start_time;
start_time;
assert( stack_state != NULL );
@@ -579,8 +572,7 @@ thread_return_t CALLING_CONVENTION stack_test_internal_thread_rapid_popping_and_
time( &start_time );
while( time(NULL) < start_time + 10 )
{
while( time(NULL) < start_time + 10 ) {
lfds611_stack_push( ss, user_data );
lfds611_stack_pop( ss, &user_data );
}
+126 -99
View File
@@ -1,5 +1,5 @@
/*******************************************************************************
OpenAirInterface
OpenAirInterface
Copyright(c) 1999 - 2014 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
@@ -14,15 +14,15 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
@@ -48,11 +48,12 @@
void
list_init (list_t * listP, char *nameP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (nameP) {
strncpy( listP->name, nameP, LIST_NAME_MAX_CHAR );
listP->name[LIST_NAME_MAX_CHAR-1] = 0; // terminate string
}
listP->tail = NULL;
listP->head = NULL;
listP->nb_elements = 0;
@@ -61,7 +62,7 @@ list_init (list_t * listP, char *nameP)
void
list_free (list_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
mem_block_t *le;
while ((le = list_remove_head (listP))) {
@@ -72,7 +73,7 @@ list_free (list_t * listP)
mem_block_t *
list_get_head (list_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
return listP->head;
}
//-----------------------------------------------------------------------------
@@ -84,15 +85,17 @@ list_get_head (list_t * listP)
mem_block_t *
list_remove_head (list_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// access optimisation
mem_block_t *head;
head = listP->head;
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -102,6 +105,7 @@ list_remove_head (list_t * listP)
} else {
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
}
return head;
}
@@ -109,7 +113,7 @@ list_remove_head (list_t * listP)
mem_block_t *
list_remove_element (mem_block_t * elementP, list_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// access optimisation;
mem_block_t *head;
@@ -117,11 +121,13 @@ list_remove_element (mem_block_t * elementP, list_t * listP)
if (elementP != NULL) {
// test head
head = listP->head;
if (listP->head == elementP) {
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -134,9 +140,11 @@ list_remove_element (mem_block_t * elementP, list_t * listP)
if (head->next == elementP) {
head->next = elementP->next;
listP->nb_elements = listP->nb_elements - 1;
if (listP->tail == elementP) {
listP->tail = head;
}
return elementP;
} else {
head = head->next;
@@ -144,6 +152,7 @@ list_remove_element (mem_block_t * elementP, list_t * listP)
}
}
}
return elementP;
}
@@ -156,7 +165,7 @@ list_remove_element (mem_block_t * elementP, list_t * listP)
void
list_add_head (mem_block_t * elementP, list_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// access optimisation;
mem_block_t *head;
@@ -164,6 +173,7 @@ list_add_head (mem_block_t * elementP, list_t * listP)
if (elementP != NULL) {
head = listP->head;
listP->nb_elements = listP->nb_elements + 1;
// almost one element
if (head == NULL) {
listP->head = elementP;
@@ -185,19 +195,21 @@ void
list_add_tail_eurecom (mem_block_t * elementP, list_t * listP)
{
mem_block_t *tail;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (elementP != NULL) {
// access optimisation
listP->nb_elements = listP->nb_elements + 1;
elementP->next = NULL;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = elementP;
} else {
tail->next = elementP;
}
listP->tail = elementP;
} else {
//msg("[CNT_LIST][ERROR] add_cnt_tail() element NULL\n");
@@ -208,7 +220,7 @@ list_add_tail_eurecom (mem_block_t * elementP, list_t * listP)
void
list_add_list (list_t * sublistP, list_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (sublistP) {
if (sublistP->head) {
@@ -216,12 +228,14 @@ list_add_list (list_t * sublistP, list_t * listP)
mem_block_t *tail;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = sublistP->head;
} else {
tail->next = sublistP->head;
}
listP->tail = sublistP->tail;
// clear sublist
sublistP->head = NULL;
@@ -236,7 +250,7 @@ list_add_list (list_t * sublistP, list_t * listP)
void
list_display (list_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
mem_block_t *cursor;
// unsigned short nb_elements = 0;
@@ -244,6 +258,7 @@ list_display (list_t * listP)
// test lists
if (listP) {
cursor = listP->head;
if (cursor) {
// almost one element
//msg ("Display list %s %p", listP->name, listP);
@@ -266,19 +281,20 @@ list_display (list_t * listP)
* val is the new value to be pushed inside the list
* \return
*/
void
push_front(struct list* z, double val) {
void
push_front(struct list* z, double val)
{
struct node* p = (struct node*) malloc(sizeof(struct node));
struct node* p = (struct node*) malloc(sizeof(struct node));
p->next = z->head;
p->val = val;
z->head = p;
p->next = z->head;
p->val = val;
z->head = p;
z->size++;
z->size++;
return;
return;
}
/*! \fn void initialize(struct list* z)
@@ -286,12 +302,13 @@ push_front(struct list* z, double val) {
* \param z is the list
* \return
*/
void
initialize(struct list* z) {
z->head = NULL;
z->size = 0;
void
initialize(struct list* z)
{
z->head = NULL;
z->size = 0;
return;
return;
}
/*! \fn void del(struct list* z)
@@ -299,22 +316,23 @@ initialize(struct list* z) {
* \param z is the list
* \return
*/
void
del(struct list* z) {
struct node* cur;
struct node* x = z->head;
while((x != NULL) && (z->size > 0)) {
cur = x;
x = x->next;
free(cur);
z->size--;
}
void
del(struct list* z)
{
struct node* cur;
struct node* x = z->head;
z->head = NULL;
z->size = 0;
while((x != NULL) && (z->size > 0)) {
cur = x;
x = x->next;
free(cur);
z->size--;
}
return;
z->head = NULL;
z->size = 0;
return;
}
/*! \fn void totable(double* table, struct list* v)
* \brief convert a list structure to a table.
@@ -322,19 +340,20 @@ del(struct list* z) {
* v is the list to be converted
* \return
*/
void
totable(double* table, struct list* v) {
int i = 0;
void
totable(double* table, struct list* v)
{
int i = 0;
struct node* x = v->head;
struct node* x = v->head;
while(x) {
table[i] = x->val;
i++;
x = x->next;
}
while(x) {
table[i] = x->val;
i++;
x = x->next;
}
return;
return;
}
/*! \fn int compare (const void * a, const void * b)
* \brief compare the value of two parameters
@@ -343,64 +362,69 @@ totable(double* table, struct list* v) {
*/
int compare (const void * a, const void * b)
{
double x = *(double*)a;
double y = *(double*)b;
double x = *(double*)a;
double y = *(double*)b;
return ( x > y );
return ( x > y );
}
#else
// push an element to the head of the list
void push_front(struct list* z, double val) {
struct entry* p = (struct entry*) malloc(sizeof(struct entry));
p->val = val;
void push_front(struct list* z, double val)
{
struct entry* p = (struct entry*) malloc(sizeof(struct entry));
p->val = val;
LIST_INSERT_HEAD(&z->head, p, entries);
z->size++;
LIST_INSERT_HEAD(&z->head, p, entries);
z->size++;
return;
return;
}
// initialization
void initialize(struct list* z) {
LIST_INIT(&z->head);
z->size = 0;
// initialization
void initialize(struct list* z)
{
LIST_INIT(&z->head);
z->size = 0;
return;
return;
}
// delete
void del(struct list* z) {
while (z->head.lh_first != NULL) {
free(z->head.lh_first);
LIST_REMOVE(z->head.lh_first, entries);
}
z->size = 0;
void del(struct list* z)
{
while (z->head.lh_first != NULL) {
free(z->head.lh_first);
LIST_REMOVE(z->head.lh_first, entries);
}
return;
z->size = 0;
return;
}
// convert the list to a table
void totable(double* table, struct list* v) {
int i = 0;
void totable(double* table, struct list* v)
{
int i = 0;
struct entry* x;
struct entry* x;
for (x = v->head.lh_first; x != NULL; x = x->entries.le_next) {
table[i] = x->val;
i++;
}
for (x = v->head.lh_first; x != NULL; x = x->entries.le_next) {
table[i] = x->val;
i++;
}
return;
return;
}
int compare (const void * a, const void * b)
{
double x = *(double*)a;
double y = *(double*)b;
double x = *(double*)a;
double y = *(double*)b;
return ( x > y );
return ( x > y );
}
#endif
@@ -409,18 +433,21 @@ int compare (const void * a, const void * b)
* \param loc_list is the list
* \return the median value
*/
int32_t calculate_median(struct list *loc_list) {
int32_t median = 0;
if (loc_list->size > 0) {
double* table = (double*) malloc(loc_list->size * sizeof(double));
totable(table, loc_list);
/// sort the table in ascending way
qsort (table, loc_list->size, sizeof(double), &compare);
/// median is the value at middle the sorted table
/// Q1 is the value at 1/4 the sorted table
/// Q3 is the value at 3/4 the sorted table
median = table[loc_list->size/2];
free(table);
}
return median;
int32_t calculate_median(struct list *loc_list)
{
int32_t median = 0;
if (loc_list->size > 0) {
double* table = (double*) malloc(loc_list->size * sizeof(double));
totable(table, loc_list);
/// sort the table in ascending way
qsort (table, loc_list->size, sizeof(double), &compare);
/// median is the value at middle the sorted table
/// Q1 is the value at 1/4 the sorted table
/// Q3 is the value at 3/4 the sorted table
median = table[loc_list->size/2];
free(table);
}
return median;
}
+14 -14
View File
@@ -78,33 +78,33 @@ public_list2( void list2_add_head (mem_block_t* , list2_t* );)
public_list2( void list2_add_tail (mem_block_t* , list2_t* );)
public_list2( void list2_add_list (list2_t* , list2_t* );)
public_list2( void list2_display (list2_t* );)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
/* The following lists are used for sorting numbers */
#ifndef LINUX_LIST
/*! \brief the node structure */
#ifndef LINUX_LIST
/*! \brief the node structure */
struct node {
struct node* next; /*!< \brief is a node pointer */
double val; /*!< \brief is a the value of a node pointer*/
struct node* next; /*!< \brief is a node pointer */
double val; /*!< \brief is a the value of a node pointer*/
};
//-----------------------------------------------------------------------------
/*! \brief the list structure */
/*! \brief the list structure */
struct list {
struct node* head; /*!< \brief is a node pointer */
ssize_t size; /*!< \brief is the list size*/
};
struct node* head; /*!< \brief is a node pointer */
ssize_t size; /*!< \brief is the list size*/
};
#else
//-----------------------------------------------------------------------------
struct entry {
double val;
LIST_ENTRY(entry) entries;
double val;
LIST_ENTRY(entry) entries;
};
//-----------------------------------------------------------------------------
struct list {
LIST_HEAD(listhead, entry) head;
ssize_t size;
LIST_HEAD(listhead, entry) head;
ssize_t size;
};
#endif
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
public_list2( void push_front (struct list*, double); )
public_list2( void initialize (struct list*); )
public_list2( void del (struct list*); )
+56 -39
View File
@@ -34,11 +34,12 @@
void
list2_init (list2_t * listP, char *nameP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (nameP) {
strncpy( listP->name, nameP, LIST_NAME_MAX_CHAR );
listP->name[LIST_NAME_MAX_CHAR-1] = 0; // terminate string
strncpy( listP->name, nameP, LIST_NAME_MAX_CHAR );
listP->name[LIST_NAME_MAX_CHAR-1] = 0; // terminate string
}
listP->tail = NULL;
listP->head = NULL;
listP->nb_elements = 0;
@@ -48,7 +49,7 @@ list2_init (list2_t * listP, char *nameP)
void
list2_free (list2_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
mem_block_t *le;
@@ -67,18 +68,20 @@ list2_free (list2_t * listP)
mem_block_t *
list2_remove_element (mem_block_t * elementP, list2_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (elementP != NULL) {
// head of list
if (elementP == listP->head) {
listP->head = elementP->next;
if (listP->head == NULL) {
listP->tail = NULL;
} else {
elementP->next->previous = NULL;
elementP->next = NULL;
}
// tail of the list
// note : case of 1 remaining element in the list has been treated above
} else if (elementP == listP->tail) {
@@ -94,15 +97,17 @@ list2_remove_element (mem_block_t * elementP, list2_t * listP)
elementP->next = NULL;
elementP->previous = NULL;
}
listP->nb_elements = listP->nb_elements - 1;
}
return elementP;
}
//-----------------------------------------------------------------------------
mem_block_t *
list2_get_head (list2_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
return listP->head;
}
@@ -110,7 +115,7 @@ list2_get_head (list2_t * listP)
mem_block_t *
list2_get_tail (list2_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
return listP->tail;
}
@@ -123,16 +128,18 @@ list2_get_tail (list2_t * listP)
mem_block_t *
list2_remove_head (list2_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// access optimisation
mem_block_t *head;
head = listP->head;
// almost one element
if (head != NULL) {
listP->head = head->next;
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update tail
if (listP->head == NULL) {
listP->tail = NULL;
@@ -143,6 +150,7 @@ list2_remove_head (list2_t * listP)
} else {
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
}
return head;
}
@@ -155,16 +163,18 @@ list2_remove_head (list2_t * listP)
mem_block_t *
list2_remove_tail (list2_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// access optimisation;
mem_block_t *tail;
tail = listP->tail;
// almost one element;
if (tail != NULL) {
listP->nb_elements = listP->nb_elements - 1;
// if only one element, update head, tail;
if (listP->head == tail) {
listP->head = NULL;
@@ -173,10 +183,12 @@ list2_remove_tail (list2_t * listP)
listP->tail = tail->previous;
tail->previous->next = NULL;
}
tail->previous = NULL;
} else {
//msg("[MEM_MGT][WARNING] remove_head_from_list(%s) no elements\n",listP->name);
}
return tail;
}
@@ -189,7 +201,7 @@ list2_remove_tail (list2_t * listP)
void
list2_add_head (mem_block_t * elementP, list2_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// access optimisation;
mem_block_t *head;
@@ -197,6 +209,7 @@ list2_add_head (mem_block_t * elementP, list2_t * listP)
if (elementP != NULL) {
head = listP->head;
listP->nb_elements = listP->nb_elements + 1;
// almost one element
if (head == NULL) {
listP->head = elementP;
@@ -220,13 +233,14 @@ void
list2_add_tail (mem_block_t * elementP, list2_t * listP)
{
mem_block_t *tail;
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (elementP != NULL) {
// access optimisation
listP->nb_elements = listP->nb_elements + 1;
elementP->next = NULL;
tail = listP->tail;
// almost one element
if (tail == NULL) {
elementP->previous = NULL;
@@ -235,6 +249,7 @@ list2_add_tail (mem_block_t * elementP, list2_t * listP)
tail->next = elementP;
elementP->previous = tail;
}
listP->tail = elementP;
}
}
@@ -243,7 +258,7 @@ list2_add_tail (mem_block_t * elementP, list2_t * listP)
void
list2_add_list (list2_t * sublistP, list2_t * listP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (sublistP) {
if (sublistP->head) {
@@ -251,6 +266,7 @@ list2_add_list (list2_t * sublistP, list2_t * listP)
mem_block_t *tail;
tail = listP->tail;
// almost one element
if (tail == NULL) {
listP->head = sublistP->head;
@@ -258,6 +274,7 @@ list2_add_list (list2_t * sublistP, list2_t * listP)
tail->next = sublistP->head;
sublistP->head->previous = tail;
}
listP->tail = sublistP->tail;
// clear sublist
sublistP->head = NULL;
@@ -272,33 +289,33 @@ list2_add_list (list2_t * sublistP, list2_t * listP)
void
list2_display (list2_t * listP)
{
//-----------------------------------------------------------------------------
/*
mem_block_t *cursor;
unsigned short nb_elements = 0;
//uint32_t nb_bytes;
// uint32_t index;
//-----------------------------------------------------------------------------
/*
mem_block_t *cursor;
unsigned short nb_elements = 0;
//uint32_t nb_bytes;
// uint32_t index;
// test lists
if (listP) {
cursor = listP->head;
if (cursor) {
// almost one element
msg ("Display list %s %p", listP->name, listP);
while (cursor != NULL) {
msg ("%d:", cursor->pool_id);
//nb_bytes = (( sdu_management*)(cursor->misc))->size;
// for (index=0; index < nb_bytes; index++) {
// msg("%02X.",cursor->data[index]);
// }
msg ("\n");
cursor = cursor->next;
nb_elements++;
// test lists
if (listP) {
cursor = listP->head;
if (cursor) {
// almost one element
msg ("Display list %s %p", listP->name, listP);
while (cursor != NULL) {
msg ("%d:", cursor->pool_id);
//nb_bytes = (( sdu_management*)(cursor->misc))->size;
// for (index=0; index < nb_bytes; index++) {
// msg("%02X.",cursor->data[index]);
// }
msg ("\n");
cursor = cursor->next;
nb_elements++;
}
msg (" found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
#ifdef USER_MODE
AssertFatal(nb_elements == listP->nb_elements, "Bad count of elements %d != %d", nb_elements, listP->nb_elements);
#endif
}
msg (" found nb_elements %d nb_elements %d\n", nb_elements, listP->nb_elements);
#ifdef USER_MODE
AssertFatal(nb_elements == listP->nb_elements, "Bad count of elements %d != %d", nb_elements, listP->nb_elements);
#endif
}
}*/
}*/
}
+3 -3
View File
@@ -10,12 +10,12 @@ The VCD file generated is called openair_vcd_dump.vcd and is located in the exec
Usage:
1) To dump function usage:
vcd_signal_dumper_dump_function_by_name(FUNCTION_NAME, VCD_FUNCTION_IN); at start of function
vcd_signal_dumper_dump_function_by_name(FUNCTION_NAME, VCD_FUNCTION_OUT); at end of function
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(FUNCTION_NAME, VCD_FUNCTION_IN); at start of function
VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(FUNCTION_NAME, VCD_FUNCTION_OUT); at end of function
FUNCTION_NAME should be defined in the enum in vcd_signal_dumper.h and the function name should be addded at the right place in the vcd_signal_dumper.c file.
2) To dump a variable:
vcd_signal_dumper_dump_variable_by_name(VARIABLE_NAME, value); where VARIABLE_NAME is defined as described above for functions and value is the state of the variable at log time.
VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(VARIABLE_NAME, value); where VARIABLE_NAME is defined as described above for functions and value is the state of the variable at log time.
TODO list:
- Add support for signed variables
+1136 -799
View File
File diff suppressed because it is too large Load Diff
+91 -87
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -85,37 +85,37 @@ extern "C" {
* @brief LOG defines 9 levels of messages for users. Importance of these levels decrease gradually from 0 to 8
* @{*/
#ifndef LOG_EMERG
# define LOG_EMERG 0 /*!< \brief system is unusable */
# define LOG_EMERG 0 /*!< \brief system is unusable */
#endif
#ifndef LOG_ALERT
# define LOG_ALERT 1 /*!< \brief action must be taken immediately */
# define LOG_ALERT 1 /*!< \brief action must be taken immediately */
#endif
#ifndef LOG_CRIT
# define LOG_CRIT 2 /*!< \brief critical conditions */
# define LOG_CRIT 2 /*!< \brief critical conditions */
#endif
#ifndef LOG_ERR
# define LOG_ERR 3 /*!< \brief error conditions */
# define LOG_ERR 3 /*!< \brief error conditions */
#endif
#ifndef LOG_WARNING
# define LOG_WARNING 4 /*!< \brief warning conditions */
# define LOG_WARNING 4 /*!< \brief warning conditions */
#endif
#ifndef LOG_NOTICE
# define LOG_NOTICE 5 /*!< \brief normal but significant condition */
# define LOG_NOTICE 5 /*!< \brief normal but significant condition */
#endif
#ifndef LOG_INFO
# define LOG_INFO 6 /*!< \brief informational */
# define LOG_INFO 6 /*!< \brief informational */
#endif
#ifndef LOG_DEBUG
# define LOG_DEBUG 7 /*!< \brief debug-level messages */
# define LOG_DEBUG 7 /*!< \brief debug-level messages */
#endif
#ifndef LOG_FILE
# define LOG_FILE 8 /*!< \brief message sequence chart -level */
# define LOG_FILE 8 /*!< \brief message sequence chart -level */
#endif
#ifndef LOG_TRACE
# define LOG_TRACE 9 /*!< \brief trace-level messages */
# define LOG_TRACE 9 /*!< \brief trace-level messages */
#endif
#define NUM_LOG_LEVEL 10 /*!< \brief the number of message levels users have with LOG */
#define NUM_LOG_LEVEL 10 /*!< \brief the number of message levels users have with LOG */
/* @}*/
@@ -124,7 +124,7 @@ extern "C" {
* @brief Macro used to call tr_log_full_ex with file, function and line information
* @{*/
#ifdef USER_MODE
//#define logIt(component, level, format, args...) do {logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args);} while(0);
//#define logIt(component, level, format, args...) do {logRecord(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args);} while(0);
#ifdef LOG_NO_THREAD
#define logIt(component, level, format, args...) logRecord_mt(__FILE__, __FUNCTION__, __LINE__, component, level, format, ##args)
#else //default
@@ -175,9 +175,9 @@ extern "C" {
* @ingroup _macro
* @brief Macro of some useful functions defined by LOG
* @{*/
#define LOG_ENTER(c) do {LOG_T(c, "Entering\n");}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */
#define LOG_EXIT(c) do {LOG_T(c,"Exiting\n"); return;}while(0) /*!< \brief Macro to log a message with severity TRACE when exiting a function */
#define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */
#define LOG_ENTER(c) do {LOG_T(c, "Entering\n");}while(0) /*!< \brief Macro to log a message with severity DEBUG when entering a function */
#define LOG_EXIT(c) do {LOG_T(c,"Exiting\n"); return;}while(0) /*!< \brief Macro to log a message with severity TRACE when exiting a function */
#define LOG_RETURN(c,x) do {uint32_t __rv;__rv=(unsigned int)(x);LOG_T(c,"Returning %08x\n", __rv);return((typeof(x))__rv);}while(0) /*!< \brief Macro to log a function exit, including integer value, then to return a value to the calling function */
/* @}*/
@@ -189,12 +189,12 @@ extern "C" {
/* .log_format = 0x13 uncolored standard messages
* .log_format = 0x93 colored standard messages */
#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */
#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */
#define LOG_RED "\033[1;31m" /*!< \brief VT100 sequence for bold red foreground */
#define LOG_GREEN "\033[32m" /*!< \brief VT100 sequence for green foreground */
#define LOG_ORANGE "\033[93m" /*!< \brief VT100 sequence for orange foreground */
#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */
#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */
#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */
#define LOG_BLUE "\033[34m" /*!< \brief VT100 sequence for blue foreground */
#define LOG_CYBL "\033[40;36m" /*!< \brief VT100 sequence for cyan foreground on black background */
#define LOG_RESET "\033[0m" /*!< \brief VT100 sequence for reset (black) foreground */
/* @}*/
@@ -205,10 +205,10 @@ extern "C" {
#define LOG_LOCAL 0x01
#define LOG_REMOTE 0x02
#define FLAG_COLOR 0x001 /*!< \brief defaults */
#define FLAG_PID 0x002 /*!< \brief defaults */
#define FLAG_COLOR 0x001 /*!< \brief defaults */
#define FLAG_PID 0x002 /*!< \brief defaults */
#define FLAG_COMP 0x004
#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */
#define FLAG_THREAD 0x008 /*!< \brief all : 255/511 */
#define FLAG_LEVEL 0x010
#define FLAG_FUNCT 0x020
#define FLAG_FILE_LINE 0x040
@@ -220,84 +220,87 @@ extern "C" {
#define LOG_HIGH 0x35
#define LOG_FULL 0x75
#define OAI_OK 0 /*!< \brief all ok */
#define OAI_ERR 1 /*!< \brief generic error */
#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */
#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */
#define OAI_OK 0 /*!< \brief all ok */
#define OAI_ERR 1 /*!< \brief generic error */
#define OAI_ERR_READ_ONLY 2 /*!< \brief tried to write to read-only item */
#define OAI_ERR_NOTFOUND 3 /*!< \brief something wasn't found */
/* @}*/
//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */
//static char *log_level_highlight_start[] = {LOG_RED, LOG_RED, LOG_RED, LOG_RED, LOG_BLUE, "", "", "", LOG_GREEN}; /*!< \brief Optional start-format strings for highlighting */
//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
//static char *log_level_highlight_end[] = {LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, LOG_RESET, "", "", "", LOG_RESET}; /*!< \brief Optional end-format strings for highlighting */
typedef enum {
MIN_LOG_COMPONENTS = 0,
PHY = MIN_LOG_COMPONENTS,
MAC,
EMU,
OCG,
OMG,
OPT,
OTG,
OTG_LATENCY,
OTG_LATENCY_BG,
OTG_GP,
OTG_GP_BG,
OTG_JITTER,
RLC,
PDCP,
RRC,
NAS,
PERF,
OIP,
CLI,
MSC,
OCM,
UDP_,
GTPU,
SPGW,
S1AP,
SCTP,
HW,
OSA,
RAL_ENB,
RAL_UE,
ENB_APP,
TMR,
USIM,
LOCALIZE,
MAX_LOG_COMPONENTS,
} comp_name_t;
MIN_LOG_COMPONENTS = 0,
PHY = MIN_LOG_COMPONENTS,
MAC,
EMU,
OCG,
OMG,
OPT,
OTG,
OTG_LATENCY,
OTG_LATENCY_BG,
OTG_GP,
OTG_GP_BG,
OTG_JITTER,
RLC,
PDCP,
RRC,
NAS,
PERF,
OIP,
CLI,
MSC,
OCM,
UDP_,
GTPU,
SPGW,
S1AP,
SCTP,
HW,
OSA,
RAL_ENB,
RAL_UE,
ENB_APP,
TMR,
USIM,
LOCALIZE,
RRH,
X2AP,
MAX_LOG_COMPONENTS,
}
comp_name_t;
//#define msg printf
//#define msg printf
typedef struct {
char *name; /*!< \brief string name of item */
int value; /*!< \brief integer value of mapping */
char *name; /*!< \brief string name of item */
int value; /*!< \brief integer value of mapping */
} mapping;
typedef struct {
const char *name;
int level;
int flag;
int interval;
int fd;
int filelog;
char *filelog_name;
const char *name;
int level;
int flag;
int interval;
int fd;
int filelog;
char *filelog_name;
/* SR: make the log buffer component relative */
char log_buffer[MAX_LOG_TOTAL];
}log_component_t;
/* SR: make the log buffer component relative */
char log_buffer[MAX_LOG_TOTAL];
} log_component_t;
typedef struct {
unsigned int remote_ip;
unsigned int audit_ip;
int remote_level;
int facility;
int audit_facility;
int format;
unsigned int remote_ip;
unsigned int audit_ip;
int remote_level;
int facility;
int audit_facility;
int format;
} log_config_t;
@@ -319,7 +322,7 @@ typedef struct LOG_params {
int line;
int comp;
int level;
char *format;
const char *format;
char l_buff_info [MAX_LOG_INFO];
int len;
} LOG_params;
@@ -334,6 +337,7 @@ typedef enum log_instance_type_e {
void log_set_instance_type (log_instance_type_t instance);
#endif
int logInit (void);
/*--- INCLUDES ---------------------------------------------------------------*/
# include "log_if.h"
+2 -2
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -38,5 +38,5 @@ extern pthread_cond_t log_notify;
extern int log_shutdown;
#endif
extern mapping log_level_names[];
extern mapping log_level_names[];
extern mapping log_verbosity_names[];
+3 -3
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -68,8 +68,8 @@ extern "C" {
//public_log_if( log_t *g_log;)
public_log_if( int logInit (void);)
public_log_if( void logRecord_mt(const char *file, const char *func, int line,int comp, int level, char *format, ...);)
public_log_if( void logRecord(const char *file, const char *func, int line,int comp, int level, char *format, ...);)
public_log_if( void logRecord_mt(const char *file, const char *func, int line,int comp, int level, const char *format, ...);)
public_log_if( void logRecord(const char *file, const char *func, int line,int comp, int level, const char *format, ...);)
public_log_if( int set_comp_log(int component, int level, int verbosity, int interval);)
public_log_if( int set_log(int component, int level, int interval);)
public_log_if( void set_glog(int level, int verbosity);)
File diff suppressed because it is too large Load Diff
+104 -62
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -32,7 +32,7 @@
* \author ROUX Sebastien
* \author S. Roux
* \maintainer: navid nikaein
* \date 2012 - 2104
* \date 2012 - 2104
* \version 0.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
@@ -46,38 +46,54 @@
//#define ENABLE_USE_CPU_EXECUTION_TIME
/* WARNING: if you edit the enums below, update also string definitions in vcd_signal_dumper.c */
typedef enum
{
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB = 0,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX,
VCD_SIGNAL_DUMPER_VARIABLES_UE_OFFSET_MBOX,
VCD_SIGNAL_DUMPER_VARIABLES_UE_RX_OFFSET,
VCD_SIGNAL_DUMPER_VARIABLES_DIFF,
VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME,
VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME,
VCD_SIGNAL_DUMPER_VARIABLES_TXCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RXCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_ALLOC_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC,
VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE,
VCD_SIGNAL_DUMPER_VARIABLES_LAST,
VCD_SIGNAL_DUMPER_VARIABLES_END = VCD_SIGNAL_DUMPER_VARIABLES_LAST,
typedef enum {
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_ENB = 0,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_TX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_RUNTIME_RX_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_TX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_FRAME_NUMBER_RX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_TX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SLOT_NUMBER_RX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_TX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_SUBFRAME_NUMBER_RX_UE,
VCD_SIGNAL_DUMPER_VARIABLES_MISSED_SLOTS_ENB,
VCD_SIGNAL_DUMPER_VARIABLES_DAQ_MBOX,
VCD_SIGNAL_DUMPER_VARIABLES_UE_OFFSET_MBOX,
VCD_SIGNAL_DUMPER_VARIABLES_UE_RX_OFFSET,
VCD_SIGNAL_DUMPER_VARIABLES_DIFF,
VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME,
VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME,
VCD_SIGNAL_DUMPER_VARIABLES_HW_SUBFRAME_RX,
VCD_SIGNAL_DUMPER_VARIABLES_HW_FRAME_RX,
VCD_SIGNAL_DUMPER_VARIABLES_TXCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RXCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_TRX_TST,
VCD_SIGNAL_DUMPER_VARIABLES_TX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_RX_TS,
VCD_SIGNAL_DUMPER_VARIABLES_RX_HWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RX_LHWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TX_HWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_TX_LHWCNT,
VCD_SIGNAL_DUMPER_VARIABLES_RX_PCK,
VCD_SIGNAL_DUMPER_VARIABLES_TX_PCK,
VCD_SIGNAL_DUMPER_VARIABLES_CNT,
VCD_SIGNAL_DUMPER_VARIABLES_DUMMY_DUMP,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_SEND_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_POLL_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_RECV_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_ITTI_ALLOC_MSG,
VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC,
VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE,
VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_RX,
VCD_SIGNAL_DUMPER_VARIABLES_UE_INST_CNT_TX,
VCD_SIGNAL_DUMPER_VARIABLES_LAST,
VCD_SIGNAL_DUMPER_VARIABLES_END = VCD_SIGNAL_DUMPER_VARIABLES_LAST,
} vcd_signal_dump_variables;
typedef enum {
/* softmodem signals */
/* softmodem signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_RT_SLEEP=0,
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ,
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE,
@@ -101,8 +117,21 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX8,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_TX9,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_RX9,
/* PHY signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_THREAD_RX,
/* RRH signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TRX,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TM,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_RX_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_TX_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_eNB_PROC_SLEEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_READ_RF,
VCD_SIGNAL_DUMPER_FUNCTIONS_TRX_WRITE_RF,
/* PHY signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SYNCH,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SLOT_FEP,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_RRC_MEASUREMENTS,
@@ -154,10 +183,10 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_MODULATION,
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ENCODING,
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_SCRAMBLING,
/* MAC signals */
/* MAC signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_MACPHY_INIT,
VCD_SIGNAL_DUMPER_FUNCTIONS_MACPHY_EXIT,
VCD_SIGNAL_DUMPER_FUNCTIONS_MACPHY_EXIT,
VCD_SIGNAL_DUMPER_FUNCTIONS_ENB_DLSCH_ULSCH_SCHEDULER,
VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_RAR,
VCD_SIGNAL_DUMPER_FUNCTIONS_TERMINATE_RA_PROC,
@@ -168,10 +197,10 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_RX_SDU,
VCD_SIGNAL_DUMPER_FUNCTIONS_MRBCH_PHY_SYNC_FAILURE,
VCD_SIGNAL_DUMPER_FUNCTIONS_SR_INDICATION,
VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
VCD_SIGNAL_DUMPER_FUNCTIONS_DLSCH_PREPROCESSOR,
VCD_SIGNAL_DUMPER_FUNCTIONS_SCHEDULE_DLSCH, // schedule_ue_spec
VCD_SIGNAL_DUMPER_FUNCTIONS_FILL_DLSCH_DCI,
VCD_SIGNAL_DUMPER_FUNCTIONS_OUT_OF_SYNC_IND,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_SI,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_DECODE_CCCH,
@@ -183,25 +212,26 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SCHEDULER,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_GET_SR,
VCD_SIGNAL_DUMPER_FUNCTIONS_UE_SEND_MCH_SDU,
/* RLC signals */
/* RLC signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_REQ,
// VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_DATA_IND,
VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_STATUS_IND,
VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_STATUS_IND,
VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_REQ,
VCD_SIGNAL_DUMPER_FUNCTIONS_MAC_RLC_DATA_IND,
VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_UM_TRY_REASSEMBLY,
VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_UM_CHECK_TIMER_DAR_TIME_OUT,
VCD_SIGNAL_DUMPER_FUNCTIONS_RLC_UM_RECEIVE_PROCESS_DAR,
/* PDCP signals */
/* PDCP signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_RUN,
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_REQ,
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_DATA_IND,
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_APPLY_SECURITY,
VCD_SIGNAL_DUMPER_FUNCTIONS_PDCP_VALIDATE_SECURITY,
/* RRC signals */
/* RRC signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_RX_TX,
VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_MAC_CONFIG,
VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SIB1,
VCD_SIGNAL_DUMPER_FUNCTIONS_RRC_UE_DECODE_SI,
@@ -214,7 +244,7 @@ typedef enum {
/* UDP signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_UDP_ENB_TASK,
/* MISC signals */
/* MISC signals */
VCD_SIGNAL_DUMPER_FUNCTIONS_EMU_TRANSPORT,
VCD_SIGNAL_DUMPER_FUNCTIONS_LOG_RECORD,
VCD_SIGNAL_DUMPER_FUNCTIONS_ITTI_ENQUEUE_MESSAGE,
@@ -226,27 +256,25 @@ typedef enum {
VCD_SIGNAL_DUMPER_FUNCTIONS_END = VCD_SIGNAL_DUMPER_FUNCTIONS_LAST,
} vcd_signal_dump_functions;
typedef enum
{
VCD_SIGNAL_DUMPER_MODULE_FREE = 0,
typedef enum {
VCD_SIGNAL_DUMPER_MODULE_FREE = 0,
VCD_SIGNAL_DUMPER_MODULE_VARIABLES,
VCD_SIGNAL_DUMPER_MODULE_FUNCTIONS,
// VCD_SIGNAL_DUMPER_MODULE_UE_PROCEDURES_FUNCTIONS,
VCD_SIGNAL_DUMPER_MODULE_LAST,
VCD_SIGNAL_DUMPER_MODULE_END = VCD_SIGNAL_DUMPER_MODULE_LAST,
VCD_SIGNAL_DUMPER_MODULE_VARIABLES,
VCD_SIGNAL_DUMPER_MODULE_FUNCTIONS,
// VCD_SIGNAL_DUMPER_MODULE_UE_PROCEDURES_FUNCTIONS,
VCD_SIGNAL_DUMPER_MODULE_LAST,
VCD_SIGNAL_DUMPER_MODULE_END = VCD_SIGNAL_DUMPER_MODULE_LAST,
} vcd_signal_dumper_modules;
typedef enum
{
VCD_FUNCTION_OUT,
VCD_FUNCTION_IN,
VCD_FUNCTION_LAST,
typedef enum {
VCD_FUNCTION_OUT,
VCD_FUNCTION_IN,
VCD_FUNCTION_LAST,
} vcd_signal_dump_in_out;
typedef enum {
VCD_REAL, // REAL = variable
VCD_WIRE, // WIRE = Function
VCD_REAL, // REAL = variable
VCD_WIRE, // WIRE = Function
} vcd_signal_type;
/*!
@@ -270,16 +298,30 @@ void vcd_signal_dumper_create_header(void);
* @param Value of the variable to dump (type: unsigned long)
*/
void vcd_signal_dumper_dump_variable_by_name(vcd_signal_dump_variables variable_name,
unsigned long value);
unsigned long value);
/*!
* \brief Dump function usage
* @param Name Function name to dump (see the corresponding enum)
* @param State: either VCD_FUNCTION_START or VCD_FUNCTION_END
*/
void vcd_signal_dumper_dump_function_by_name(vcd_signal_dump_functions function_name,
vcd_signal_dump_in_out function_in_out);
vcd_signal_dump_in_out function_in_out);
extern int ouput_vcd;
#if defined(ENABLE_VCD)
#define VCD_SIGNAL_DUMPER_INIT(aRgUmEnT) vcd_signal_dumper_init(aRgUmEnT)
#define VCD_SIGNAL_DUMPER_CLOSE() vcd_signal_dumper_close()
#define VCD_SIGNAL_DUMPER_CREATE_HEADER() vcd_signal_dumper_create_header()
#define VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(vAr1,vAr2) vcd_signal_dumper_dump_variable_by_name(vAr1,vAr2)
#define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(vAr1,vAr2) vcd_signal_dumper_dump_function_by_name(vAr1,vAr2)
#else
#define VCD_SIGNAL_DUMPER_INIT(aRgUmEnT)
#define VCD_SIGNAL_DUMPER_CLOSE()
#define VCD_SIGNAL_DUMPER_CREATE_HEADER()
#define VCD_SIGNAL_DUMPER_DUMP_VARIABLE_BY_NAME(vAr1,vAr2)
#define VCD_SIGNAL_DUMPER_DUMP_FUNCTION_BY_NAME(vAr1,vAr2)
#endif
#endif /* !defined (VCD_SIGNAL_DUMPER_H_) */
+30 -13
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -56,16 +56,20 @@ static unsigned int
crcbit (unsigned char * inputptr, int octetlen, unsigned int poly)
{
unsigned int i, crc = 0, c;
while (octetlen-- > 0) {
c = (*inputptr++) << 24;
for (i = 8; i != 0; i--) {
if ((1 << 31) & (c ^ crc))
crc = (crc << 1) ^ poly;
else
crc <<= 1;
c <<= 1;
}
}
return crc;
}
@@ -82,6 +86,7 @@ void
crcTableInit ()
{
unsigned char c = 0;
do {
crc24Table[c] = crcbit (&c, 1, poly24);
crc16Table[c] = (unsigned short) (crcbit (&c, 1, poly16) >> 16);
@@ -104,11 +109,14 @@ crc24 (unsigned char * inptr, int bitlen)
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
crc = (crc << 8) ^ crc24Table[(*inptr++) ^ (crc >> 24)];
}
if (resbit > 0)
crc = (crc << resbit) ^ crc24Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))];
return crc;
}
@@ -119,11 +127,14 @@ crc16 (unsigned char * inptr, int bitlen)
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
crc = (crc << 8) ^ (crc16Table[(*inptr++) ^ (crc >> 24)] << 16);
}
if (resbit > 0)
crc = (crc << resbit) ^ (crc16Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);
return crc;
}
@@ -134,11 +145,14 @@ crc12 (unsigned char * inptr, int bitlen)
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
crc = (crc << 8) ^ (crc12Table[(*inptr++) ^ (crc >> 24)] << 16);
}
if (resbit > 0)
crc = (crc << resbit) ^ (crc12Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 16);
return crc;
}
@@ -149,11 +163,14 @@ crc8 (unsigned char * inptr, int bitlen)
unsigned int crc = 0;
octetlen = bitlen / 8; /* Change in octets */
resbit = (bitlen % 8);
while (octetlen-- > 0) {
crc = crc8Table[(*inptr++) ^ (crc >> 24)] << 24;
}
if (resbit > 0)
crc = (crc << resbit) ^ (crc8Table[((*inptr) >> (8 - resbit)) ^ (crc >> (32 - resbit))] << 24);
return crc;
}
@@ -162,15 +179,15 @@ crc8 (unsigned char * inptr, int bitlen)
Test code
********************************************************************/
/* #ifdef MAIN
#include <stdio.h>
main()
{
unsigned char test[] = "Thebigredfox";
crcTableInit();
printf("%x\n", crcbit(test, sizeof(test) - 1, poly24));
printf("%x\n", crc24(test, (sizeof(test) - 1)*8));
printf("%x\n", crcbit(test, sizeof(test) - 1, poly8));
printf("%x\n", crc8(test, (sizeof(test) - 1)*8));
}
#endif */
/* #ifdef MAIN
#include <stdio.h>
main()
{
unsigned char test[] = "Thebigredfox";
crcTableInit();
printf("%x\n", crcbit(test, sizeof(test) - 1, poly24));
printf("%x\n", crc24(test, (sizeof(test) - 1)*8));
printf("%x\n", crcbit(test, sizeof(test) - 1, poly8));
printf("%x\n", crc8(test, (sizeof(test) - 1)*8));
}
#endif */
+148 -120
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -49,18 +49,20 @@
static int x, y, z;
void init_seeds(int seed){
void init_seeds(int seed)
{
set_taus_seed(seed);
LOG_I(OTG,"set taus seed to %d done \n", seed);
}
double uniform_rng() {
double uniform_rng()
{
double random;
random = (double)(taus(OTG)%0xffffffff)/((double)0xffffffff);
//LOG_D(OTG,"Uniform taus random number= %lf\n", random);
return random;
return random;
}
@@ -70,170 +72,196 @@ return random;
// Uniform Distribution using the Uniform_Random_Number_Generator
double uniform_dist(int min, int max) {
double uniform_dist(int min, int max)
{
double uniform_rn;
uniform_rn = (max - min) * uniform_rng() + min;
// LOG_T(OTG,"Uniform Random Nb = %lf, (min %d, max %d)\n", uniform_rn, min, max);
//printf("Uniform Random Nb = %lf, (min %d, max %d)\n", uniform_rn, min, max);
// LOG_T(OTG,"Uniform Random Nb = %lf, (min %d, max %d)\n", uniform_rn, min, max);
//printf("Uniform Random Nb = %lf, (min %d, max %d)\n", uniform_rn, min, max);
return uniform_rn;
}
// Gaussian Distribution using Box-Muller Transformation
double gaussian_dist(double mean, double std_dev) {
double x_rand1,x_rand2, w, gaussian_rn_1;
double gaussian_dist(double mean, double std_dev)
{
double x_rand1,x_rand2, w, gaussian_rn_1;
do {
do {
x_rand1 = 2.0 * uniform_rng() - 1;
x_rand2 = 2.0 * uniform_rng() - 1;
w = x_rand1 * x_rand1 + x_rand2 * x_rand2;
} while (w >= 1.0);
w = sqrt((-2.0 * log(w)) / w);
gaussian_rn_1 = (std_dev * (x_rand1 * w)) + mean;
} while (gaussian_rn_1 <= 0);
LOG_T(OTG,"Gaussian Random Nb= %lf (mean %lf, deviation %lf)\n", gaussian_rn_1, mean, std_dev);
return gaussian_rn_1;
do {
do {
x_rand1 = 2.0 * uniform_rng() - 1;
x_rand2 = 2.0 * uniform_rng() - 1;
w = x_rand1 * x_rand1 + x_rand2 * x_rand2;
} while (w >= 1.0);
w = sqrt((-2.0 * log(w)) / w);
gaussian_rn_1 = (std_dev * (x_rand1 * w)) + mean;
} while (gaussian_rn_1 <= 0);
LOG_T(OTG,"Gaussian Random Nb= %lf (mean %lf, deviation %lf)\n", gaussian_rn_1, mean, std_dev);
return gaussian_rn_1;
}
// Exponential Distribution using the standard natural logarithmic transformations
double exponential_dist(double lambda) {
double exponential_dist(double lambda)
{
double exponential_rn;
double exponential_rn;
if (log(uniform_rng()) > 0)
exponential_rn = log(uniform_rng()) / lambda;
else
exponential_rn = -log(uniform_rng()) / lambda;
LOG_T(OTG,"Exponential Random Nb = %lf (lambda %lf)\n", exponential_rn, lambda);
return exponential_rn;
if (log(uniform_rng()) > 0)
exponential_rn = log(uniform_rng()) / lambda;
else
exponential_rn = -log(uniform_rng()) / lambda;
LOG_T(OTG,"Exponential Random Nb = %lf (lambda %lf)\n", exponential_rn, lambda);
return exponential_rn;
}
// Poisson Distribution using Knuths Algorithm
double poisson_dist(double lambda){
double poisson_rn, L, p, u;
int k = 0;
p = 1;
L = exp(-lambda);
do {
u = uniform_rng();
p = p * u;
k += 1;
} while (p > L);
poisson_rn = k - 1;
LOG_T(OTG,"Poisson Random Nb = %lf (lambda %lf)\n", poisson_rn, lambda);
return poisson_rn;
double poisson_dist(double lambda)
{
double poisson_rn, L, p, u;
int k = 0;
p = 1;
L = exp(-lambda);
do {
u = uniform_rng();
p = p * u;
k += 1;
} while (p > L);
poisson_rn = k - 1;
LOG_T(OTG,"Poisson Random Nb = %lf (lambda %lf)\n", poisson_rn, lambda);
return poisson_rn;
}
double weibull_dist(double scale, double shape){
double weibull_rn;
double weibull_dist(double scale, double shape)
{
double weibull_rn;
if ((scale<=0)||(shape<=0)){
LOG_W(OTG,"Weibull :: scale=%.2f or shape%.2f <0 , adjust to new values: sale=3, shape=4 \n", scale,shape);
scale=3;
shape=4;
}
weibull_rn=scale * pow(-log(1-uniform_rng()), 1/shape);
LOG_T(OTG,"Weibull Random Nb = %lf (scale=%.2f, shape=%.2f)\n", weibull_rn, scale,shape);
return weibull_rn;
if ((scale<=0)||(shape<=0)) {
LOG_W(OTG,"Weibull :: scale=%.2f or shape%.2f <0 , adjust to new values: sale=3, shape=4 \n", scale,shape);
scale=3;
shape=4;
}
weibull_rn=scale * pow(-log(1-uniform_rng()), 1/shape);
LOG_T(OTG,"Weibull Random Nb = %lf (scale=%.2f, shape=%.2f)\n", weibull_rn, scale,shape);
return weibull_rn;
}
double pareto_dist(double scale, double shape) {
double pareto_rn;
if ((scale<=0)||(shape<=0)){
LOG_W(OTG,"Pareto :: scale=%.2f or shape%.2f <0 , adjust new values: sale=3, shape=4 \n", scale,shape);
scale=3;
shape=4;
}
pareto_rn=scale * pow(1/(1-uniform_rng()), 1/shape);
LOG_T(OTG,"Pareto Random Nb = %lf (scale=%.2f, shape=%.2f)\n", pareto_rn,scale,shape);
return pareto_rn;
double pareto_dist(double scale, double shape)
{
double pareto_rn;
if ((scale<=0)||(shape<=0)) {
LOG_W(OTG,"Pareto :: scale=%.2f or shape%.2f <0 , adjust new values: sale=3, shape=4 \n", scale,shape);
scale=3;
shape=4;
}
pareto_rn=scale * pow(1/(1-uniform_rng()), 1/shape);
LOG_T(OTG,"Pareto Random Nb = %lf (scale=%.2f, shape=%.2f)\n", pareto_rn,scale,shape);
return pareto_rn;
}
double gamma_dist(double scale, double shape) {
double gamma_dist(double scale, double shape)
{
double gamma_rn, mult_var=1;
int i, shape_int;
double gamma_rn, mult_var=1;
int i, shape_int;
shape_int=ceil(shape);
if ((scale<=0)||(shape_int<=0)){
LOG_W(OTG,"Gamma :: scale=%.2f or shape%.2f <0 , adjust to new values: sale=0.5, shape=25 \n", scale,shape);
scale=0.5;
shape=25;
}
for(i=1;i<=shape_int;i++){
mult_var=mult_var*uniform_rng();
}
gamma_rn= (-1/scale)*log(mult_var);
LOG_T(OTG,"Gamma Random Nb = %lf (scale=%.2f, shape=%.2f)\n", gamma_rn, scale, shape);
return gamma_rn;
shape_int=ceil(shape);
if ((scale<=0)||(shape_int<=0)) {
LOG_W(OTG,"Gamma :: scale=%.2f or shape%.2f <0 , adjust to new values: sale=0.5, shape=25 \n", scale,shape);
scale=0.5;
shape=25;
}
for(i=1; i<=shape_int; i++) {
mult_var=mult_var*uniform_rng();
}
gamma_rn= (-1/scale)*log(mult_var);
LOG_T(OTG,"Gamma Random Nb = %lf (scale=%.2f, shape=%.2f)\n", gamma_rn, scale, shape);
return gamma_rn;
}
double cauchy_dist(double scale, double shape ) {
double cauchy_rn;
if ((scale<=0)||(shape<=0)){
LOG_W(OTG,"Cauchy :: scale=%.2f or shape%.2f <0 , new values: sale=2, shape=10 \n", scale,shape);
scale=2;
shape=10;
}
double cauchy_dist(double scale, double shape )
{
double cauchy_rn;
if ((scale<=0)||(shape<=0)) {
LOG_W(OTG,"Cauchy :: scale=%.2f or shape%.2f <0 , new values: sale=2, shape=10 \n", scale,shape);
scale=2;
shape=10;
}
cauchy_rn= scale*tan(PI*(uniform_rng()-0.5)) + shape;
if (cauchy_rn<0){
cauchy_rn=fabs(cauchy_rn);
LOG_T(OTG,"Cauchy Random Nb = %lf <0 (scale=%.2f, shape=%.2f), we use absolute value\n", cauchy_rn, scale, shape);
}
else
LOG_T(OTG,"Cauchy Random Nb = %lf (scale=%.2f, shape=%.2f)\n", cauchy_rn, scale, shape);
return cauchy_rn;
cauchy_rn= scale*tan(PI*(uniform_rng()-0.5)) + shape;
if (cauchy_rn<0) {
cauchy_rn=fabs(cauchy_rn);
LOG_T(OTG,"Cauchy Random Nb = %lf <0 (scale=%.2f, shape=%.2f), we use absolute value\n", cauchy_rn, scale, shape);
} else
LOG_T(OTG,"Cauchy Random Nb = %lf (scale=%.2f, shape=%.2f)\n", cauchy_rn, scale, shape);
return cauchy_rn;
}
double lognormal_dist(double mean, double std_dev){
double lognormal_dist(double mean, double std_dev)
{
double lognormal_rn;
lognormal_rn= exp(gaussian_dist(mean, std_dev));
return lognormal_rn;
return lognormal_rn;
}
double wichman_hill() { // not used
double wichman_hill() // not used
{
double temp, random;
int modx = x % 177;
int mody = y % 176;
int modz = z % 178;
//First Generator
x = (171 * modx) - (2 * modx);
if (x < 0)
x += 30269;
//Second Generator
y = (172 * mody) - (35 * mody);
if (y < 0)
y += 30307;
//Third Generator
z = (170 * modz) - (63 * modz);
if (z < 0)
z += 30323;
temp = (x / 30269.0) + (y / 30307.0) + (z / 30323.0);
random = temp - (int)temp;
double temp, random;
int modx = x % 177;
int mody = y % 176;
int modz = z % 178;
return random;
//First Generator
x = (171 * modx) - (2 * modx);
if (x < 0)
x += 30269;
//Second Generator
y = (172 * mody) - (35 * mody);
if (y < 0)
y += 30307;
//Third Generator
z = (170 * modz) - (63 * modz);
if (z < 0)
z += 30323;
temp = (x / 30269.0) + (y / 30307.0) + (z / 30323.0);
random = temp - (int)temp;
return random;
}
+32 -32
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -53,27 +53,27 @@
/*! \fn void set_taus_seed(unsigned int seed_type);
* \brief initialize seeds used for the generation of taus random values
* \param[in] initial value
* \param[out]
* \note
* \param[out]
* \note
* @ingroup _oml
*/
void set_taus_seed(unsigned int seed_type);
/*! \fn inline unsigned int taus(unsigned int comp);
* \brief compute random number
* \brief compute random number
* \param[in] integer
* \param[out]
* \note
* \param[out]
* \note
* @ingroup _oml
*/
inline unsigned int taus(unsigned int comp);
unsigned int taus(unsigned int comp);
/*! \fn void init_seeds(int seed);
* \brief init values for wichman_hill algo
* \param[in] seed
* \param[out]
* \note
* \param[out]
* \note
* @ingroup _oml
*/
void init_seeds(int seed);
@@ -82,7 +82,7 @@ void init_seeds(int seed);
* \brief generates uniform random number with wichman_hill algo
* \param[in]
* \param[out] random number: wichman_hill
* \note
* \note
* @ingroup _oml
*/
double wichman_hill(void) ;
@@ -90,37 +90,37 @@ double wichman_hill(void) ;
/*! \fn double uniform_rng();
* \brief generates uniform random number with algo: wichman_hill / random() / Taus
* \param[in]
* \param[out] random number
* \note
* \param[out] random number
* \note
* @ingroup _oml
*/
double uniform_rng(void);
/*! \fn double uniform_dist(double min, double max);
* \brief
* \param[in] double min
* \brief
* \param[in] double min
* \param[in] double max
* \param[out] uniform number
* \note
* \note
* @ingroup _oml
*/
double uniform_dist(int min, int max);
/*! \fn double gaussian_dist(double mean, double std_dev);
* \brief
* \brief
* \param[in] double mean
* \param[in] double standard deviation
* \param[in] double standard deviation
* \param[out] exponential gaussian number
* \note
* \note
* @ingroup _oml
*/
double gaussian_dist(double mean, double std_dev);
/*! \fn double exponential_dist(double lambda);
* \brief
* \param[in] double lambda
* \brief
* \param[in] double lambda
* \param[out] exponential random number
* \note
* \note
* @ingroup _oml
*/
@@ -130,13 +130,13 @@ double exponential_dist(double lambda);
* \brief generates random numbers for the poisson distribution
* \param[in] lambda used for poisson distrib configuration
* \param[out] poisson random number
* \note
* \note
* @ingroup _oml
*/
double poisson_dist(double lambda);
/*! \fn double weibull_dist(double scale, double shape);
* \brief generates random numbers for the Weibull distribution with scale parameter, and shape parameter.
* \brief generates random numbers for the Weibull distribution with scale parameter, and shape parameter.
* \param[in] scale parameter, and shape parameter.
* \param[out] weibull random number
* \note Formula (http://www.xycoon.com/wei_random.htm)
@@ -145,8 +145,8 @@ double poisson_dist(double lambda);
double weibull_dist(double scale, double shape);
/*! \fn double pareto_dist(double scale, double shape);
* \brief enerates random numbers for the pareto distribution with scale parameter, and shape parameter.
* \param[in] double scale
* \brief enerates random numbers for the pareto distribution with scale parameter, and shape parameter.
* \param[in] double scale
* \param[in] double shape
* \param[out] pareto random number
* \note Formula (http://www.xycoon.com/par_random.htm)
@@ -155,8 +155,8 @@ double weibull_dist(double scale, double shape);
double pareto_dist(double scale, double shape);
/*! \fn double gamma_dist(double scale, double shape);
* \brief generates random numbers for the gamma distribution with scale parameter, and shape parameter.
* \param[in] double scale
* \brief generates random numbers for the gamma distribution with scale parameter, and shape parameter.
* \param[in] double scale
* \param[in] double shape
* \param[out] gamma random number
* \note Formula (http://www.xycoon.com/gamma_random.htm)
@@ -165,8 +165,8 @@ double pareto_dist(double scale, double shape);
double gamma_dist(double scale, double shape);
/*! \fn double cauchy_dist(double scale, double shape);
* \brief generates random numbers for the cauchy distribution with scale parameter, and shape parameter.
* \param[in] double scale
* \brief generates random numbers for the cauchy distribution with scale parameter, and shape parameter.
* \param[in] double scale
* \param[in] double shape
* \param[out] cauchy random number
* \note Formula(http://www.xycoon.com/nor_relationships3.htm)
@@ -176,8 +176,8 @@ double cauchy_dist(double scale, double shape);
/*! \fn double double lognormal_dist(double mean, double std_dev)
* \brief generates random numbers for the log normal distribution with mean parameter and standard deviation parameter.
* \param[in] double mean
* \brief generates random numbers for the log normal distribution with mean parameter and standard deviation parameter.
* \param[in] double mean
* \param[in] double std_dev
* \param[out] lognormal random number
* \note Formula(http://www.xycoon.com/nor_relationships3.htm)
@@ -187,4 +187,4 @@ double lognormal_dist(double mean, double std_dev);
#endif
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+32 -24
View File
@@ -21,19 +21,19 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file taus.c
* \brief random number generator per OAI component
* \brief random number generator per OAI component
* \author Navid Nikaein
* \date 2011 - 2014
* \version 0.1
* \email navid.nikaein@eurecom.fr
* \warning
* \warning
* @ingroup util
*/
@@ -58,7 +58,8 @@ unsigned int s0[MAX_NUM_COMPS], s1[MAX_NUM_COMPS], s2[MAX_NUM_COMPS], b[MAX_NUM_
inline unsigned int taus(unsigned int comp) {
inline unsigned int taus(unsigned int comp)
{
b[comp] = (((s0[comp] << 13) ^ s0[comp]) >> 19);
s0[comp] = (((s0[comp] & 0xFFFFFFFE) << 12)^ b[comp]);
@@ -66,50 +67,57 @@ inline unsigned int taus(unsigned int comp) {
s1[comp] = (((s1[comp] & 0xFFFFFFF8) << 4)^ b[comp]);
b[comp] = (((s2[comp] << 3) ^ s2[comp]) >> 11);
s2[comp] = (((s2[comp] & 0xFFFFFFF0) << 17)^ b[comp]);
r[comp] = s0[comp] ^ s1[comp] ^ s2[comp];
r[comp] = s0[comp] ^ s1[comp] ^ s2[comp];
return r[comp];
}
void set_taus_seed(unsigned int seed_type) {
unsigned int i; // i index of component
for (i=MIN_NUM_COMPS; i < MAX_NUM_COMPS ; i ++) {
switch (seed_type){
case 0: // use rand func
void set_taus_seed(unsigned int seed_type)
{
unsigned int i; // i index of component
for (i=MIN_NUM_COMPS; i < MAX_NUM_COMPS ; i ++) {
switch (seed_type) {
case 0: // use rand func
if (i == 0) srand(time(NULL));
s0[i] = ((unsigned int)rand());
s1[i] = ((unsigned int)rand());
s2[i] = ((unsigned int)rand());
printf("Initial seeds use rand: s0[%d] = 0x%x, s1[%d] = 0x%x, s2[%d] = 0x%x\n", i, s0[i], i, s1[i], i, s2[i]);
break;
case 1: // use rand with seed
if (i == 0) srand(0x1e23d851);
s0[i] = ((unsigned int)rand());
s1[i] = ((unsigned int)rand());
s2[i] = ((unsigned int)rand());
printf("Initial seeds use rand with seed : s0[%d] = 0x%x, s1[%d] = 0x%x, s2[%d] = 0x%x\n", i, s0[i], i, s1[i], i, s2[i]);
break;
default:
default:
break;
}
}
}
int get_rand (unsigned int comp){
int get_rand (unsigned int comp)
{
if ((comp > MIN_NUM_COMPS) && (comp < MAX_NUM_COMPS))
return r[comp];
else{
else {
//LOG_E(RNG,"unknown component %d\n",comp);
return -1;
}
}
unsigned int dtaus(unsigned int comp, unsigned int a, unsigned b){
unsigned int dtaus(unsigned int comp, unsigned int a, unsigned b)
{
return (int) (((double)taus(comp)/(double)0xffffffff)* (double)(b-a) + (double)a);
}
/*
@@ -122,14 +130,14 @@ main() {
printf("dtaus %d \n",dtaus(PHY, 1000, 1000000));
do {//for (i=0;i<10;i++){
randphy = taus(PHY);
randphy = taus(PHY);
randomg = taus(OTG);
i++;
// printf("rand for OMG (%d,0x%x) PHY (%d,0x%x)\n",OMG, randomg, PHY, randphy);
} while (randphy != randomg);
} while (randphy != randomg);
printf("after %d run: get rand for (OMG 0x%x, PHY 0x%x)\n",i, get_rand(OTG), get_rand(PHY));
}
#endif
#endif
*/
+247 -96
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -44,6 +44,20 @@
#include "list.h"
#include "LAYER2/MAC/extern.h"
/* all function calls are protected by a mutex
* to ensure that many threads calling them at
* the same time don't mess up.
* We might be more clever in the future, it's a
* bit overkill.
* Commenting this define removes the protection,
* so be careful with it.
*/
#define MEMBLOCK_BIG_LOCK
#ifdef MEMBLOCK_BIG_LOCK
static pthread_mutex_t mtex = PTHREAD_MUTEX_INITIALIZER;
#endif
//-----------------------------------------------------------------------------
//#define DEBUG_MEM_MNGT_FREE
//#define DEBUG_MEM_MNGT_ALLOC_SIZE
@@ -57,78 +71,105 @@ uint32_t counters[11] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
* initialize all ures
*/
void *
pool_buffer_init ()
pool_buffer_init (void)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint32_t index, mb_index, pool_index;
mem_pool *memory = (mem_pool *) &mem_block_var;
int pool_sizes[14] = { MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB1_NB_BLOCKS,
MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB7_NB_BLOCKS,
MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB9_NB_BLOCKS,
MEM_MNGT_MB10_NB_BLOCKS, MEM_MNGT_MB11_NB_BLOCKS,
MEM_MNGT_MB12_NB_BLOCKS, MEM_MNGT_MBCOPY_NB_BLOCKS
};
MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB7_NB_BLOCKS,
MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB9_NB_BLOCKS,
MEM_MNGT_MB10_NB_BLOCKS, MEM_MNGT_MB11_NB_BLOCKS,
MEM_MNGT_MB12_NB_BLOCKS, MEM_MNGT_MBCOPY_NB_BLOCKS
};
#ifdef MEMBLOCK_BIG_LOCK
if (pthread_mutex_lock(&mtex)) abort();
#endif
memset (memory, 0, sizeof (mem_pool));
mb_index = 0;
// LG_TEST
for (pool_index = 0; pool_index <= MEM_MNGT_POOL_ID_COPY; pool_index++) {
list_init (&memory->mem_lists[pool_index], "POOL");
for (index = 0; index < pool_sizes[pool_index]; index++) {
//memory->mem_blocks[mb_index + index].previous = NULL; -> done in memset 0
//memory->mem_blocks[mb_index + index].next = NULL; -> done in memset 0
switch (pool_index) {
case 0:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool0[index][0]);
break;
case 1:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool1[index][0]);
break;
case 2:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool2[index][0]);
break;
case 3:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool3[index][0]);
break;
case 4:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool4[index][0]);
break;
case 5:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool5[index][0]);
break;
case 6:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool6[index][0]);
break;
case 7:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool7[index][0]);
break;
case 8:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool8[index][0]);
break;
case 9:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool9[index][0]);
break;
case 10:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool10[index][0]);
break;
case 11:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool11[index][0]);
break;
case 12:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool12[index][0]);
break;
default:;
memory->mem_blocks[mb_index + index].data = NULL; // pool copy
case 0:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool0[index][0]);
break;
case 1:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool1[index][0]);
break;
case 2:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool2[index][0]);
break;
case 3:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool3[index][0]);
break;
case 4:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool4[index][0]);
break;
case 5:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool5[index][0]);
break;
case 6:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool6[index][0]);
break;
case 7:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool7[index][0]);
break;
case 8:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool8[index][0]);
break;
case 9:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool9[index][0]);
break;
case 10:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool10[index][0]);
break;
case 11:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool11[index][0]);
break;
case 12:
memory->mem_blocks[mb_index + index].data = (unsigned char*)&(memory->mem_pool12[index][0]);
break;
default:
;
memory->mem_blocks[mb_index + index].data = NULL; // pool copy
}
memory->mem_blocks[mb_index + index].pool_id = pool_index;
list_add_tail_eurecom (&memory->mem_blocks[mb_index + index], &memory->mem_lists[pool_index]);
}
mb_index += pool_sizes[pool_index];
}
#ifdef MEMBLOCK_BIG_LOCK
if (pthread_mutex_unlock(&mtex)) abort();
#endif
return 0;
}
@@ -136,42 +177,51 @@ pool_buffer_init ()
void *
pool_buffer_clean (void *arg)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
return 0;
}
//-----------------------------------------------------------------------------
void
free_mem_block (mem_block_t * leP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (!(leP)) {
msg ("[MEM_MNGT][FREE] WARNING FREE NULL MEM_BLOCK\n");
return;
}
#ifdef DEBUG_MEM_MNGT_FREE
#ifdef MEMBLOCK_BIG_LOCK
if (pthread_mutex_lock(&mtex)) abort();
#endif
#ifdef DEBUG_MEM_MNGT_FREE
msg ("[MEM_MNGT][FREE] free_mem_block() %p pool: %d\n", leP, leP->pool_id);
#endif
#ifdef DEBUG_MEM_MNGT_ALLOC
#endif
#ifdef DEBUG_MEM_MNGT_ALLOC
check_free_mem_block (leP);
#endif
#endif
if (leP->pool_id <= MEM_MNGT_POOL_ID_COPY) {
list_add_tail_eurecom (leP, &mem_block_var.mem_lists[leP->pool_id]);
#ifdef DEBUG_MEM_MNGT_ALLOC
#ifdef DEBUG_MEM_MNGT_ALLOC
counters[leP->pool_id] -= 1;
#endif
#endif
leP = NULL; // this prevent from freeing the block twice
} else {
msg ("[MEM_MNGT][FREE] ERROR free_mem_block() unknown pool_id : %d\n", leP->pool_id);
}
#ifdef MEMBLOCK_BIG_LOCK
if (pthread_mutex_unlock(&mtex)) abort();
#endif
}
//-----------------------------------------------------------------------------
mem_block_t *
get_free_mem_block (uint16_t sizeP)
get_free_mem_block (uint32_t sizeP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
mem_block_t *le = NULL;
int pool_selected;
int size;
@@ -182,6 +232,11 @@ get_free_mem_block (uint16_t sizeP)
mac_xface->macphy_exit("[MEM_MNGT][ERROR][FATAL] get_free_mem_block size requested out of bounds");
return NULL;
}
#ifdef MEMBLOCK_BIG_LOCK
if (pthread_mutex_lock(&mtex)) abort();
#endif
size = sizeP >> 6;
pool_selected = 0;
@@ -194,24 +249,36 @@ get_free_mem_block (uint16_t sizeP)
// if no block is available pick one in an other pool
do {
if ((le = list_remove_head (&mem_block_var.mem_lists[pool_selected]))) {
#ifdef DEBUG_MEM_MNGT_ALLOC
#ifdef DEBUG_MEM_MNGT_ALLOC
counters[pool_selected] += 1;
#endif
#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
#endif
#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
msg ("[MEM_MNGT][INFO] ALLOC MEM_BLOCK SIZE %d bytes pool %d (%p)\n", sizeP, pool_selected,le);
#endif
#endif
#ifdef MEMBLOCK_BIG_LOCK
if (pthread_mutex_unlock(&mtex)) abort();
#endif
return le;
}
#ifdef DEBUG_MEM_MNGT_ALLOC
#ifdef DEBUG_MEM_MNGT_ALLOC
msg ("[MEM_MNGT][ERROR][MINOR] memory pool %d is empty trying next pool alloc count = %d\n", pool_selected, counters[pool_selected]);
#ifdef USER_MODE
#ifdef USER_MODE
// display_mem_load ();
// check_mem_area ((void *)&mem_block_var);
#endif
#endif
#endif
#endif
} while (pool_selected++ < 12);
display_mem_load();
mac_xface->macphy_exit("[MEM_MNGT][ERROR][FATAL] get_free_mem_block failed");
#ifdef MEMBLOCK_BIG_LOCK
if (pthread_mutex_unlock(&mtex)) abort();
#endif
return NULL;
};
@@ -219,12 +286,16 @@ get_free_mem_block (uint16_t sizeP)
mem_block_t *
get_free_copy_mem_block (void)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
mem_block_t *le;
#ifdef MEMBLOCK_BIG_LOCK
AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
#endif
if ((le = list_remove_head (&mem_block_var.mem_lists[MEM_MNGT_POOL_ID_COPY]))) {
#ifdef DEBUG_MEM_MNGT_ALLOC_SIZE
msg ("[MEM_MNGT][INFO] ALLOC COPY MEM BLOCK (%p)\n",le);
msg ("[MEM_MNGT][INFO] ALLOC COPY MEM BLOCK (%p)\n",le);
#endif
return le;
} else {
@@ -243,13 +314,18 @@ get_free_copy_mem_block (void)
mem_block_t *
copy_mem_block (mem_block_t * leP, mem_block_t * destP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#ifdef MEMBLOCK_BIG_LOCK
AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
#endif
if ((destP != NULL) && (leP != NULL) && (destP->pool_id == MEM_MNGT_POOL_ID_COPY)) {
destP->data = leP->data;
} else {
msg ("[MEM_MNGT][COPY] copy_mem_block() pool dest src or dest is NULL\n");
}
return destP;
}
@@ -257,7 +333,10 @@ copy_mem_block (mem_block_t * leP, mem_block_t * destP)
void
display_mem_load (void)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#ifdef MEMBLOCK_BIG_LOCK
/* this function does not need to be protected, do nothing */
#endif
mem_pool *memory = (mem_pool *) &mem_block_var;
@@ -295,92 +374,134 @@ display_mem_load (void)
void
check_mem_area (void)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int index, mb_index;
mem_pool *memory = (mem_pool *) &mem_block_var;
#ifdef MEMBLOCK_BIG_LOCK
AssertFatal(0, "This function is not handled properly but not used anywhere. FIXME?\n");
#endif
for (index = 0; index < MEM_MNGT_MB0_NB_BLOCKS; index++) {
if ((memory->mem_blocks[index].data != (unsigned char*)&(memory->mem_pool0[index][0])) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID0)) {
msg ("[MEM] ERROR POOL0 block index %d\n", index);
}
}
mb_index = MEM_MNGT_MB0_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB1_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool1[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID1)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool1[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID1)) {
msg ("[MEM] ERROR POOL1 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB1_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB2_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool2[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID2)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool2[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID2)) {
msg ("[MEM] ERROR POOL2 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB2_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB3_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool3[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID3)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool3[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID3)) {
msg ("[MEM] ERROR POOL3 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB3_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB4_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool4[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID4)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool4[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID4)) {
msg ("[MEM] ERROR POOL4 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB4_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB5_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool5[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID5)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool5[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID5)) {
msg ("[MEM] ERROR POOL5 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB5_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB6_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool6[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID6)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool6[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID6)) {
msg ("[MEM] ERROR POOL6 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB6_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB7_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool7[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID7)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool7[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID7)) {
msg ("[MEM] ERROR POOL7 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB7_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB8_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool8[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID8)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool8[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID8)) {
msg ("[MEM] ERROR POOL8 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB8_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB9_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool9[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID9)) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool9[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID9)) {
msg ("[MEM] ERROR POOL9 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB9_NB_BLOCKS;
for (index = mb_index; index < MEM_MNGT_MB10_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool10[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID10)) {
msg ("[MEM] ERROR POOL10 block index %d\n", index);
}
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool10[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID10)) {
msg ("[MEM] ERROR POOL10 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB10_NB_BLOCKS;
for (index = mb_index; index < MEM_MNGT_MB11_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool11[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID11)) {
msg ("[MEM] ERROR POOL11 block index %d\n", index);
}
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool11[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID11)) {
msg ("[MEM] ERROR POOL11 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB11_NB_BLOCKS;
for (index = mb_index; index < MEM_MNGT_MB12_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool12[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID12)) {
msg ("[MEM] ERROR POOL12 block index %d\n", index);
}
if ((memory->mem_blocks[mb_index + index].data != (unsigned char*)&(memory->mem_pool12[index][0]))
&& (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID12)) {
msg ("[MEM] ERROR POOL12 block index %d\n", index);
}
}
mb_index += MEM_MNGT_MB12_NB_BLOCKS;
for (index = mb_index; index < MEM_MNGT_NB_ELEMENTS; index++) {
if ((memory->mem_blocks[index].data != NULL) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID_COPY)) {
msg ("[MEM] ERROR POOL COPY block index %d\n", index);
}
if ((memory->mem_blocks[index].data != NULL) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID_COPY)) {
msg ("[MEM] ERROR POOL COPY block index %d\n", index);
}
}
}
@@ -388,8 +509,13 @@ check_mem_area (void)
void
check_free_mem_block (mem_block_t * leP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
ptrdiff_t block_index;
#ifdef MEMBLOCK_BIG_LOCK
/* this function does not SEEM TO need to be protected, do nothing (for the moment) */
#endif
if ((leP >= mem_block_var.mem_blocks) && (leP <= &mem_block_var.mem_blocks[MEM_MNGT_NB_ELEMENTS-1])) {
// the pointer is inside the memory region
block_index = leP - mem_block_var.mem_blocks;
@@ -399,102 +525,127 @@ check_free_mem_block (mem_block_t * leP)
if ((leP->data != (unsigned char*)mem_block_var.mem_pool0[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID0)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB0_NB_BLOCKS;
if (block_index < MEM_MNGT_MB1_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool1[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID1)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB1_NB_BLOCKS;
if (block_index < MEM_MNGT_MB2_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool2[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID2)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB2_NB_BLOCKS;
if (block_index < MEM_MNGT_MB3_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool3[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID3)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB3_NB_BLOCKS;
if (block_index < MEM_MNGT_MB4_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool4[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID4)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB4_NB_BLOCKS;
if (block_index < MEM_MNGT_MB5_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool5[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID5)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB5_NB_BLOCKS;
if (block_index < MEM_MNGT_MB6_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool6[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID6)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB6_NB_BLOCKS;
if (block_index < MEM_MNGT_MB7_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool7[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID7)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB7_NB_BLOCKS;
if (block_index < MEM_MNGT_MB8_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool8[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID8)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB8_NB_BLOCKS;
if (block_index < MEM_MNGT_MB9_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool9[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID9)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB9_NB_BLOCKS;
if (block_index < MEM_MNGT_MB10_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool10[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID10)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB10_NB_BLOCKS;
if (block_index < MEM_MNGT_MB11_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool11[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID11)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
block_index -= MEM_MNGT_MB11_NB_BLOCKS;
if (block_index < MEM_MNGT_MB12_NB_BLOCKS) {
if ((leP->data != (unsigned char*)mem_block_var.mem_pool12[block_index]) && (leP->pool_id != MEM_MNGT_POOL_ID12)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
return;
}
} else {
+20 -17
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -39,6 +39,9 @@
#ifndef __MEM_BLOCK_H__
# define __MEM_BLOCK_H__
#ifdef USER_MODE
#include <stdint.h>
#endif
#ifdef MEM_BLOCK_C
# define public_mem_block(x) x
# define private_mem_block(x) x
@@ -48,12 +51,12 @@
#endif
//-----------------------------------------------------------------------------
typedef struct mem_block_t{
typedef struct mem_block_t {
struct mem_block_t *next;
struct mem_block_t *previous;
unsigned char pool_id;
unsigned char *data;
}mem_block_t;
} mem_block_t;
#include "UTIL/LISTS/list.h"
//-----------------------------------------------------------------------------
@@ -61,7 +64,7 @@ typedef struct mem_block_t{
public_mem_block(void *pool_buffer_init (void);)
public_mem_block(void *pool_buffer_clean (void *arg);)
public_mem_block(void free_mem_block (mem_block_t * leP);)
public_mem_block(mem_block_t *get_free_mem_block (unsigned short sizeP);)
public_mem_block(mem_block_t* get_free_mem_block (uint32_t sizeP);)
public_mem_block(mem_block_t *get_free_copy_mem_block (void);)
public_mem_block(mem_block_t *get_free_copy_mem_block_up (void);)
public_mem_block(mem_block_t *copy_mem_block (mem_block_t * leP, mem_block_t * destP);)
@@ -82,42 +85,42 @@ private_mem_block(void check_free_mem_block (mem_block_t * leP);)
#endif
// definition of the size of the allocated memory area
# define MEM_MNGT_MB0_BLOCK_SIZE 64
// 64
// 64
# define MEM_MNGT_MB0_NB_BLOCKS 4096 * MEM_SCALE
# define MEM_MNGT_POOL_ID0 0
# define MEM_MNGT_MB1_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*2
// 128
// 128
# define MEM_MNGT_MB1_NB_BLOCKS 4096 * MEM_SCALE
# define MEM_MNGT_POOL_ID1 1
# define MEM_MNGT_MB2_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*4
// 256
// 256
# define MEM_MNGT_MB2_NB_BLOCKS 2048 * MEM_SCALE
# define MEM_MNGT_POOL_ID2 2
# define MEM_MNGT_MB3_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*8
// 512
// 512
# define MEM_MNGT_MB3_NB_BLOCKS 2048 * MEM_SCALE
# define MEM_MNGT_POOL_ID3 3
# define MEM_MNGT_MB4_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*16
// 1024
// 1024
# define MEM_MNGT_MB4_NB_BLOCKS 1024 * MEM_SCALE
# define MEM_MNGT_POOL_ID4 4
# define MEM_MNGT_MB5_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*32
// 2048
// 2048
# define MEM_MNGT_MB5_NB_BLOCKS 1024 * MEM_SCALE // LG WAS 1024
# define MEM_MNGT_POOL_ID5 5
# define MEM_MNGT_MB6_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*64
// 4096
// 4096
# define MEM_MNGT_MB6_NB_BLOCKS 1024 * MEM_SCALE // LG WAS 256
# define MEM_MNGT_POOL_ID6 6
# define MEM_MNGT_MB7_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*128
// 8192
// 8192
# define MEM_MNGT_MB7_NB_BLOCKS 64* MEM_SCALE // LG WAS 32
# define MEM_MNGT_POOL_ID7 7
@@ -127,27 +130,27 @@ private_mem_block(void check_free_mem_block (mem_block_t * leP);)
# define MEM_MNGT_MB8_NB_BLOCKS 256 * MEM_SCALE
#else
# define MEM_MNGT_MB8_NB_BLOCKS 16 * MEM_SCALE
// 16384
// 16384
#endif
# define MEM_MNGT_POOL_ID8 8
# define MEM_MNGT_MB9_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*512
// 32768
// 32768
# define MEM_MNGT_MB9_NB_BLOCKS 8 * MEM_SCALE
# define MEM_MNGT_POOL_ID9 9
# define MEM_MNGT_MB10_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*1024
// 65536
// 65536
# define MEM_MNGT_MB10_NB_BLOCKS 0 * MEM_SCALE
# define MEM_MNGT_POOL_ID10 10
# define MEM_MNGT_MB11_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*2048
// 131072
// 131072
# define MEM_MNGT_MB11_NB_BLOCKS 0 * MEM_SCALE
# define MEM_MNGT_POOL_ID11 11
# define MEM_MNGT_MB12_BLOCK_SIZE MEM_MNGT_MB0_BLOCK_SIZE*4096
// 262144
// 262144
# define MEM_MNGT_MB12_NB_BLOCKS 32 * MEM_SCALE
# define MEM_MNGT_POOL_ID12 12
+103 -55
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -54,7 +54,7 @@
# define PRINT_MEM_MNGT_ADDR msg
#else
# define PRINT_MEM_MNGT_ADDR
//
//
#endif
//-----------------------------------------------------------------------------
#ifdef USER_MODE
@@ -67,66 +67,82 @@ uint32_t counters[11] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
void *
pool_buffer_init (void *arg)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
uint32_t index, mb_index, pool_index;
mem_pool *memory = (mem_pool *) arg;
int pool_sizes[11] = { MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB1_NB_BLOCKS,
MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB7_NB_BLOCKS,
MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB9_NB_BLOCKS,
MEM_MNGT_MBCOPY_NB_BLOCKS
};
MEM_MNGT_MB2_NB_BLOCKS, MEM_MNGT_MB3_NB_BLOCKS,
MEM_MNGT_MB4_NB_BLOCKS, MEM_MNGT_MB5_NB_BLOCKS,
MEM_MNGT_MB6_NB_BLOCKS, MEM_MNGT_MB7_NB_BLOCKS,
MEM_MNGT_MB8_NB_BLOCKS, MEM_MNGT_MB9_NB_BLOCKS,
MEM_MNGT_MBCOPY_NB_BLOCKS
};
memset (memory, 0, sizeof (mem_pool));
mb_index = 0;
// LG_TEST
for (pool_index = 0; pool_index <= MEM_MNGT_POOL_ID_COPY; pool_index++) {
init_list (&memory->mem_lists[pool_index], "POOL");
for (index = 0; index < pool_sizes[pool_index]; index++) {
//memory->mem_blocks[mb_index + index].previous = NULL; -> done in memset 0
//memory->mem_blocks[mb_index + index].next = NULL; -> done in memset 0
switch (pool_index) {
case 0:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool0[index][0]);
break;
case 1:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool1[index][0]);
break;
case 2:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool2[index][0]);
break;
case 3:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool3[index][0]);
break;
case 4:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool4[index][0]);
break;
case 5:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool5[index][0]);
break;
case 6:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool6[index][0]);
break;
case 7:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool7[index][0]);
break;
case 8:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool8[index][0]);
break;
case 9:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool9[index][0]);
break;
default:;
memory->mem_blocks[mb_index + index].data = NULL; // pool copy
case 0:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool0[index][0]);
break;
case 1:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool1[index][0]);
break;
case 2:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool2[index][0]);
break;
case 3:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool3[index][0]);
break;
case 4:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool4[index][0]);
break;
case 5:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool5[index][0]);
break;
case 6:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool6[index][0]);
break;
case 7:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool7[index][0]);
break;
case 8:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool8[index][0]);
break;
case 9:
memory->mem_blocks[mb_index + index].data = &(memory->mem_pool9[index][0]);
break;
default:
;
memory->mem_blocks[mb_index + index].data = NULL; // pool copy
}
memory->mem_blocks[mb_index + index].pool_id = pool_index;
add_tail (&memory->mem_blocks[mb_index + index], &memory->mem_lists[pool_index]);
}
mb_index += pool_sizes[pool_index];
}
return 0;
}
@@ -134,7 +150,7 @@ pool_buffer_init (void *arg)
void *
pool_buffer_clean (void *arg)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
#ifndef NO_THREAD_SAFE
mem_pool *memory = (mem_pool *) arg;
pthread_mutex_destroy (&memory->mem_lists[MEM_MNGT_POOL_ID0].mutex);
@@ -155,12 +171,13 @@ pool_buffer_clean (void *arg)
void
free_mem_block (mem_block_t * leP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if (!(leP)) {
msg ("[MEM_MNGT][FREE] WARNING FREE NULL MEM_BLOCK\n");
return;
}
#ifdef DEBUG_MEM_MNGT_FREE
msg ("[MEM_MNGT][FREE] free_mem_block() %p pool: %d\n", leP, leP->pool_id);
#endif
@@ -184,7 +201,7 @@ free_mem_block (mem_block_t * leP)
mem_block_t *
get_free_mem_block (uint16_t sizeP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
mem_block_t *le = NULL;
int pool_selected;
int size;
@@ -194,6 +211,7 @@ get_free_mem_block (uint16_t sizeP)
wcdma_handle_error (WCDMA_ERROR_OUT_OF_MEM_BLOCK);
return NULL;
}
size = sizeP >> 6;
pool_selected = 0;
@@ -214,6 +232,7 @@ get_free_mem_block (uint16_t sizeP)
#endif
return le;
}
#ifdef DEBUG_MEM_MNGT_ALLOC
msg ("[MEM_MNGT][ERROR][MINOR] memory pool %d is empty trying next pool alloc count = %d\n", pool_selected, counters[pool_selected]);
# ifdef USER_MODE
@@ -222,6 +241,7 @@ get_free_mem_block (uint16_t sizeP)
# endif
#endif
} while (pool_selected++ < 9);
msg ("[MEM_MNGT][ERROR][FATAL] size %d requested out of bounds or memory pools empty\n", sizeP);
wcdma_handle_error (WCDMA_ERROR_OUT_OF_MEM_BLOCK);
return NULL;
@@ -231,7 +251,7 @@ get_free_mem_block (uint16_t sizeP)
mem_block_t *
get_free_copy_mem_block (void)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
mem_block_t *le;
if ((le = remove_head (&mem->mem_lists[MEM_MNGT_POOL_ID_COPY]))) {
@@ -253,13 +273,14 @@ get_free_copy_mem_block (void)
mem_block_t *
copy_mem_block (mem_block_t * leP, mem_block_t * destP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
if ((destP != NULL) && (leP != NULL) && (destP->pool_id == MEM_MNGT_POOL_ID_COPY)) {
destP->data = leP->data;
} else {
msg ("[MEM_MNGT][COPY] copy_mem_block() pool dest src or dest is NULL\n");
}
return destP;
}
@@ -267,7 +288,7 @@ copy_mem_block (mem_block_t * leP, mem_block_t * destP)
void
display_mem_load (void)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
msg ("POOL 0 (%d elements of %d Bytes): \n", MEM_MNGT_MB0_NB_BLOCKS, MEM_MNGT_MB0_BLOCK_SIZE);
display_list (&mem->mem_lists[MEM_MNGT_POOL_ID0]);
@@ -297,7 +318,7 @@ display_mem_load (void)
void
check_mem_area (void *arg)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int index, mb_index;
mem_pool *memory = (mem_pool *) arg;
@@ -307,70 +328,90 @@ check_mem_area (void *arg)
break_point ();
}
}
mb_index = MEM_MNGT_MB0_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB1_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool1[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID1)) {
msg ("[MEM] ERROR POOL1 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB1_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB2_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool2[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID2)) {
msg ("[MEM] ERROR POOL2 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB2_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB3_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool3[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID3)) {
msg ("[MEM] ERROR POOL3 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB3_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB4_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool4[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID4)) {
msg ("[MEM] ERROR POOL4 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB4_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB5_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool5[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID5)) {
msg ("[MEM] ERROR POOL5 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB5_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB6_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool6[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID6)) {
msg ("[MEM] ERROR POOL6 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB6_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB7_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool7[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID7)) {
msg ("[MEM] ERROR POOL7 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB7_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB8_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool8[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID8)) {
msg ("[MEM] ERROR POOL8 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB8_NB_BLOCKS;
for (index = 0; index < MEM_MNGT_MB9_NB_BLOCKS; index++) {
if ((memory->mem_blocks[mb_index + index].data != &(memory->mem_pool9[index][0])) && (memory->mem_blocks[mb_index + index].pool_id != MEM_MNGT_POOL_ID9)) {
msg ("[MEM] ERROR POOL9 block index %d\n", index);
break_point ();
}
}
mb_index += MEM_MNGT_MB9_NB_BLOCKS;
for (index = mb_index; index < MEM_MNGT_NB_ELEMENTS; index++) {
if ((memory->mem_blocks[index].data != NULL) && (memory->mem_blocks[index].pool_id != MEM_MNGT_POOL_ID_COPY)) {
msg ("[MEM] ERROR POOL COPY block index %d\n", index);
@@ -383,10 +424,12 @@ check_mem_area (void *arg)
void
check_free_mem_block (mem_block_t * leP)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int block_index;
if ((leP >= &mem->mem_blocks[0]) && (leP <= &mem->mem_blocks[MEM_MNGT_NB_ELEMENTS])) {
block_index = ((uint32_t) leP - (uint32_t) (&mem->mem_blocks[0])) / sizeof (mem_block_t);
if (block_index < MEM_MNGT_MB0_NB_BLOCKS) {
if (((uint32_t) (leP->data) != (uint32_t) (&(mem->mem_pool0[block_index][0]))) && (leP->pool_id != MEM_MNGT_POOL_ID0)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
@@ -407,29 +450,34 @@ check_free_mem_block (mem_block_t * leP)
if ((leP->data != &(mem->mem_pool4[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID4)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
} else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS) {
} else if (block_index < MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS +
MEM_MNGT_MB5_NB_BLOCKS) {
if ((leP->data != &(mem->mem_pool5[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID5)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
} else if (block_index <
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS + MEM_MNGT_MB6_NB_BLOCKS) {
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
MEM_MNGT_MB6_NB_BLOCKS) {
if ((leP->data != &(mem->mem_pool6[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID6)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
} else if (block_index <
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS + MEM_MNGT_MB6_NB_BLOCKS +
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
MEM_MNGT_MB6_NB_BLOCKS +
MEM_MNGT_MB7_NB_BLOCKS) {
if ((leP->data != &(mem->mem_pool7[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID7)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
} else if (block_index <
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS + MEM_MNGT_MB6_NB_BLOCKS +
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
MEM_MNGT_MB6_NB_BLOCKS +
MEM_MNGT_MB7_NB_BLOCKS + MEM_MNGT_MB8_NB_BLOCKS) {
if ((leP->data != &(mem->mem_pool8[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID8)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
}
} else if (block_index <
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS + MEM_MNGT_MB6_NB_BLOCKS +
MEM_MNGT_MB0_NB_BLOCKS + MEM_MNGT_MB1_NB_BLOCKS + MEM_MNGT_MB2_NB_BLOCKS + MEM_MNGT_MB3_NB_BLOCKS + MEM_MNGT_MB4_NB_BLOCKS + MEM_MNGT_MB5_NB_BLOCKS +
MEM_MNGT_MB6_NB_BLOCKS +
MEM_MNGT_MB7_NB_BLOCKS + MEM_MNGT_MB8_NB_BLOCKS + MEM_MNGT_MB9_NB_BLOCKS) {
if ((leP->data != &(mem->mem_pool9[block_index][0])) && (leP->pool_id != MEM_MNGT_POOL_ID9)) {
msg ("[MEM][ERROR][FATAL] free mem block is corrupted\n");
@@ -445,7 +493,7 @@ check_free_mem_block (mem_block_t * leP)
void
break_point (void)
{
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
int break_var;
msg ("[BREAK_POINT]\n");
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
+199 -182
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -33,7 +33,7 @@
* \date 2011
* \version 0.1
* \company Eurecom
* \email: navid.nikaein@eurecom.fr
* \email: navid.nikaein@eurecom.fr
* \note
* \warning
*/
@@ -60,195 +60,212 @@
#ifdef TEST_OCG
int main(int argc, char *argv[]) {
#else
int OCG_main(char is_local_server[FILENAME_LENGTH_MAX]) {
#endif
int state = STATE_START_OCG;
char web_XML_folder[DIR_LENGTH_MAX] = "";
char output_dir[DIR_LENGTH_MAX] = ""; // the output folder during the OCG procedure. Change step by step
char *OPENAIR_TARGETS=getenv("OPENAIR_TARGETS");
if (OPENAIR_TARGETS == NULL) {
LOG_E(OCG, "please set the PATH for OPENAIR_TARGETS");
exit(EXIT_FAILURE);
}
if (!strcmp(is_local_server, "0")) { // Eurecom web server
strcpy(web_XML_folder, WEB_XML_FOLDER);
strcat(output_dir, OUTPUT_DIR);
} else { // local user
sprintf(web_XML_folder,"%s/SIMU/EXAMPLES/OSD/WEBXML/",getenv("OPENAIR_TARGETS"));
sprintf(output_dir,"%s/SIMU/EXAMPLES/OSD/RESULTS/",getenv("OPENAIR_TARGETS"));
/*
strcpy(web_XML_folder, OPENAIR_TARGETS);
strcpy(output_dir, OPENAIR_TARGETS);
char *slash;
slash = web_XML_folder + strlen(web_XML_folder) - 1;
if (strcmp(slash, "/")) { // check if the path OPENAIR_TARGETS is ended with a '/'
strcat(web_XML_folder, "/");
strcat(output_dir, "/");
}
strcat(web_XML_folder, "SIMU/EXAMPLES/OSD/WEBXML/");
strcat(output_dir, "SIMU/EXAMPLES/OSD/RESULTS/");
*/ }
LOG_I(OCG, "Folder for detecting the XML configuration file is %s\n", web_XML_folder);
LOG_I(OCG, "Folder for generating the results is %s\n", output_dir);
LOG_I(OCG, "OSD XML config file is %s\n", is_local_server);
while(state != STATE_END) {
switch(state) {
case STATE_START_OCG :
LOG_I(OCG, "OCG starts ...\n\n");
get_opt_OK = MODULE_NOT_PROCESSED; // -9999 is the initial value, representing the module not processed
detect_file_OK = MODULE_NOT_PROCESSED;
create_dir_OK = MODULE_NOT_PROCESSED;
// to write the pid into a file 'OCG.pid' so that the web portal part could check if OCG is running
/*
pid_t pid;
pid = getpid();
FILE *OCG_pid;
OCG_pid = fopen("OCG.pid", "w");
fprintf(OCG_pid, "%d\n", pid);
fclose(OCG_pid);
*/
#ifdef TEST_OCG
state = STATE_GET_OPT;
case STATE_GET_OPT :
get_opt_OK = get_opt(argc, argv);
if (get_opt_OK == MODULE_OK) {
strcpy(src_file, LOCAL_XML_FOLDER);
copy_or_move = 1;
state = STATE_INI_EMU;
} else if (get_opt_OK == GET_HELP) state = STATE_END;
else state = STATE_DETECT_FILE;
break;
int main(int argc, char *argv[])
{
#else
state = STATE_DETECT_FILE;
//get_opt_OK == MODULE_OK;
int OCG_main(char is_local_server[FILENAME_LENGTH_MAX])
{
#endif
int state = STATE_START_OCG;
char web_XML_folder[DIR_LENGTH_MAX] = "";
char output_dir[DIR_LENGTH_MAX] = ""; // the output folder during the OCG procedure. Change step by step
char *OPENAIR_TARGETS=getenv("OPENAIR_TARGETS");
if (OPENAIR_TARGETS == NULL) {
LOG_E(OCG, "please set the PATH for OPENAIR_TARGETS");
exit(EXIT_FAILURE);
}
if (!strcmp(is_local_server, "0")) { // Eurecom web server
strcpy(web_XML_folder, WEB_XML_FOLDER);
strcat(output_dir, OUTPUT_DIR);
} else { // local user
sprintf(web_XML_folder,"%s/SIMU/EXAMPLES/OSD/WEBXML/",getenv("OPENAIR_TARGETS"));
sprintf(output_dir,"%s/SIMU/EXAMPLES/OSD/RESULTS/",getenv("OPENAIR_TARGETS"));
/*
strcpy(web_XML_folder, OPENAIR_TARGETS);
strcpy(output_dir, OPENAIR_TARGETS);
char *slash;
slash = web_XML_folder + strlen(web_XML_folder) - 1;
if (strcmp(slash, "/")) { // check if the path OPENAIR_TARGETS is ended with a '/'
strcat(web_XML_folder, "/");
strcat(output_dir, "/");
}
strcat(web_XML_folder, "SIMU/EXAMPLES/OSD/WEBXML/");
strcat(output_dir, "SIMU/EXAMPLES/OSD/RESULTS/");
*/
}
LOG_I(OCG, "Folder for detecting the XML configuration file is %s\n", web_XML_folder);
LOG_I(OCG, "Folder for generating the results is %s\n", output_dir);
LOG_I(OCG, "OSD XML config file is %s\n", is_local_server);
while(state != STATE_END) {
switch(state) {
case STATE_START_OCG :
LOG_I(OCG, "OCG starts ...\n\n");
get_opt_OK = MODULE_NOT_PROCESSED; // -9999 is the initial value, representing the module not processed
detect_file_OK = MODULE_NOT_PROCESSED;
create_dir_OK = MODULE_NOT_PROCESSED;
// to write the pid into a file 'OCG.pid' so that the web portal part could check if OCG is running
/*
pid_t pid;
pid = getpid();
FILE *OCG_pid;
OCG_pid = fopen("OCG.pid", "w");
fprintf(OCG_pid, "%d\n", pid);
fclose(OCG_pid);
*/
#ifdef TEST_OCG
state = STATE_GET_OPT;
case STATE_GET_OPT :
get_opt_OK = get_opt(argc, argv);
if (get_opt_OK == MODULE_OK) {
strcpy(src_file, LOCAL_XML_FOLDER);
copy_or_move = 1;
state = STATE_INI_EMU;
} else if (get_opt_OK == GET_HELP) state = STATE_END;
else state = STATE_DETECT_FILE;
break;
#else
state = STATE_DETECT_FILE;
//get_opt_OK == MODULE_OK;
#endif
case STATE_DETECT_FILE :
strcpy(src_file, web_XML_folder);
detect_file_OK = detect_file(src_file, is_local_server);
if (detect_file_OK == MODULE_OK) {
if ((!strcmp(is_local_server, "0")) || (!strcmp(is_local_server, "-1"))) copy_or_move = 2;
state = STATE_INI_EMU;
} else if (detect_file_OK == MODULE_ERROR) state = STATE_GENERATE_REPORT;
else if (detect_file_OK == NO_FILE) {
state = STATE_DETECT_FILE;
sleep(1);
}
break;
case STATE_INI_EMU : // before initiating an emu, an XML file should be found above
parse_filename_OK = MODULE_NOT_PROCESSED;
create_dir_OK = MODULE_NOT_PROCESSED;
parse_XML_OK = MODULE_NOT_PROCESSED;
save_XML_OK = MODULE_NOT_PROCESSED;
// call_emu_OK = MODULE_NOT_PROCESSED;
//config_mobi_OK = MODULE_NOT_PROCESSED;
generate_report_OK = MODULE_NOT_PROCESSED;
case STATE_DETECT_FILE :
strcpy(src_file, web_XML_folder);
detect_file_OK = detect_file(src_file, is_local_server);
LOG_I(OCG, "An emulation for file %s is initiated\n", filename);
state = STATE_PARSE_FILENAME;
break;
if (detect_file_OK == MODULE_OK) {
if ((!strcmp(is_local_server, "0")) || (!strcmp(is_local_server, "-1"))) copy_or_move = 2;
case STATE_PARSE_FILENAME :
strcat(src_file, filename);
if ((parse_filename_OK = parse_filename(filename)) == MODULE_OK) state = STATE_CREATE_DIR;
else {
if (copy_or_move == 2) {
remove(src_file);
state = STATE_DETECT_FILE;
} else state = STATE_GENERATE_REPORT;
}
break;
case STATE_CREATE_DIR :
if ((create_dir_OK = create_dir(output_dir, user_name, file_date)) == MODULE_OK) {
state = STATE_PARSE_XML;
strcat(output_dir, user_name);
strcat(output_dir, "/");
strcat(output_dir, file_date);
strcat(output_dir, "/");
strcpy(dst_dir, output_dir);
oai_emulation.info.output_path = &dst_dir; // information for other modules within OAI
} else state = STATE_GENERATE_REPORT;
break;
case STATE_PARSE_XML :
if ((parse_XML_OK = parse_XML(src_file)) == MODULE_OK) state = STATE_SAVE_XML;
else {
if (copy_or_move == 2) remove(src_file);
state = STATE_GENERATE_REPORT;
}
break;
case STATE_SAVE_XML :
if ((save_XML_OK = save_XML(copy_or_move, src_file, output_dir, filename)) == MODULE_OK)
state = STATE_CALL_EMU;
else state = STATE_GENERATE_REPORT;
break;
case STATE_CALL_EMU : // change this state to set_params
state = STATE_INI_EMU;
} else if (detect_file_OK == MODULE_ERROR) state = STATE_GENERATE_REPORT;
else if (detect_file_OK == NO_FILE) {
state = STATE_DETECT_FILE;
sleep(1);
}
break;
case STATE_INI_EMU : // before initiating an emu, an XML file should be found above
parse_filename_OK = MODULE_NOT_PROCESSED;
create_dir_OK = MODULE_NOT_PROCESSED;
parse_XML_OK = MODULE_NOT_PROCESSED;
save_XML_OK = MODULE_NOT_PROCESSED;
// call_emu_OK = MODULE_NOT_PROCESSED;
//config_mobi_OK = MODULE_NOT_PROCESSED;
generate_report_OK = MODULE_NOT_PROCESSED;
LOG_I(OCG, "An emulation for file %s is initiated\n", filename);
state = STATE_PARSE_FILENAME;
break;
case STATE_PARSE_FILENAME :
strcat(src_file, filename);
if ((parse_filename_OK = parse_filename(filename)) == MODULE_OK) state = STATE_CREATE_DIR;
else {
if (copy_or_move == 2) {
remove(src_file);
state = STATE_DETECT_FILE;
} else state = STATE_GENERATE_REPORT;
}
break;
case STATE_CREATE_DIR :
if ((create_dir_OK = create_dir(output_dir, user_name, file_date)) == MODULE_OK) {
state = STATE_PARSE_XML;
strcat(output_dir, user_name);
strcat(output_dir, "/");
strcat(output_dir, file_date);
strcat(output_dir, "/");
strcpy(dst_dir, output_dir);
oai_emulation.info.output_path = dst_dir; // information for other modules within OAI
} else state = STATE_GENERATE_REPORT;
break;
case STATE_PARSE_XML :
if ((parse_XML_OK = parse_XML(src_file)) == MODULE_OK) state = STATE_SAVE_XML;
else {
if (copy_or_move == 2) remove(src_file);
state = STATE_GENERATE_REPORT;
}
break;
case STATE_SAVE_XML :
if ((save_XML_OK = save_XML(copy_or_move, src_file, output_dir, filename)) == MODULE_OK)
state = STATE_CALL_EMU;
else state = STATE_GENERATE_REPORT;
break;
case STATE_CALL_EMU : // change this state to set_params
if ((detect_file_OK == MODULE_OK) && (parse_filename_OK == MODULE_OK) && (create_dir_OK == MODULE_OK) && (parse_XML_OK == MODULE_OK) && (save_XML_OK == MODULE_OK)) {
// if the above tasks are all successful, we could tell the oaisim_config.c that everything is ready before running the emulation
oai_emulation.info.ocg_ok = 1;
}
if ((detect_file_OK == MODULE_OK) && (parse_filename_OK == MODULE_OK) && (create_dir_OK == MODULE_OK) && (parse_XML_OK == MODULE_OK) && (save_XML_OK == MODULE_OK)) {
// if the above tasks are all successful, we could tell the oaisim_config.c that everything is ready before running the emulation
oai_emulation.info.ocg_ok = 1;
}
#ifdef TEST_OCG
call_emu_OK = call_emu(output_dir);
// config_mobi_OK = config_mobi("RWMEmulator.xml", filename); // generate the XML for Mobigen
#endif
state = STATE_GENERATE_REPORT;
break;
case STATE_GENERATE_REPORT :
if (create_dir_OK != MODULE_OK) {
// a temp folder is required when the output folder could not be correctly generated
//strcpy(output_dir, OPENAIR_TARGETS);
//strcat(output_dir, "SIMU/EXAMPLES/OSD/");
//strcat(output_dir, TEMP_OUTPUT_DIR);
strncpy(output_dir, OPENAIR_TARGETS, sizeof(output_dir));
output_dir[sizeof(output_dir) - 1] = 0; // terminate string
strncat(output_dir, "SIMU/EXAMPLES/OSD/", sizeof(output_dir) - strlen(output_dir) - 1);
strncat(output_dir, TEMP_OUTPUT_DIR, sizeof(output_dir) - strlen(output_dir) - 1);
struct stat st;
if(stat(output_dir, &st) != 0) { // if temp output directory does not exist, we create it here
mkdir(output_dir, S_IRWXU | S_IRWXG | S_IRWXO);
LOG_I(OCG, "temp output directory %s is created", output_dir);
}
} else {
//strcat(output_dir, "SCENARIO/STATE/"); // if needeed the outpur directory can be further set
LOG_I(OCG, "Output directory is %s \n", output_dir);
}
generate_report(output_dir, "OCG_report.xml");
if (copy_or_move == 1) state = STATE_END;
else state = STATE_END;
//else state = STATE_DETECT_FILE;
break;
}
} // end while
// Cleanup function for the XML library.
xmlCleanupParser();
// this is to debug memory for regression tests
xmlMemoryDump();
LOG_I(OCG, "... OCG ends\n\n");
#ifdef TEST_OCG
return 0;
call_emu_OK = call_emu(output_dir);
// config_mobi_OK = config_mobi("RWMEmulator.xml", filename); // generate the XML for Mobigen
#endif
state = STATE_GENERATE_REPORT;
break;
case STATE_GENERATE_REPORT :
if (create_dir_OK != MODULE_OK) {
// a temp folder is required when the output folder could not be correctly generated
strncpy(output_dir, OPENAIR_TARGETS, sizeof(output_dir));
output_dir[sizeof(output_dir) - 1] = 0; // terminate string
strncat(output_dir, "SIMU/EXAMPLES/OSD/", sizeof(output_dir) - strlen(output_dir) - 1);
strncat(output_dir, TEMP_OUTPUT_DIR, sizeof(output_dir) - strlen(output_dir) - 1);
struct stat st;
if(stat(output_dir, &st) != 0) { // if temp output directory does not exist, we create it here
mkdir(output_dir, S_IRWXU | S_IRWXG | S_IRWXO);
LOG_I(OCG, "temp output directory %s is created", output_dir);
}
} else {
//strcat(output_dir, "SCENARIO/STATE/"); // if needeed the outpur directory can be further set
LOG_I(OCG, "Output directory is %s \n", output_dir);
}
generate_report(output_dir, "OCG_report.xml");
if (copy_or_move == 1) state = STATE_END;
else state = STATE_END;
//else state = STATE_DETECT_FILE;
break;
}
} // end while
// Cleanup function for the XML library.
xmlCleanupParser();
// this is to debug memory for regression tests
xmlMemoryDump();
LOG_I(OCG, "... OCG ends\n\n");
#ifdef TEST_OCG
return 0;
#else
return 1;
return 1;
#endif
}
+512 -557
View File
File diff suppressed because it is too large Load Diff
+14 -13
View File
@@ -1,4 +1,4 @@
Lusheng Wang and
Lusheng Wang and
/*! \file OCG_call_emu.c
* \brief Call the emulator
* \author Lusheng Wang and Navid Nikaein
@@ -20,19 +20,20 @@ Lusheng Wang and
OAI_Emulation oai_emulation;
int call_emu(char dst_dir[DIR_LENGTH_MAX]) {
int call_emu(char dst_dir[DIR_LENGTH_MAX])
{
////////// print the configuration
FILE *file;
char dst_file[DIR_LENGTH_MAX] = "";
strcat(dst_file, dst_dir);
strcat(dst_file, "emulation_result.txt");
file = fopen(dst_file,"w");
//system("../../../openair1/SIMULATION/LTE_PHY_L2/physim --help");
fclose(file);
////////// print the configuration
FILE *file;
char dst_file[DIR_LENGTH_MAX] = "";
strcat(dst_file, dst_dir);
strcat(dst_file, "emulation_result.txt");
file = fopen(dst_file,"w");
//system("../../../openair1/SIMULATION/LTE_PHY_L2/physim --help");
LOG_I(OCG, "Emulation finished\n");
return MODULE_OK;
fclose(file);
LOG_I(OCG, "Emulation finished\n");
return MODULE_OK;
}
+3 -3
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -48,8 +48,8 @@ extern "C" {
/** @defgroup _call_emu Call Emu
* @ingroup _fn
* @brief Call the emulator
* @{*/
int call_emu(char dst_dir[DIR_LENGTH_MAX]);
* @{*/
int call_emu(char dst_dir[DIR_LENGTH_MAX]);
/* @}*/
#ifdef __cplusplus
+97 -95
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -47,105 +47,107 @@
#include "OCG_config_mobi.h"
/*----------------------------------------------------------------------------*/
int config_mobi(char mobigen_filename[FILENAME_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]) {
// for the xml writer, refer to http://xmlsoft.org/html/libxml-xmlwriter.html
char dir_to_mobigen_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = "";
char mobi_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = "";
xmlTextWriterPtr writer;
strcpy(dir_to_mobigen_file, DIR_TO_MOBIGEN);
strcat(dir_to_mobigen_file, mobigen_filename);
/* Create a new XmlWriter for uri, with no compression. */
writer = xmlNewTextWriterFilename(dir_to_mobigen_file, 0);
// set the output format of the XML file
xmlTextWriterSetIndent(writer, 1);
xmlTextWriterSetIndentString(writer, " ");
/* Start the document with the xml default for the version,
* encoding ISO 8859-1 and the default for the standalone
* declaration. */
xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
int config_mobi(char mobigen_filename[FILENAME_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX])
{
// for the xml writer, refer to http://xmlsoft.org/html/libxml-xmlwriter.html
/* Start an element named "EXAMPLE". Since this is the first
* element, this will be the root element of the document. */
xmlTextWriterStartElement(writer, "universe");
char dir_to_mobigen_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = "";
char mobi_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = "";
xmlTextWriterPtr writer;
/* Write an element named "X_ORDER_ID" as child of HEADER. */
xmlTextWriterWriteFormatElement(writer, "dimx", "%lf", oai_emulation.topo_config.area.x);
/* Write an element named "X_ORDER_ID" as child of HEADER. */
xmlTextWriterWriteFormatElement(writer, "dimy", "%lf", oai_emulation.topo_config.area.y);
strcpy(dir_to_mobigen_file, DIR_TO_MOBIGEN);
strcat(dir_to_mobigen_file, mobigen_filename);
/* Create a new XmlWriter for uri, with no compression. */
writer = xmlNewTextWriterFilename(dir_to_mobigen_file, 0);
xmlTextWriterWriteFormatElement(writer, "seed", "%d", 1);
xmlTextWriterStartElement(writer, "extension");
xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.simulations.TimeSimulation");
xmlTextWriterWriteFormatAttribute(writer, "param", "%lf", oai_emulation.emu_config.emu_time);
xmlTextWriterEndElement(writer);
xmlTextWriterStartElement(writer, "extension");
xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.spatialmodel.core.SpatialModel");
xmlTextWriterWriteFormatAttribute(writer, "max_x", "%lf", oai_emulation.topo_config.area.x);
xmlTextWriterWriteFormatAttribute(writer, "max_y", "%lf", oai_emulation.topo_config.area.y);
xmlTextWriterWriteAttribute(writer, "min_x", "0");
xmlTextWriterWriteAttribute(writer, "min_y", "0");
xmlTextWriterWriteFormatElement(writer, "dump_boundary_points", "%s", "false");
xmlTextWriterWriteFormatElement(writer, "separated_flow", "%s", "false");
xmlTextWriterWriteFormatElement(writer, "max_traffic_lights", "%d", 500);
xmlTextWriterEndElement(writer);
xmlTextWriterStartElement(writer, "extension");
xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.extensions.ReportNodeMobility");
strcpy(mobi_file, MOBI_XML_FOLDER);
strcat(mobi_file, filename);
xmlTextWriterWriteAttribute(writer, "output", mobi_file);
xmlTextWriterWriteFormatElement(writer, "step", "%d", 1);
xmlTextWriterEndElement(writer);
xmlTextWriterStartElement(writer, "nodegroup");
xmlTextWriterWriteAttribute(writer, "car2x", "false");
xmlTextWriterWriteAttribute(writer, "id", "");
xmlTextWriterWriteAttribute(writer, "n", "50");
xmlTextWriterWriteAttribute(writer, "type", "car");
xmlTextWriterStartElement(writer, "position");
xmlTextWriterWriteAttribute(writer, "random", "true");
xmlTextWriterWriteFormatElement(writer, "z", "%s", "0.0");
xmlTextWriterEndElement(writer);
xmlTextWriterStartElement(writer, "extension");
xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.mobilitymodels.RandomWaypointWalk");
if (!strcmp(oai_emulation.topo_config.UE_mobility.UE_mobility_type.selected_option, "fixed")) {
xmlTextWriterWriteFormatElement(writer, "minspeed", "%d", 0);
xmlTextWriterWriteFormatElement(writer, "maxspeed", "%d", 0);
xmlTextWriterWriteFormatElement(writer, "minstay", "%d", 9999);
xmlTextWriterWriteFormatElement(writer, "maxstay", "%d", 9999);
} else if (!strcmp(oai_emulation.topo_config.UE_mobility.UE_mobility_type.selected_option, "random_waypoint")) {
xmlTextWriterWriteFormatElement(writer, "minspeed", "%lf", oai_emulation.topo_config.UE_mobility.UE_moving_dynamics.min_speed);
xmlTextWriterWriteFormatElement(writer, "maxspeed", "%lf", oai_emulation.topo_config.UE_mobility.UE_moving_dynamics.max_speed);
xmlTextWriterWriteFormatElement(writer, "minstay", "%lf", oai_emulation.topo_config.UE_mobility.UE_moving_dynamics.min_pause_time);
xmlTextWriterWriteFormatElement(writer, "maxstay", "%lf", oai_emulation.topo_config.UE_mobility.UE_moving_dynamics.max_pause_time);
}
// Close the element named HEADER.
xmlTextWriterEndElement(writer);
// set the output format of the XML file
xmlTextWriterSetIndent(writer, 1);
xmlTextWriterSetIndentString(writer, " ");
/* Start the document with the xml default for the version,
* encoding ISO 8859-1 and the default for the standalone
* declaration. */
xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
/* Start an element named "EXAMPLE". Since this is the first
* element, this will be the root element of the document. */
xmlTextWriterStartElement(writer, "universe");
/* Write an element named "X_ORDER_ID" as child of HEADER. */
xmlTextWriterWriteFormatElement(writer, "dimx", "%lf", oai_emulation.topo_config.area.x);
/* Write an element named "X_ORDER_ID" as child of HEADER. */
xmlTextWriterWriteFormatElement(writer, "dimy", "%lf", oai_emulation.topo_config.area.y);
xmlTextWriterWriteFormatElement(writer, "seed", "%d", 1);
xmlTextWriterStartElement(writer, "extension");
xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.simulations.TimeSimulation");
xmlTextWriterWriteFormatAttribute(writer, "param", "%lf", oai_emulation.emu_config.emu_time);
xmlTextWriterEndElement(writer);
xmlTextWriterStartElement(writer, "extension");
xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.spatialmodel.core.SpatialModel");
xmlTextWriterWriteFormatAttribute(writer, "max_x", "%lf", oai_emulation.topo_config.area.x);
xmlTextWriterWriteFormatAttribute(writer, "max_y", "%lf", oai_emulation.topo_config.area.y);
xmlTextWriterWriteAttribute(writer, "min_x", "0");
xmlTextWriterWriteAttribute(writer, "min_y", "0");
xmlTextWriterWriteFormatElement(writer, "dump_boundary_points", "%s", "false");
xmlTextWriterWriteFormatElement(writer, "separated_flow", "%s", "false");
xmlTextWriterWriteFormatElement(writer, "max_traffic_lights", "%d", 500);
xmlTextWriterEndElement(writer);
xmlTextWriterStartElement(writer, "extension");
xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.extensions.ReportNodeMobility");
strcpy(mobi_file, MOBI_XML_FOLDER);
strcat(mobi_file, filename);
xmlTextWriterWriteAttribute(writer, "output", mobi_file);
xmlTextWriterWriteFormatElement(writer, "step", "%d", 1);
xmlTextWriterEndElement(writer);
xmlTextWriterStartElement(writer, "nodegroup");
xmlTextWriterWriteAttribute(writer, "car2x", "false");
xmlTextWriterWriteAttribute(writer, "id", "");
xmlTextWriterWriteAttribute(writer, "n", "50");
xmlTextWriterWriteAttribute(writer, "type", "car");
xmlTextWriterStartElement(writer, "position");
xmlTextWriterWriteAttribute(writer, "random", "true");
xmlTextWriterWriteFormatElement(writer, "z", "%s", "0.0");
xmlTextWriterEndElement(writer);
xmlTextWriterStartElement(writer, "extension");
xmlTextWriterWriteAttribute(writer, "class", "de.uni_stuttgart.informatik.canu.mobisim.mobilitymodels.RandomWaypointWalk");
if (!strcmp(oai_emulation.topo_config.UE_mobility.UE_mobility_type.selected_option, "fixed")) {
xmlTextWriterWriteFormatElement(writer, "minspeed", "%d", 0);
xmlTextWriterWriteFormatElement(writer, "maxspeed", "%d", 0);
xmlTextWriterWriteFormatElement(writer, "minstay", "%d", 9999);
xmlTextWriterWriteFormatElement(writer, "maxstay", "%d", 9999);
} else if (!strcmp(oai_emulation.topo_config.UE_mobility.UE_mobility_type.selected_option, "random_waypoint")) {
xmlTextWriterWriteFormatElement(writer, "minspeed", "%lf", oai_emulation.topo_config.UE_mobility.UE_moving_dynamics.min_speed);
xmlTextWriterWriteFormatElement(writer, "maxspeed", "%lf", oai_emulation.topo_config.UE_mobility.UE_moving_dynamics.max_speed);
xmlTextWriterWriteFormatElement(writer, "minstay", "%lf", oai_emulation.topo_config.UE_mobility.UE_moving_dynamics.min_pause_time);
xmlTextWriterWriteFormatElement(writer, "maxstay", "%lf", oai_emulation.topo_config.UE_mobility.UE_moving_dynamics.max_pause_time);
}
// Close the element named HEADER.
xmlTextWriterEndElement(writer);
xmlTextWriterEndDocument(writer);
xmlTextWriterEndDocument(writer);
xmlFreeTextWriter(writer);
return MODULE_OK;
xmlFreeTextWriter(writer);
return MODULE_OK;
}
+5 -5
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -48,10 +48,10 @@ extern "C" {
/** @defgroup _config_mobi Config Mobigen
* @ingroup _fn
* @brief Generate configuration XML for mobigen
* @{*/
int config_mobi(char mobigen_filename[FILENAME_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]);
/* @}*/
* @{*/
int config_mobi(char mobigen_filename[FILENAME_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]);
/* @}*/
#ifdef __cplusplus
}
#endif
+41 -43
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -47,57 +47,55 @@
#include "UTIL/LOG/log.h"
/*----------------------------------------------------------------------------*/
int create_dir(char output_dir[DIR_LENGTH_MAX], char user_name[FILENAME_LENGTH_MAX / 2], char file_date[FILENAME_LENGTH_MAX / 2]) {
int create_dir(char output_dir[DIR_LENGTH_MAX], char user_name[FILENAME_LENGTH_MAX / 2], char file_date[FILENAME_LENGTH_MAX / 2])
{
char directory[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = "";
mode_t process_mask = umask(0);
char directory[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = "";
mode_t process_mask = umask(0);
//strcpy(directory, output_dir);
strncpy(directory, output_dir, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX);
directory[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - 1] = 0; // terminate string
struct stat st;
if(stat(directory, &st) != 0) { // if output_dir does not exist, we create it here
mkdir(directory, S_IRWXU | S_IRWXG | S_IRWXO);
LOG_I(OCG, "output_dir %s is created", directory);
}
strncpy(directory, output_dir, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX);
directory[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - 1] = 0; // terminate string
//strcat(directory, user_name);
strncat(directory, user_name, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(directory) - 1);
struct stat st;
mkdir(directory, S_IRWXU | S_IRWXG | S_IRWXO);
if(stat(directory, &st) != 0) { // if output_dir does not exist, we create it here
mkdir(directory, S_IRWXU | S_IRWXG | S_IRWXO);
LOG_I(OCG, "output_dir %s is created", directory);
}
// strcat(directory, "/");
//strcat(directory, file_date);
strncat(directory, "/", FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(directory) - 1);
strncat(directory, file_date, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(directory) - 1);
mkdir(directory, S_IRWXU | S_IRWXG |S_IRWXO);
strncat(directory, user_name, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(directory) - 1);
//char directory_extension[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX + 64] = "";
/*strcpy(directory_extension, directory); // to create some more folders
strcat(directory_extension, "/LOGS");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
mkdir(directory, S_IRWXU | S_IRWXG | S_IRWXO);
strcpy(directory_extension, directory);
strcat(directory_extension, "/PACKET_TRACE");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
strncat(directory, "/", FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(directory) - 1);
strncat(directory, file_date, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(directory) - 1);
strcpy(directory_extension, directory);
strcat(directory_extension, "/SCENARIO");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
mkdir(directory, S_IRWXU | S_IRWXG |S_IRWXO);
strcpy(directory_extension, directory);
strcat(directory_extension, "/SCENARIO/XML");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
//char directory_extension[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX + 64] = "";
/*strcpy(directory_extension, directory); // to create some more folders
strcat(directory_extension, "/LOGS");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
strcpy(directory_extension, directory);
strcat(directory_extension, "/SCENARIO/STATE");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
*/
umask(process_mask);
strcpy(directory_extension, directory);
strcat(directory_extension, "/PACKET_TRACE");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
strcpy(directory_extension, directory);
strcat(directory_extension, "/SCENARIO");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
strcpy(directory_extension, directory);
strcat(directory_extension, "/SCENARIO/XML");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
strcpy(directory_extension, directory);
strcat(directory_extension, "/SCENARIO/STATE");
mkdir(directory_extension, S_IRWXU | S_IRWXG |S_IRWXO);
*/
umask(process_mask);
LOG_I(OCG, "Directory for current emulation is created\n");
return MODULE_OK;
LOG_I(OCG, "Directory for current emulation is created\n");
return MODULE_OK;
}
+3 -3
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -48,8 +48,8 @@ extern "C" {
/** @defgroup _create_dir Create Dir
* @ingroup _fn
* @brief Create directory in OUTPUT_DIR for current emulation
* @{*/
int create_dir(char output_dir[DIR_LENGTH_MAX], char user_name[FILENAME_LENGTH_MAX / 2], char file_date[FILENAME_LENGTH_MAX / 2]);
* @{*/
int create_dir(char output_dir[DIR_LENGTH_MAX], char user_name[FILENAME_LENGTH_MAX / 2], char file_date[FILENAME_LENGTH_MAX / 2]);
/* @}*/
#ifdef __cplusplus
+69 -67
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -49,75 +49,77 @@
/*----------------------------------------------------------------------------*/
int detect_file(char src_dir[DIR_LENGTH_MAX], char is_local_server[FILENAME_LENGTH_MAX]) {
DIR *dir = NULL;
struct dirent *file = NULL;
char template[FILENAME_LENGTH_MAX] = "";
char manual[FILENAME_LENGTH_MAX] = "";
int detect_file(char src_dir[DIR_LENGTH_MAX], char is_local_server[FILENAME_LENGTH_MAX])
{
DIR *dir = NULL;
struct dirent *file = NULL;
char template[FILENAME_LENGTH_MAX] = "";
char manual[FILENAME_LENGTH_MAX] = "";
if((dir = opendir(src_dir)) == NULL) {
LOG_E(OCG, "Folder %s for detecting the XML configuration file is not found\n", src_dir);
return MODULE_ERROR;
}
if((dir = opendir(src_dir)) == NULL) {
LOG_E(OCG, "Folder %s for detecting the XML configuration file is not found\n", src_dir);
return MODULE_ERROR;
}
while((file = readdir(dir)) != NULL) {
if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) {
if(file->d_type != DT_DIR) {
if ((!strcmp(is_local_server, "0")) || (!strcmp(is_local_server, "-1"))) { // for EURECOM web or local user without specifying the file name
strncpy(template, file->d_name, sizeof("template") - 1);
strncpy(manual, file->d_name, sizeof("manual") - 1);
if ((!strcmp(template, "template")) || (!strcmp(manual, "manual"))) { // should skip the templates and the manual XML files
} else {
if (strlen(file->d_name) <= FILENAME_LENGTH_MAX) {
strcpy(filename, file->d_name);
LOG_I(OCG, "Configuration file \"%s\" is detected\n", filename);
closedir(dir);
return MODULE_OK; // find a good file and return
} else {
LOG_E(OCG, "File name too long: char filename[] should be less than 64 characters\n");
closedir(dir);
return MODULE_ERROR;
}
}
} else { // should use a template or a manual XML file
strncpy(template, is_local_server, sizeof("template") - 1);
strncpy(manual, is_local_server, sizeof("manual") - 1);
if ((!strcmp(template, "template")) || (!strcmp(manual, "manual"))) {
strcpy(filename, is_local_server);
} else {
strcpy(filename, "template_");
strcat(filename, is_local_server);
strcat(filename, ".xml");
}
while((file = readdir(dir)) != NULL) {
if(strcmp(file->d_name, ".") && strcmp(file->d_name, "..")) {
if(file->d_type != DT_DIR) {
if ((!strcmp(is_local_server, "0")) || (!strcmp(is_local_server, "-1"))) { // for EURECOM web or local user without specifying the file name
strncpy(template, file->d_name, sizeof("template") - 1);
strncpy(manual, file->d_name, sizeof("manual") - 1);
char check_src_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX];
//strcpy(check_src_file, src_dir);
//strcat(check_src_file, filename);
strncpy(check_src_file, src_dir, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX);
check_src_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - 1] = 0; // terminate string
strncat(check_src_file, filename, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(check_src_file) - 1);
struct stat st;
if(stat(check_src_file, &st) != 0) {
LOG_E(OCG, "file %s does not exist\n", check_src_file);
closedir(dir);
return MODULE_ERROR;
} else {
LOG_I(OCG, "template/manual file \"%s\" is used\n", filename);
closedir(dir);
return MODULE_OK;
}
}
} else { // this option is not used at this moment : NO directory should be put in the src_dir
//detect_file(strncat(src_dir, file->d_name, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX));
}
}
}
if ((!strcmp(template, "template")) || (!strcmp(manual, "manual"))) { // should skip the templates and the manual XML files
closedir(dir);
} else {
if (strlen(file->d_name) <= FILENAME_LENGTH_MAX) {
strcpy(filename, file->d_name);
LOG_I(OCG, "Configuration file \"%s\" is detected\n", filename);
closedir(dir);
return MODULE_OK; // find a good file and return
} else {
LOG_E(OCG, "File name too long: char filename[] should be less than 64 characters\n");
closedir(dir);
return MODULE_ERROR;
}
}
} else { // should use a template or a manual XML file
strncpy(template, is_local_server, sizeof("template") - 1);
strncpy(manual, is_local_server, sizeof("manual") - 1);
if (strcmp(is_local_server, "0") && strcmp(is_local_server, "-1")) {
LOG_E(OCG, "file %s does not exist in directory %s\n", is_local_server, src_dir);
return MODULE_ERROR;
} else return NO_FILE;
if ((!strcmp(template, "template")) || (!strcmp(manual, "manual"))) {
strcpy(filename, is_local_server);
} else {
strcpy(filename, "template_");
strcat(filename, is_local_server);
strcat(filename, ".xml");
}
char check_src_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX];
strncpy(check_src_file, src_dir, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX);
check_src_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - 1] = 0; // terminate string
strncat(check_src_file, filename, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(check_src_file) - 1);
struct stat st;
if(stat(check_src_file, &st) != 0) {
LOG_E(OCG, "file %s does not exist\n", check_src_file);
closedir(dir);
return MODULE_ERROR;
} else {
LOG_I(OCG, "template/manual file \"%s\" is used\n", filename);
closedir(dir);
return MODULE_OK;
}
}
} else { // this option is not used at this moment : NO directory should be put in the src_dir
//detect_file(strncat(src_dir, file->d_name, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX));
}
}
}
closedir(dir);
if (strcmp(is_local_server, "0") && strcmp(is_local_server, "-1")) {
LOG_E(OCG, "file %s does not exist in directory %s\n", is_local_server, src_dir);
return MODULE_ERROR;
} else return NO_FILE;
}
+4 -4
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -48,9 +48,9 @@ extern "C" {
/** @defgroup _detect_file Detect File
* @ingroup _fn
* @brief Detect new XML configuration file in USER_XML_FOLDER
* @{*/
//int detect_file(int argc, char *argv[], char folder[DIR_LENGTH_MAX]);
int detect_file(char folder[DIR_LENGTH_MAX], char is_local_server[FILENAME_LENGTH_MAX]);
* @{*/
//int detect_file(int argc, char *argv[], char folder[DIR_LENGTH_MAX]);
int detect_file(char folder[DIR_LENGTH_MAX], char is_local_server[FILENAME_LENGTH_MAX]);
/* @}*/
#ifdef __cplusplus
+3 -3
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -37,12 +37,12 @@ extern char src_file[]; /*!< \brief USER_XML_FOLDER/user_name.file_date.xml or D
extern char dst_dir[]; /*!< \brief user_name/file_date/ */
extern int copy_or_move; /*!< \brief indicating if the current emulation is with a local XML or an XML generated from the web portal */
extern int file_detected; /*!< \brief indicate whether a new file is detected */
/* @}*/
/* @}*/
/** @defgroup _oks OCG Module State Indicators
* @ingroup _OCG
* @brief Indicate whether a module has processed successfully
* @{*/
* @{*/
extern int get_opt_OK; /*!< \brief value: -9999, -1, 0 or 1 */
extern int detect_file_OK; /*!< \brief value: -9999, -1 or 0 */
extern int parse_filename_OK; /*!< \brief value: -9999, -1 or 0 */
+18 -18
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -49,40 +49,40 @@
/*----------------------------------------------------------------------------*/
int generate_report(char dst_dir[DIR_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]) {
// for the xml writer, refer to http://xmlsoft.org/html/libxml-xmlwriter.html
int generate_report(char dst_dir[DIR_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX])
{
// for the xml writer, refer to http://xmlsoft.org/html/libxml-xmlwriter.html
char dst_file[FILENAME_LENGTH_MAX + DIR_LENGTH_MAX] = "";
//strcat(dst_file, dst_dir);
//strcat(dst_file, filename);
strncat(dst_file, dst_dir, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(dst_file) - 1);
strncat(dst_file, filename, FILENAME_LENGTH_MAX + DIR_LENGTH_MAX - strlen(dst_file) - 1);
xmlTextWriterPtr writer;
writer = xmlNewTextWriterFilename(dst_file, 0);
// set the output format of the XML file
// set the output format of the XML file
xmlTextWriterSetIndent(writer, 1);
xmlTextWriterSetIndentString(writer,(unsigned char*) " ");
xmlTextWriterStartDocument(writer, NULL, NULL, NULL);
/* Write an element named "X_ORDER_ID" as child of HEADER. */
xmlTextWriterWriteFormatElement(writer,(unsigned char*) "COMMENT ", " in this output file, %d means NOT_PROCESSED; %d means NO_FILE; %d means ERROR; %d means OK ", MODULE_NOT_PROCESSED, NO_FILE, MODULE_ERROR, MODULE_OK);
xmlTextWriterWriteFormatElement(writer,(unsigned char*) "COMMENT ", " in this output file, %d means NOT_PROCESSED; %d means NO_FILE; %d means ERROR; %d means OK ", MODULE_NOT_PROCESSED,
NO_FILE, MODULE_ERROR, MODULE_OK);
xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_GET_OPT ", " %d ", get_opt_OK);
xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_DETECT_FILE ", " %d ", detect_file_OK);
xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_PARSE_FILENAME", " %d ", parse_filename_OK);
xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_CREATE_DIR ", " %d ", create_dir_OK);
xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_PARSE_XML ", " %d ", parse_XML_OK);
xmlTextWriterWriteFormatElement(writer,(unsigned char*) "OCG_SAVE_XML ", " %d ", save_XML_OK);
// xmlTextWriterWriteFormatElement(writer, "OCG_CALL_EMU ", " %d ", call_emu_OK);
// xmlTextWriterWriteFormatElement(writer, "OCG_CALL_EMU ", " %d ", call_emu_OK);
xmlTextWriterEndDocument(writer);
xmlFreeTextWriter(writer);
LOG_I(OCG, "A report of OCG is generated in directory \"%s\"\n\n", dst_dir);
return MODULE_OK;
}
+3 -3
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -48,8 +48,8 @@ extern "C" {
/** @defgroup _generate_report Generate report
* @ingroup _fn
* @brief Generate a report to show the states of OCG modules
* @{*/
int generate_report(char dst_dir[DIR_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]);
* @{*/
int generate_report(char dst_dir[DIR_LENGTH_MAX], char filename[FILENAME_LENGTH_MAX]);
/* @}*/
#ifdef __cplusplus
+21 -18
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -51,24 +51,27 @@
char filename[FILENAME_LENGTH_MAX];
int get_opt(int argc, char *argv[]) {
char opts;
int get_opt(int argc, char *argv[])
{
char opts;
while((opts = getopt(argc, argv, "f:h")) != -1) {
while((opts = getopt(argc, argv, "f:h")) != -1) {
switch (opts) {
case 'f' :
strcpy(filename, optarg);
LOG_D(OCG, "User specified configuration file is \"%s\"\n", filename);
return MODULE_OK;
case 'h' :
LOG_I(OCG, "OCG command : OCG -f \"filename.xml\"\n");
return GET_HELP;
default :
LOG_E(OCG, "OCG command : OCG -f \"filename.xml\"\n");
return GET_HELP;
}
}
switch (opts) {
case 'f' :
strcpy(filename, optarg);
LOG_D(OCG, "User specified configuration file is \"%s\"\n", filename);
return MODULE_OK;
return NO_FILE;
case 'h' :
LOG_I(OCG, "OCG command : OCG -f \"filename.xml\"\n");
return GET_HELP;
default :
LOG_E(OCG, "OCG command : OCG -f \"filename.xml\"\n");
return GET_HELP;
}
}
return NO_FILE;
}
+5 -5
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
@@ -47,10 +47,10 @@ extern "C" {
/** @defgroup _get_opt Get Opt
* @ingroup _fn
* @brief Get options of the OCG command, e.g. "OCG -f" and "OCG -h"
* @{*/
int get_opt(int argc, char *argv[]);
/* @}*/
* @{*/
int get_opt(int argc, char *argv[]);
/* @}*/
#ifdef __cplusplus
}
#endif
+1 -1
View File
@@ -21,7 +21,7 @@
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More