merge with master
This commit is contained in:
+368
-332
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
+33
-33
@@ -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
|
||||
|
||||
|
||||
+80
-80
@@ -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
|
||||
|
||||
|
||||
+16
-16
@@ -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
|
||||
|
||||
|
||||
+43
-43
@@ -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
|
||||
|
||||
|
||||
+14
-14
@@ -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
|
||||
|
||||
|
||||
+4
-6
@@ -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
-11
@@ -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 )
|
||||
|
||||
+13
-20
@@ -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
-13
@@ -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;
|
||||
}
|
||||
|
||||
+15
-20
@@ -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];
|
||||
}
|
||||
|
||||
+15
-21
@@ -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)++;
|
||||
}
|
||||
|
||||
+4
-5
@@ -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
|
||||
|
||||
+11
-12
@@ -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 );
|
||||
|
||||
+20
-25
@@ -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 */
|
||||
|
||||
+39
-48
@@ -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 );
|
||||
|
||||
+3
-6
@@ -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 );
|
||||
}
|
||||
|
||||
+5
-5
@@ -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 );
|
||||
|
||||
|
||||
+5
-9
@@ -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;
|
||||
}
|
||||
|
||||
+10
-10
@@ -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;
|
||||
|
||||
+9
-11
@@ -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 );
|
||||
|
||||
+7
-9
@@ -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;
|
||||
|
||||
+7
-9
@@ -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
|
||||
|
||||
+10
-11
@@ -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
-12
@@ -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;
|
||||
|
||||
|
||||
+31
-35
@@ -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 );
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
}
|
||||
}*/
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
+91
-87
@@ -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"
|
||||
|
||||
@@ -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[];
|
||||
|
||||
@@ -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
@@ -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_) */
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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");
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
@@ -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
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
+1123
-1118
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
Reference in New Issue
Block a user