diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.c b/openair2/LAYER2/PROTO_AGENT/proto_agent.c
new file mode 100644
index 0000000000..c78c9d93d4
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.c
@@ -0,0 +1,499 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent.h
+ * \brief top level enb agent receive thread and itti task
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#include "proto_agent_common.h"
+#include "log.h"
+#include "proto_agent.h"
+//#include "enb_agent_mac_defs.h" // TODO: Check if they are needed
+
+//#include "enb_agent_extern.h" // TODO: Check if they are needed for this implementation
+
+#include "assertions.h"
+
+#include "proto_agent_net_comm.h" // TODO: Check if they are needed
+#include "proto_agent_async.h"
+
+//#define TEST_TIMER
+
+proto_agent_instance_t proto_agent[NUM_MAX_ENB];
+proto_agent_instance_t proto_server[NUM_MAX_ENB];
+
+// Use the same configuration file for the moment
+
+char in_ip[40];
+static uint16_t in_port;
+char local_cache[40];
+
+void *send_thread(void *args);
+void *client_receive_thread(void *args);
+void *server_receive_thread(void *args);
+//void *server_send_thread(void *args);
+pthread_t new_thread(void *(*f)(void *), void *b);
+//Protocol__ProgranMessage *enb_agent_timeout_prp(void* args);
+Protocol__FlexsplitMessage *proto_agent_timeout_fsp(void* args);
+
+
+/*
+ * enb agent task mainly wakes up the tx thread for periodic and oneshot messages to the controller
+ * and can interact with other itti tasks
+*/
+void *proto_agent_task(void *args){
+
+ proto_agent_instance_t *d = (proto_agent_instance_t *) args;
+ Protocol__FlexsplitMessage *msg;
+ void *data;
+ int size;
+ err_code_t err_code;
+ int priority;
+
+ MessageDef *msg_p = NULL;
+ const char *msg_name = NULL;
+ instance_t instance;
+ int result;
+
+
+ itti_mark_task_ready(TASK_PROTO_AGENT);
+
+ do {
+ // Wait for a message
+ itti_receive_msg (TASK_PROTO_AGENT, &msg_p);
+ DevAssert(msg_p != NULL);
+ msg_name = ITTI_MSG_NAME (msg_p);
+ instance = ITTI_MSG_INSTANCE (msg_p);
+
+ switch (ITTI_MSG_ID(msg_p)) {
+ case TERMINATE_MESSAGE:
+ itti_exit_task ();
+ break;
+
+ case MESSAGE_TEST:
+ LOG_I(PROTO_AGENT, "Received %s\n", ITTI_MSG_NAME(msg_p));
+ break;
+
+ case TIMER_HAS_EXPIRED:
+ msg = proto_agent_process_timeout(msg_p->ittiMsg.timer_has_expired.timer_id, msg_p->ittiMsg.timer_has_expired.arg);
+ if (msg != NULL){
+ data=proto_agent_pack_message(msg,&size);
+ if (proto_agent_msg_send(d->enb_id, PROTO_AGENT_DEFAULT, data, size, priority)) {
+ err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
+ goto error;
+ }
+
+ LOG_D(PROTO_AGENT,"sent message with size %d\n", size);
+ }
+ break;
+
+ default:
+ LOG_E(PROTO_AGENT, "Received unexpected message %s\n", msg_name);
+ break;
+ }
+
+ result = itti_free (ITTI_MSG_ORIGIN_ID(msg_p), msg_p);
+ AssertFatal (result == EXIT_SUCCESS, "Failed to free memory (%d)!\n", result);
+ continue;
+ error:
+ LOG_E(PROTO_AGENT,"proto_agent_task: error %d occured\n",err_code);
+ } while (1);
+
+ return NULL;
+}
+
+void *send_thread(void *args) {
+
+ proto_agent_instance_t *d = args;
+ void *data;
+ int size;
+ int priority;
+ err_code_t err_code;
+
+ Protocol__FlexsplitMessage *msg;
+
+ void **init_msg;
+ int msg_flag = 0;
+ msg_flag = proto_agent_hello(d->enb_id, args, init_msg);
+
+ if (msg_flag == -1)
+ {
+ LOG_E( PROTO_AGENT, "Server did not create the message\n");
+ goto error;
+ }
+ if (proto_agent_msg_send(d->enb_id, PROTO_AGENT_DEFAULT, init_msg, sizeof(Protocol__FlexsplitMessage), 0)) {
+ err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
+ goto error;
+ }
+
+ LOG_D(PROTO_AGENT,"sent message with size %d\n", size);
+
+
+// msg=proto_agent_handle_message(d->enb_id, data, size);
+
+ free(data);
+
+ free(*init_msg);
+ // check if there is something to send back to the controller
+ if (msg != NULL){
+ data=proto_agent_pack_message(msg,&size);
+
+ if (proto_agent_msg_send(d->enb_id, PROTO_AGENT_DEFAULT, data, size, priority)) {
+ err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
+ goto error;
+ }
+
+ LOG_D(PROTO_AGENT,"sent message with size %d\n", size);
+ }
+
+ //}
+
+ return NULL;
+
+error:
+ LOG_E(PROTO_AGENT,"receive_thread: error %d occured\n",err_code);
+ return NULL;
+}
+
+void *receive_thread(void *args) {
+
+ proto_agent_instance_t *d = args;
+ void *data;
+ int size;
+ int priority;
+ err_code_t err_code;
+
+ Protocol__FlexsplitMessage *msg;
+
+ while (1) {
+ if (proto_agent_msg_recv(d->enb_id, PROTO_AGENT_DEFAULT, &data, &size, &priority)) {
+ err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
+ goto error;
+ }
+
+ LOG_D(PROTO_AGENT,"received message with size %d\n", size);
+
+
+ msg=proto_agent_handle_message(d->enb_id, data, size);
+
+ free(data);
+
+ // check if there is something to send back to the controller
+ if (msg != NULL){
+ data=proto_agent_pack_message(msg,&size);
+
+ if (proto_agent_msg_send(d->enb_id, PROTO_AGENT_DEFAULT, data, size, priority)) {
+ err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENQUEUING;
+ goto error;
+ }
+
+ LOG_D(PROTO_AGENT,"sent message with size %d\n", size);
+ }
+
+ }
+
+ return NULL;
+
+error:
+ LOG_E(PROTO_AGENT,"receive_thread: error %d occured\n",err_code);
+ return NULL;
+}
+
+
+/* utility function to create a thread */
+pthread_t new_thread(void *(*f)(void *), void *b) {
+ pthread_t t;
+ pthread_attr_t att;
+
+ if (pthread_attr_init(&att)){
+ fprintf(stderr, "pthread_attr_init err\n");
+ exit(1);
+ }
+ if (pthread_attr_setdetachstate(&att, PTHREAD_CREATE_DETACHED)) {
+ fprintf(stderr, "pthread_attr_setdetachstate err\n");
+ exit(1);
+ }
+ if (pthread_create(&t, &att, f, b)) {
+ fprintf(stderr, "pthread_create err\n");
+ exit(1);
+ }
+ if (pthread_attr_destroy(&att)) {
+ fprintf(stderr, "pthread_attr_destroy err\n");
+ exit(1);
+ }
+
+ return t;
+}
+
+
+// This is the only function that we will call for the moment from this file
+int proto_server_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){
+
+ int channel_id;
+
+ printf("INSIDE PROTO_SERVER_START\n");
+ // Maybe change the RAN_LTE_OAI to protocol?? (e.g. PDCP)
+ set_enb_vars(mod_id, RAN_LTE_OAI);
+ proto_server[mod_id].enb_id = mod_id;
+
+ /*
+ * check the configuration - Getting all the values from the config file
+ */
+ if (enb_properties->properties[mod_id]->proto_agent_cache != NULL) {
+ strncpy(local_cache, enb_properties->properties[mod_id]->proto_agent_cache, sizeof(local_cache));
+ local_cache[sizeof(local_cache) - 1] = 0;
+ } else {
+ strcpy(local_cache, DEFAULT_PROTO_AGENT_CACHE);
+ }
+
+ if (enb_properties->properties[mod_id]->proto_agent_ipv4_address != NULL) {
+ strncpy(in_ip, enb_properties->properties[mod_id]->proto_agent_ipv4_address, sizeof(in_ip) );
+ in_ip[sizeof(in_ip) - 1] = 0; // terminate string
+ } else {
+ strcpy(in_ip, DEFAULT_PROTO_AGENT_IPv4_ADDRESS );
+ }
+
+ if (enb_properties->properties[mod_id]->proto_agent_port != 0 ) {
+ in_port = enb_properties->properties[mod_id]->proto_agent_port;
+ } else {
+ in_port = DEFAULT_PROTO_AGENT_PORT ;
+ }
+ LOG_I(ENB_AGENT,"starting PROTO agent SERVER for module id %d on ipv4 %s, port %d\n",
+ proto_server[mod_id].enb_id,
+ in_ip,
+ in_port);
+
+ /*
+ * Initialize the channel container
+ */
+ proto_agent_init_channel_container();
+
+ /*Create the async channel info*/
+ printf("Before creating the async server channe;\n");
+ proto_agent_instance_t *channel_info = proto_server_async_channel_info(mod_id, in_ip, in_port);
+ printf("After creating the async server channe;\n");
+
+ /*Create a channel using the async channel info*/
+ printf("Before creating the receive channel\n");
+
+ channel_id = proto_agent_create_channel((void *) channel_info,
+ proto_agent_async_msg_send,
+ proto_agent_async_msg_recv,
+ proto_agent_async_release);
+
+ printf("After creating the receive channel\n");
+
+ if (channel_id <= 0) {
+ goto error;
+ }
+ printf("Before getting ing the receive thread\n");
+
+ proto_agent_channel_t *channel = get_channel(channel_id);
+ printf("After getting ing the receive thread\n");
+
+ if (channel == NULL) {
+ goto error;
+ }
+
+ /*Register the channel for all underlying agents (use ENB_AGENT_MAX)*/
+ printf("Before registering the receive channel \n");
+
+ proto_agent_register_channel(mod_id, channel, ENB_AGENT_MAX);
+ printf("After registering the receive channel\n");
+
+ /*Example of registration for a specific agent(MAC):
+ *enb_agent_register_channel(mod_id, channel, ENB_AGENT_MAC);
+ */
+
+ /*Initialize the continuous MAC stats update mechanism*/
+ // For the moment we do not need this
+ // enb_agent_init_cont_mac_stats_update(mod_id);
+ printf("Before initializing the receive thread\n");
+ //new_thread(send_thread, &proto_server[mod_id]);
+ new_thread(receive_thread, &proto_server[mod_id]);
+ printf("After initializing the receive thread\n");
+
+ /*
+ * initilize a timer
+ */
+ printf("Before initializing the receive timer\n");
+
+ proto_agent_init_timer();
+
+ printf("After initializing the receive thread\n");
+
+ /*
+ * start the enb agent task for tx and interaction with the underlying network function
+ */
+
+ if (itti_create_task (TASK_PROTO_AGENT, proto_agent_task, (void *) &proto_server[mod_id]) < 0) {
+ LOG_E(PROTO_AGENT, "Create task for eNB Agent failed\n");
+ return -1;
+ }
+
+ new_thread(send_thread, &proto_server[mod_id]);
+
+
+ LOG_I(PROTO_AGENT,"server ends\n");
+ return 0;
+
+error:
+ LOG_I(PROTO_AGENT,"there was an error\n");
+ return 1;
+
+}
+
+int proto_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){
+
+ int channel_id;
+
+ printf("Starting client\n");
+
+ // Maybe change the RAN_LTE_OAI to protocol?? (e.g. PDCP)
+ set_enb_vars(mod_id, RAN_LTE_OAI);
+ proto_agent[mod_id].enb_id = mod_id;
+
+ /*
+ * check the configuration - Getting all the values from the config file
+ */
+ if (enb_properties->properties[mod_id]->proto_agent_cache != NULL) {
+ strncpy(local_cache, enb_properties->properties[mod_id]->proto_agent_cache, sizeof(local_cache));
+ local_cache[sizeof(local_cache) - 1] = 0;
+ } else {
+ strcpy(local_cache, DEFAULT_PROTO_AGENT_CACHE);
+ }
+
+ if (enb_properties->properties[mod_id]->proto_agent_ipv4_address != NULL) {
+ strncpy(in_ip, enb_properties->properties[mod_id]->proto_agent_ipv4_address, sizeof(in_ip) );
+ in_ip[sizeof(in_ip) - 1] = 0; // terminate string
+ } else {
+ strcpy(in_ip, DEFAULT_PROTO_AGENT_IPv4_ADDRESS );
+ }
+
+ if (enb_properties->properties[mod_id]->proto_agent_port != 0 ) {
+ in_port = enb_properties->properties[mod_id]->proto_agent_port;
+ } else {
+ in_port = DEFAULT_PROTO_AGENT_PORT ;
+ }
+ LOG_I(PROTO_AGENT,"starting PROTO agent client for module id %d on ipv4 %s, port %d\n",
+ proto_agent[mod_id].enb_id,
+ in_ip,
+ in_port);
+
+ /*
+ * Initialize the channel container
+ */
+ proto_agent_init_channel_container();
+
+ /*Create the async channel info*/
+ proto_agent_instance_t *channel_info = proto_agent_async_channel_info(mod_id, in_ip, in_port);
+
+ /*Create a channel using the async channel info*/
+ channel_id = proto_agent_create_channel((void *) channel_info,
+ proto_agent_async_msg_send,
+ proto_agent_async_msg_recv,
+ proto_agent_async_release);
+
+
+ if (channel_id <= 0) {
+ goto error;
+ }
+
+ proto_agent_channel_t *channel = get_channel(channel_id);
+
+ if (channel == NULL) {
+ goto error;
+ }
+
+ /*Register the channel for all underlying agents (use ENB_AGENT_MAX)*/
+ proto_agent_register_channel(mod_id, channel, ENB_AGENT_MAX);
+
+ /*Example of registration for a specific agent(MAC):
+ *enb_agent_register_channel(mod_id, channel, ENB_AGENT_MAC);
+ */
+
+ /*Initialize the continuous MAC stats update mechanism*/
+ // For the moment we do not need this
+ // enb_agent_init_cont_mac_stats_update(mod_id);
+
+ new_thread(receive_thread, &proto_agent[mod_id]);
+
+ /*Initialize and register the mac xface. Must be modified later
+ *for more flexibility in agent management */
+ // We do not need this
+ // AGENT_MAC_xface *mac_agent_xface = (AGENT_MAC_xface *) malloc(sizeof(AGENT_MAC_xface));
+ // enb_agent_register_mac_xface(mod_id, mac_agent_xface);
+
+ /*
+ * initilize a timer
+ */
+
+ proto_agent_init_timer();
+
+ /*
+ * Initialize the mac agent
+ */
+ //enb_agent_init_mac_agent(mod_id);
+
+ /*
+ * start the enb agent task for tx and interaction with the underlying network function
+ */
+
+ if (itti_create_task (TASK_PROTO_AGENT, proto_agent_task, (void *) &proto_agent[mod_id]) < 0) {
+ LOG_E(PROTO_AGENT, "Create task for eNB Agent failed\n");
+ return -1;
+ }
+
+ LOG_I(PROTO_AGENT,"client ends\n");
+ return 0;
+
+error:
+ LOG_I(PROTO_AGENT,"there was an error\n");
+ return 1;
+
+}
+
+
+
+
+Protocol__FlexsplitMessage *proto_agent_timeout(void* args){
+
+ // enb_agent_timer_args_t *timer_args = calloc(1, sizeof(*timer_args));
+ //memcpy (timer_args, args, sizeof(*timer_args));
+ proto_agent_timer_args_t *timer_args = (proto_agent_timer_args_t *) args;
+
+ LOG_I(PROTO_AGENT, "proto_agent %d timeout\n", timer_args->mod_id);
+ //LOG_I(ENB_AGENT, "eNB action %d ENB flags %d \n", timer_args->cc_actions,timer_args->cc_report_flags);
+ //LOG_I(ENB_AGENT, "UE action %d UE flags %d \n", timer_args->ue_actions,timer_args->ue_report_flags);
+
+ return NULL;
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent.h b/openair2/LAYER2/PROTO_AGENT/proto_agent.h
new file mode 100644
index 0000000000..b0d6020ce6
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent.h
@@ -0,0 +1,51 @@
+
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file proto_agent.h
+ * \brief top level protocol agent
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#ifndef PROTO_AGENT_H_
+#define PROTO_AGENT_H_
+
+#include "ENB_APP/enb_config.h" // for enb properties
+#include "proto_agent_common.h"
+
+int proto_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties);
+int proto_server_start(mid_t mod_id, const Enb_properties_array_t* enb_properties);
+
+int proto_agent_stop(mid_t mod_id);
+
+void *proto_agent_task(void *args);
+
+#endif
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c
new file mode 100644
index 0000000000..6299479bc4
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.c
@@ -0,0 +1,154 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_async.c
+ * \brief channel implementation for async interface
+ * \author Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#include "proto_agent_async.h"
+#include "proto_agent_defs.h"
+
+#include "log.h"
+
+
+proto_agent_async_channel_t * proto_server_async_channel_info(mid_t mod_id, char *dst_ip, uint16_t dst_port) {
+
+ proto_agent_async_channel_t *channel;
+ channel = (proto_agent_async_channel_t *) malloc(sizeof(proto_agent_channel_t));
+
+ if (channel == NULL)
+ goto error;
+
+ channel->enb_id = mod_id;
+ /*Create a socket*/
+ printf("Starting async server\n");
+ new_thread(new_link_server, (void *) &dst_port);
+ channel->link = (void *) &dst_port;
+ printf("Started async server\n");
+ if (channel->link == NULL) goto error;
+
+ LOG_I(PROTO_AGENT,"starting proto agent server for module id %d on ipv4 %s, port %d\n",
+ channel->enb_id,
+ dst_ip,
+ dst_port);
+
+ /*
+ * create a message queue
+ */
+
+ channel->send_queue = new_message_queue();
+ if (channel->send_queue == NULL) goto error;
+ channel->receive_queue = new_message_queue();
+ if (channel->receive_queue == NULL) goto error;
+
+ /*
+ * create a link manager
+ */
+ channel->manager = create_link_manager(channel->send_queue, channel->receive_queue, channel->link);
+ if (channel->manager == NULL) goto error;
+
+ return channel;
+
+ error:
+ LOG_I(PROTO_AGENT,"there was an error\n");
+ return 1;
+}
+
+
+proto_agent_async_channel_t * proto_agent_async_channel_info(mid_t mod_id, char *dst_ip, uint16_t dst_port) {
+
+ proto_agent_async_channel_t *channel;
+ channel = (proto_agent_async_channel_t *) malloc(sizeof(proto_agent_channel_t));
+
+ if (channel == NULL)
+ goto error;
+
+ channel->enb_id = mod_id;
+ /*Create a socket*/
+ channel->link = new_link_client(dst_ip, dst_port);
+
+ if (channel->link == NULL) goto error;
+
+
+ LOG_I(PROTO_AGENT,"starting proto agent client for module id %d on ipv4 %s, port %d\n",
+ channel->enb_id,
+ dst_ip,
+ dst_port);
+
+ /*
+ * create a message queue
+ */
+
+ channel->send_queue = new_message_queue();
+ if (channel->send_queue == NULL) goto error;
+ channel->receive_queue = new_message_queue();
+ if (channel->receive_queue == NULL) goto error;
+
+ /*
+ * create a link manager
+ */
+ channel->manager = create_link_manager(channel->send_queue, channel->receive_queue, channel->link);
+ if (channel->manager == NULL) goto error;
+
+ return channel;
+
+ error:
+ LOG_I(PROTO_AGENT,"there was an error\n");
+ return 1;
+}
+
+int proto_agent_async_msg_send(void *data, int size, int priority, void *channel_info) {
+ proto_agent_async_channel_t *channel;
+ channel = (proto_agent_channel_t *)channel_info;
+
+ return message_put(channel->send_queue, data, size, priority);
+}
+
+int proto_agent_async_msg_recv(void **data, int *size, int *priority, void *channel_info) {
+ proto_agent_async_channel_t *channel;
+ channel = (proto_agent_async_channel_t *)channel_info;
+
+ return message_get(channel->receive_queue, data, size, priority);
+}
+
+void proto_agent_async_release(proto_agent_channel_t *channel) {
+ proto_agent_async_channel_t *channel_info;
+ channel_info = (proto_agent_async_channel_t *) channel->channel_info;
+
+ destroy_link_manager(channel_info->manager);
+
+ destroy_message_queue(channel_info->send_queue);
+ destroy_message_queue(channel_info->receive_queue);
+
+ close_link(channel_info->link);
+ free(channel_info);
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h
new file mode 100644
index 0000000000..e6abc72e6e
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_async.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_async.h
+ * \brief channel implementation for async interface
+ * \author Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#ifndef PROTO_AGENT_ASYNC_H_
+#define PROTO_AGENT_ASYNC_H_
+
+#include "proto_agent_net_comm.h"
+
+typedef struct {
+ mid_t enb_id;
+ socket_link_t *link;
+ message_queue_t *send_queue;
+ message_queue_t *receive_queue;
+ link_manager_t *manager;
+} proto_agent_async_channel_t;
+
+proto_agent_async_channel_t * proto_agent_async_channel_info(mid_t mod_id, char *dst_ip, uint16_t dst_port);
+proto_agent_async_channel_t * proto_server_async_channel_info(mid_t mod_id, char *dst_ip, uint16_t dst_port);
+
+int proto_agent_async_msg_send(void *data, int size, int priority, void *channel_info);
+
+int proto_agent_async_msg_recv(void **data, int *size, int *priority, void *channel_info);
+
+void proto_agent_async_release(proto_agent_channel_t *channel);
+
+
+#endif /*PROTO_AGENT_ASYNC_H_*/
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
new file mode 100644
index 0000000000..0e6ed7d03b
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.c
@@ -0,0 +1,432 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file proto_agent_common.c
+ * \brief common primitives for all agents
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#include
+#include
+#include
+
+#include "proto_agent_common.h"
+#include "PHY/extern.h"
+#include "log.h"
+
+#include "RRC/LITE/extern.h"
+#include "RRC/L2_INTERFACE/openair_rrc_L2_interface.h"
+#include "rrc_eNB_UE_context.h"
+
+void * enb[NUM_MAX_ENB];
+void * enb_ue[NUM_MAX_ENB];
+void * enb_rrc[NUM_MAX_ENB];
+/*
+ * message primitives
+ */
+
+int proto_agent_serialize_message(Protocol__FlexsplitMessage *msg, void **buf, int *size) {
+
+ *size = protocol__flexsplit_message__get_packed_size(msg);
+
+ *buf = malloc(*size);
+ if (buf == NULL)
+ goto error;
+
+ protocol__flexsplit_message__pack(msg, *buf);
+
+ return 0;
+
+ error:
+ LOG_E(PROTO_AGENT, "an error occured\n"); // change the com
+ return -1;
+}
+
+
+
+/* We assume that the buffer size is equal to the message size.
+ Should be chekced durint Tx/Rx */
+int proto_agent_deserialize_message(void *data, int size, Protocol__FlexsplitMessage **msg) {
+ *msg = protocol__flexsplit_message__unpack(NULL, size, data);
+ if (*msg == NULL)
+ goto error;
+
+ return 0;
+
+ error:
+ LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+ return -1;
+}
+
+
+
+int fsp_create_header(xid_t xid, Protocol__FspType type, Protocol__FspHeader **header) {
+
+ *header = malloc(sizeof(Protocol__FspHeader));
+ if(*header == NULL)
+ goto error;
+
+ protocol__fsp_header__init(*header);
+ (*header)->version = FLEXSPLIT_VERSION;
+ (*header)->has_version = 1;
+ // check if the type is set
+ (*header)->type = type;
+ (*header)->has_type = 1;
+ (*header)->xid = xid;
+ (*header)->has_xid = 1;
+ return 0;
+
+ error:
+ LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+ return -1;
+}
+
+
+int proto_agent_hello(mid_t mod_id, const void *params, Protocol__FlexsplitMessage **msg) {
+
+ Protocol__FspHeader *header;
+ /*TODO: Need to set random xid or xid from received hello message*/
+ xid_t xid = 1;
+ if (fsp_create_header(xid, PROTOCOL__FSP_TYPE__FSPT_HELLO, &header) != 0)
+ goto error;
+
+ Protocol__FspHello *hello_msg;
+ hello_msg = malloc(sizeof(Protocol__FspHello));
+ if(hello_msg == NULL)
+ goto error;
+ protocol__fsp_hello__init(hello_msg);
+ hello_msg->header = header;
+
+ *msg = malloc(sizeof(Protocol__FlexsplitMessage));
+ if(*msg == NULL)
+ goto error;
+
+ protocol__flexsplit_message__init(*msg);
+ (*msg)->msg_case = PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG;
+ (*msg)->msg_dir = PROTOCOL__FLEXSPLIT_DIRECTION__SUCCESSFUL_OUTCOME;
+ (*msg)->has_msg_dir = 1;
+ (*msg)->hello_msg = hello_msg;
+ return 0;
+
+ error:
+ if(header != NULL)
+ free(header);
+ if(hello_msg != NULL)
+ free(hello_msg);
+ if(*msg != NULL)
+ free(*msg);
+ LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+ return -1;
+}
+
+
+int proto_agent_destroy_hello(Protocol__FlexsplitMessage *msg) {
+
+ if(msg->msg_case != PROTOCOL__FLEXSPLIT_MESSAGE__MSG_HELLO_MSG)
+ goto error;
+
+ free(msg->hello_msg->header);
+ free(msg->hello_msg);
+ free(msg);
+ return 0;
+
+ error:
+ LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
+ return -1;
+}
+
+// call this function to start a nanosecond-resolution timer
+struct timespec timer_start(){
+ struct timespec start_time;
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start_time);
+ return start_time;
+}
+
+// call this function to end a timer, returning nanoseconds elapsed as a long
+long timer_end(struct timespec start_time){
+ struct timespec end_time;
+ clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end_time);
+ long diffInNanos = end_time.tv_nsec - start_time.tv_nsec;
+ return diffInNanos;
+}
+
+
+/*
+ * get generic info from RAN
+ */
+
+void set_enb_vars(mid_t mod_id, ran_name_t ran){
+
+ switch (ran){
+ case RAN_LTE_OAI :
+ enb[mod_id] = (void *)&eNB_mac_inst[mod_id];
+ enb_ue[mod_id] = (void *)&eNB_mac_inst[mod_id].UE_list;
+ enb_rrc[mod_id] = (void *)&eNB_rrc_inst[mod_id];
+ break;
+ default :
+ goto error;
+ }
+
+ return;
+
+ error:
+ LOG_E(PROTO_AGENT, "unknown RAN name %d\n", ran);
+}
+
+
+//struct proto_agent_map agent_map;
+proto_agent_timer_instance_t timer_instance;
+err_code_t proto_agent_init_timer(void){
+
+ LOG_I(PROTO_AGENT, "init RB tree\n");
+
+ RB_INIT(&timer_instance.proto_agent_head);
+
+ /*
+ struct proto_agent_timer_element_s e;
+ memset(&e, 0, sizeof(proto_agent_timer_element_t));
+ RB_INSERT(proto_agent_map, &agent_map, &e);
+ */
+ return PROTOCOL__FLEXSPLIT_ERR__NO_ERR;
+}
+
+RB_GENERATE(proto_agent_map,proto_agent_timer_element_s, entry, proto_agent_compare_timer);
+
+/* The timer_id might not be the best choice for the comparison */
+int proto_agent_compare_timer(struct proto_agent_timer_element_s *a, struct proto_agent_timer_element_s *b){
+
+ if (a->timer_id < b->timer_id) return -1;
+ if (a->timer_id > b->timer_id) return 1;
+
+ // equal timers
+ return 0;
+}
+
+err_code_t proto_agent_create_timer(uint32_t interval_sec,
+ uint32_t interval_usec,
+ agent_id_t agent_id,
+ instance_t instance,
+ uint32_t timer_type,
+ xid_t xid,
+ proto_agent_timer_callback_t cb,
+ void* timer_args,
+ long *timer_id){
+
+ struct proto_agent_timer_element_s *e = calloc(1, sizeof(*e));
+ DevAssert(e != NULL);
+
+//uint32_t timer_id;
+ int ret=-1;
+
+ if ((interval_sec == 0) && (interval_usec == 0 ))
+ return TIMER_NULL;
+
+ if (timer_type >= PROTO_AGENT_TIMER_TYPE_MAX)
+ return TIMER_TYPE_INVALIDE;
+
+ if (timer_type == PROTO_AGENT_TIMER_TYPE_ONESHOT){
+ ret = timer_setup(interval_sec,
+ interval_usec,
+ TASK_PROTO_AGENT,
+ instance,
+ TIMER_ONE_SHOT,
+ timer_args,
+ timer_id);
+
+ e->type = TIMER_ONE_SHOT;
+ }
+ else if (timer_type == PROTO_AGENT_TIMER_TYPE_PERIODIC ){
+ ret = timer_setup(interval_sec,
+ interval_usec,
+ TASK_PROTO_AGENT,
+ instance,
+ TIMER_PERIODIC,
+ timer_args,
+ timer_id);
+
+ e->type = TIMER_PERIODIC;
+ }
+
+ if (ret < 0 ) {
+ return TIMER_SETUP_FAILED;
+ }
+
+ e->agent_id = agent_id;
+ e->instance = instance;
+ e->state = PROTO_AGENT_TIMER_STATE_ACTIVE;
+ e->timer_id = *timer_id;
+ e->xid = xid;
+ e->timer_args = timer_args;
+ e->cb = cb;
+ /*element should be a real pointer*/
+ RB_INSERT(proto_agent_map, &timer_instance.proto_agent_head, e);
+
+ LOG_I(PROTO_AGENT,"Created a new timer with id 0x%lx for agent %d, instance %d \n",
+ e->timer_id, e->agent_id, e->instance);
+
+ return 0;
+}
+
+err_code_t proto_agent_destroy_timer(long timer_id){
+
+ struct proto_agent_timer_element_s *e = get_timer_entry(timer_id);
+
+ if (e != NULL ) {
+ RB_REMOVE(proto_agent_map, &timer_instance.proto_agent_head, e);
+ proto_agent_destroy_flexsplit_message(e->timer_args->msg);
+ free(e);
+ }
+
+ if (timer_remove(timer_id) < 0 )
+ goto error;
+
+ return 0;
+
+ error:
+ LOG_E(PROTO_AGENT, "timer can't be removed\n");
+ return TIMER_REMOVED_FAILED ;
+}
+
+err_code_t proto_agent_destroy_timer_by_task_id(xid_t xid) {
+ struct proto_agent_timer_element_s *e = NULL;
+ long timer_id;
+ RB_FOREACH(e, proto_agent_map, &timer_instance.proto_agent_head) {
+ if (e->xid == xid) {
+ timer_id = e->timer_id;
+ RB_REMOVE(proto_agent_map, &timer_instance.proto_agent_head, e);
+ proto_agent_destroy_flexsplit_message(e->timer_args->msg);
+ free(e);
+ if (timer_remove(timer_id) < 0 ) {
+ goto error;
+ }
+ }
+ }
+ return 0;
+
+ error:
+ LOG_E(PROTO_AGENT, "timer can't be removed\n");
+ return TIMER_REMOVED_FAILED ;
+}
+
+err_code_t proto_agent_destroy_timers(void){
+
+ struct proto_agent_timer_element_s *e = NULL;
+
+ RB_FOREACH(e, proto_agent_map, &timer_instance.proto_agent_head) {
+ RB_REMOVE(proto_agent_map, &timer_instance.proto_agent_head, e);
+ timer_remove(e->timer_id);
+ proto_agent_destroy_flexsplit_message(e->timer_args->msg);
+ free(e);
+ }
+
+ return 0;
+
+}
+
+void proto_agent_sleep_until(struct timespec *ts, int delay) {
+ ts->tv_nsec += delay;
+ if(ts->tv_nsec >= 1000*1000*1000){
+ ts->tv_nsec -= 1000*1000*1000;
+ ts->tv_sec++;
+ }
+ clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts, NULL);
+}
+
+/*
+ int i =0;
+ RB_FOREACH(e, proto_agent_map, &proto_agent_head) {
+ printf("%d: %p\n", i, e); i++;
+ }
+*/
+
+
+err_code_t proto_agent_stop_timer(long timer_id){
+
+ struct proto_agent_timer_element_s *e=NULL;
+ struct proto_agent_timer_element_s search;
+ memset(&search, 0, sizeof(struct proto_agent_timer_element_s));
+ search.timer_id = timer_id;
+
+ e = RB_FIND(proto_agent_map, &timer_instance.proto_agent_head, &search);
+
+ if (e != NULL ) {
+ e->state = PROTO_AGENT_TIMER_STATE_STOPPED;
+ }
+
+ timer_remove(timer_id);
+
+ return 0;
+}
+
+struct proto_agent_timer_element_s * get_timer_entry(long timer_id) {
+
+ struct proto_agent_timer_element_s search;
+ memset(&search, 0, sizeof(struct proto_agent_timer_element_s));
+ search.timer_id = timer_id;
+
+ return RB_FIND(proto_agent_map, &timer_instance.proto_agent_head, &search);
+}
+
+/*
+// this will change the timer_id
+err_code_t enb_agent_restart_timer(uint32_t *timer_id){
+
+ struct enb_agent_timer_element_s *e=NULL;
+
+ RB_FOREACH(e, enb_agent_map, &enb_agent_head) {
+ if (e->timer_id == timer_id)
+ break;
+ }
+
+ if (e != NULL ) {
+ e->state = ENB_AGENT_TIMER_STATE_ACTIVE;
+ }
+
+ ret = timer_setup(e->interval_sec,
+ e->interval_usec,
+ e->agent_id,
+ e->instance,
+ e->type,
+ e->timer_args,
+ &timer_id);
+
+ }
+
+ if (ret < 0 ) {
+ return PROTOCOL__PROGRAN_ERR__TIMER_SETUP_FAILED;
+ }
+
+ return 0;
+
+}
+
+*/
+
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
new file mode 100644
index 0000000000..df8e320719
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_common.h
@@ -0,0 +1,361 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_common.h
+ * \brief common message primitves and utilities
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+
+
+#ifndef PROTO_AGENT_COMMON_H_
+#define PROTO_AGENT_COMMON_H_
+
+#include
+
+#include "header.pb-c.h"
+#include "flexsplit.pb-c.h"
+
+// Do not need these
+//#include "stats_messages.pb-c.h"
+//#include "stats_common.pb-c.h"
+
+#include "proto_agent_defs.h"
+#include "enb_config.h"
+
+#include "LAYER2/MAC/extern.h"
+#include "LAYER2/RLC/rlc.h"
+
+# include "tree.h"
+# include "intertask_interface.h"
+# include "timer.h"
+
+#define FLEXSPLIT_VERSION 0
+
+typedef int (*proto_agent_message_decoded_callback)(
+ mid_t mod_id,
+ const void *params,
+ Protocol__FlexsplitMessage **msg
+);
+
+typedef int (*proto_agent_message_destruction_callback)(
+ Protocol__FlexsplitMessage *msg
+);
+
+/**********************************
+ * progRAN protocol messages helper
+ * functions and generic handlers
+ **********************************/
+
+int proto_agent_serialize_message(Protocol__FlexsplitMessage *msg, void **buf, int *size);
+int proto_agent_deserialize_message(void *data, int size, Protocol__FlexsplitMessage **msg);
+
+void * proto_agent_pack_message(Protocol__FlexsplitMessage *msg,
+ uint32_t * size);
+
+err_code_t proto_agent_destroy_flexsplit_message(Protocol__FlexsplitMessage *msg);
+
+int fsp_create_header(xid_t xid, Protocol__FspType type, Protocol__FspHeader **header);
+
+int proto_agent_hello(mid_t mod_id, const void *params, Protocol__FlexsplitMessage **msg);
+int proto_agent_destroy_hello(Protocol__FlexsplitMessage *msg);
+
+Protocol__FlexsplitMessage* proto_agent_handle_message (mid_t mod_id,
+ uint8_t *data,
+ uint32_t size);
+
+Protocol__FlexsplitMessage *proto_agent_handle_timed_task(void *args);
+
+
+
+
+/****************************
+ * get generic info from RAN
+ ****************************/
+
+void set_enb_vars(mid_t mod_id, ran_name_t ran);
+
+// int get_current_time_ms (mid_t mod_id, int subframe_flag);
+
+/*Return the current frame number
+ *Could be using implementation specific numbering of frames
+ */
+// unsigned int get_current_frame(mid_t mod_id);
+
+/* Do not need these */
+
+///*Return the current SFN (0-1023)*/
+//unsigned int get_current_system_frame_num(mid_t mod_id);
+//
+//unsigned int get_current_subframe(mid_t mod_id);
+
+///*Return the frame and subframe number in compact 16-bit format.
+// Bits 0-3 subframe, rest for frame. Required by progRAN protocol*/
+// uint16_t get_sfn_sf (mid_t mod_id);
+//
+// int get_num_ues(mid_t mod_id);
+//
+// int get_ue_crnti (mid_t mod_id, mid_t ue_id);
+//
+// int get_ue_bsr (mid_t mod_id, mid_t ue_id, lcid_t lcid);
+//
+// int get_ue_phr (mid_t mod_id, mid_t ue_id);
+//
+// int get_ue_wcqi (mid_t mod_id, mid_t ue_id);
+//
+// int get_tx_queue_size(mid_t mod_id, mid_t ue_id, logical_chan_id_t channel_id);
+//
+// int get_MAC_CE_bitmap_TA(mid_t mod_id, mid_t ue_id);
+//
+// int get_active_CC(mid_t mod_id, mid_t ue_id);
+//
+// int get_current_RI(mid_t mod_id, mid_t ue_id, int CC_id);
+//
+// int get_n1pucch_an(mid_t mod_id, int CC_id);
+//
+// int get_nRB_CQI(mid_t mod_id, int CC_id);
+//
+// int get_deltaPUCCH_Shift(mid_t mod_id, int CC_id);
+//
+// int get_prach_ConfigIndex(mid_t mod_id, int CC_id);
+//
+// int get_prach_FreqOffset(mid_t mod_id, int CC_id);
+//
+// int get_maxHARQ_Msg3Tx(mid_t mod_id, int CC_id);
+//
+// int get_ul_cyclic_prefix_length(mid_t mod_id, int CC_id);
+//
+// int get_dl_cyclic_prefix_length(mid_t mod_id, int CC_id);
+//
+// int get_cell_id(mid_t mod_id, int CC_id);
+//
+// int get_srs_BandwidthConfig(mid_t mod_id, int CC_id);
+//
+// int get_srs_SubframeConfig(mid_t mod_id, int CC_id);
+//
+// int get_srs_MaxUpPts(mid_t mod_id, int CC_id);
+//
+// int get_N_RB_DL(mid_t mod_id, int CC_id);
+//
+// int get_N_RB_UL(mid_t mod_id, int CC_id);
+//
+// int get_subframe_assignment(mid_t mod_id, int CC_id);
+//
+// int get_special_subframe_assignment(mid_t mod_id, int CC_id);
+//
+// int get_ra_ResponseWindowSize(mid_t mod_id, int CC_id);
+//
+// int get_mac_ContentionResolutionTimer(mid_t mod_id, int CC_id);
+//
+// int get_duplex_mode(mid_t mod_id, int CC_id);
+//
+// long get_si_window_length(mid_t mod_id, int CC_id);
+//
+// int get_num_pdcch_symb(mid_t mod_id, int CC_id);
+//
+// int get_tpc(mid_t mod_id, mid_t ue_id);
+//
+// int get_harq(const mid_t mod_id, const uint8_t CC_id, const mid_t ue_id,
+// const int frame, const uint8_t subframe, int *id, int *status);
+
+/*
+ * ************************************
+ * Get Messages for UE Configuration Reply
+ * ************************************
+ */
+
+// int get_time_alignment_timer(mid_t mod_id, mid_t ue_id);
+//
+// int get_meas_gap_config(mid_t mod_id, mid_t ue_id);
+//
+// int get_meas_gap_config_offset(mid_t mod_id, mid_t ue_id);
+//
+// int get_ue_aggregated_max_bitrate_dl (mid_t mod_id, mid_t ue_id);
+//
+// int get_ue_aggregated_max_bitrate_ul (mid_t mod_id, mid_t ue_id);
+//
+// int get_half_duplex(mid_t ue_id);
+//
+// int get_intra_sf_hopping(mid_t ue_id);
+//
+// int get_type2_sb_1(mid_t ue_id);
+//
+// int get_ue_category(mid_t ue_id);
+//
+// int get_res_alloc_type1(mid_t ue_id);
+//
+// int get_ue_transmission_mode(mid_t mod_id, mid_t ue_id);
+//
+// int get_tti_bundling(mid_t mod_id, mid_t ue_id);
+//
+// int get_maxHARQ_TX(mid_t mod_id, mid_t ue_id);
+//
+// int get_beta_offset_ack_index(mid_t mod_id, mid_t ue_id);
+//
+// int get_beta_offset_ri_index(mid_t mod_id, mid_t ue_id);
+//
+// int get_beta_offset_cqi_index(mid_t mod_id, mid_t ue_id);
+//
+// int get_simultaneous_ack_nack_cqi(mid_t mod_id, mid_t ue_id);
+//
+// int get_ack_nack_simultaneous_trans(mid_t mod_id,mid_t ue_id);
+//
+// int get_aperiodic_cqi_rep_mode(mid_t mod_id,mid_t ue_id);
+//
+// int get_tdd_ack_nack_feedback(mid_t mod_id, mid_t ue_id);
+//
+// int get_ack_nack_repetition_factor(mid_t mod_id, mid_t ue_id);
+//
+// int get_extended_bsr_size(mid_t mod_id, mid_t ue_id);
+//
+// int get_ue_transmission_antenna(mid_t mod_id, mid_t ue_id);
+//
+// int get_lcg(mid_t ue_id, mid_t lc_id);
+//
+// int get_direction(mid_t ue_id, mid_t lc_id);
+
+
+
+/*******************
+ * timer primitves
+ *******************/
+
+#define TIMER_NULL -1
+#define TIMER_TYPE_INVALIDE -2
+#define TIMER_SETUP_FAILED -3
+#define TIMER_REMOVED_FAILED -4
+#define TIMER_ELEMENT_NOT_FOUND -5
+
+
+/* Type of the callback executed when the timer expired */
+typedef Protocol__FlexsplitMessage *(*proto_agent_timer_callback_t)(void*);
+
+typedef enum {
+ /* oneshot timer: */
+ PROTO_AGENT_TIMER_TYPE_ONESHOT = 0x0,
+
+ /* periodic timer */
+ PROTO_AGENT_TIMER_TYPE_PERIODIC = 0x1,
+
+ /* Inactive state: initial state for any timer. */
+ PROTO_AGENT_TIMER_TYPE_EVENT_DRIVEN = 0x2,
+
+ /* Max number of states available */
+ PROTO_AGENT_TIMER_TYPE_MAX,
+} proto_agent_timer_type_t;
+
+typedef enum {
+ /* Inactive state: initial state for any timer. */
+ PROTO_AGENT_TIMER_STATE_INACTIVE = 0x0,
+
+ /* Inactive state: initial state for any timer. */
+ PROTO_AGENT_TIMER_STATE_ACTIVE = 0x1,
+
+ /* Inactive state: initial state for any timer. */
+ PROTO_AGENT_TIMER_STATE_STOPPED = 0x2,
+
+ /* Max number of states available */
+ PROTO_AGENT_TIMER_STATE_MAX,
+} proto_agent_timer_state_t;
+
+typedef struct proto_agent_timer_args_s{
+ mid_t mod_id;
+ Protocol__FlexsplitMessage *msg;
+} proto_agent_timer_args_t;
+
+
+// Do we need this?? Probably not..
+typedef struct proto_agent_timer_element_s{
+ RB_ENTRY(proto_agent_timer_element_s) entry;
+
+ agent_id_t agent_id;
+ instance_t instance;
+
+ proto_agent_timer_type_t type;
+ proto_agent_timer_state_t state;
+
+ uint32_t interval_sec;
+ uint32_t interval_usec;
+
+ long timer_id; /* Timer id returned by the timer API*/
+ xid_t xid; /*The id of the task as received by the controller
+ message*/
+
+ proto_agent_timer_callback_t cb;
+ proto_agent_timer_args_t *timer_args;
+
+} proto_agent_timer_element_t;
+
+typedef struct proto_agent_timer_instance_s{
+ RB_HEAD(proto_agent_map, proto_agent_timer_element_s) proto_agent_head;
+}proto_agent_timer_instance_t;
+
+err_code_t proto_agent_init_timer(void);
+
+err_code_t proto_agent_create_timer(uint32_t interval_sec,
+ uint32_t interval_usec,
+ agent_id_t agent_id,
+ instance_t instance,
+ uint32_t timer_type,
+ xid_t xid,
+ proto_agent_timer_callback_t cb,
+ void* timer_args,
+ long *timer_id);
+
+err_code_t proto_agent_destroy_timers(void);
+err_code_t proto_agent_destroy_timer(long timer_id);
+err_code_t proto_agent_destroy_timer_by_task_id(xid_t xid);
+
+err_code_t proto_agent_stop_timer(long timer_id);
+
+err_code_t proto_agent_restart_timer(long *timer_id);
+
+struct proto_agent_timer_element_s * get_timer_entry(long timer_id);
+
+Protocol__FlexsplitMessage * proto_agent_process_timeout(long timer_id, void* timer_args);
+
+int proto_agent_compare_timer(struct proto_agent_timer_element_s *a, struct proto_agent_timer_element_s *b);
+
+/*Specify a delay in nanoseconds to timespec and sleep until then*/
+void proto_agent_sleep_until(struct timespec *ts, int delay);
+
+/* RB_PROTOTYPE is for .h files */
+RB_PROTOTYPE(proto_agent_map, proto_agent_timer_element_s, entry, proto_agent_compare_timer);
+
+
+#endif
+
+
+
+
+
+
+
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h
new file mode 100644
index 0000000000..85559e864b
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_defs.h
@@ -0,0 +1,133 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2016 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_defs.h
+ * \brief enb agent common definitions
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+#ifndef PROTO_AGENT_DEFS_H_
+#define PROTO_AGENT_DEFS_H_
+
+#include
+#include
+#include
+#include
+
+#include "UTIL/ASYNC_IF/link_manager.h"
+
+#define NUM_MAX_ENB 2
+#define NUM_MAX_UE 2048
+#define DEFAULT_PROTO_AGENT_IPv4_ADDRESS "127.0.0.1"
+#define DEFAULT_PROTO_AGENT_PORT 2210
+#define DEFAULT_PROTO_AGENT_CACHE "/mnt/oai_agent_cache"
+
+typedef enum {
+
+ PROTO_AGENT_DEFAULT=0,
+
+ ENB_AGENT_PHY=1,
+ ENB_AGENT_MAC=2,
+ ENB_AGENT_RLC=3,
+ ENB_AGENT_PDCP=4,
+ ENB_AGENT_RRC=5,
+ ENB_AGENT_S1AP=6,
+ ENB_AGENT_GTP=7,
+ ENB_AGENT_X2AP=8,
+
+ ENB_AGENT_MAX=9,
+
+} agent_id_t;
+
+typedef enum {
+ /* no action */
+ ENB_AGENT_ACTION_NONE = 0x0,
+
+ /* send action */
+ ENB_AGENT_ACTION_SEND = 0x1,
+
+ /* apply action */
+ ENB_AGENT_ACTION_APPLY = 0x2,
+
+ /* clear action */
+ ENB_AGENT_ACTION_CLEAR = 0x4,
+
+ /* write action */
+ ENB_AGENT_ACTION_WRITE = 0x8,
+
+ /* filter action */
+ ENB_AGENT_ACTION_FILTER = 0x10,
+
+ /* preprocess action */
+ ENB_AGENT_ACTION_PREPROCESS = 0x20,
+
+ /* meter action */
+ ENB_AGENT_ACTION_METER = 0x40,
+
+ /* Max number of states available */
+ ENB_AGENT_ACTION_MAX = 0x7f,
+} agent_action_t;
+
+
+typedef enum {
+
+ RAN_LTE_OAI= 0,
+
+ /* Max number of states available */
+ RAN_NAME_MAX = 0x7f,
+} ran_name_t;
+
+typedef uint8_t xid_t;
+typedef uint8_t mid_t; // module or enb id
+typedef uint8_t lcid_t;
+typedef int32_t err_code_t;
+
+
+
+typedef struct {
+ /* general info */
+
+ /* stats */
+
+ uint32_t total_rx_msg;
+ uint32_t total_tx_msg;
+
+ uint32_t rx_msg[NUM_MAX_ENB];
+ uint32_t tx_msg[NUM_MAX_ENB];
+
+}proto_agent_info_t;
+
+typedef struct {
+ mid_t enb_id;
+ proto_agent_info_t agent_info;
+
+}proto_agent_instance_t;
+
+#endif
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c
new file mode 100644
index 0000000000..b3e39bbd65
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_handler.c
@@ -0,0 +1,150 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2014 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_handler.c
+ * \brief enb agent tx and rx message handler
+ * \author Navid Nikaein and Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+
+#include "proto_agent_common.h"
+
+//#include "enb_agent_mac.h" // Do we need this?
+
+#include "log.h"
+
+#include "assertions.h"
+
+proto_agent_message_decoded_callback agent_messages_callback[][3] = {
+ {proto_agent_hello, 0, 0}, /*PROTOCOL__PROGRAN_MESSAGE__MSG_HELLO_MSG*/
+};
+
+proto_agent_message_destruction_callback message_destruction_callback[] = {
+ proto_agent_destroy_hello,
+};
+
+static const char *proto_agent_direction2String[] = {
+ "", /* not_set */
+ "originating message", /* originating message */
+ "successfull outcome", /* successfull outcome */
+ "unsuccessfull outcome", /* unsuccessfull outcome */
+};
+
+
+Protocol__FlexsplitMessage* proto_agent_handle_message (mid_t mod_id,
+ uint8_t *data,
+ uint32_t size){
+
+ Protocol__FlexsplitMessage *decoded_message, *reply_message;
+ err_code_t err_code;
+ DevAssert(data != NULL);
+
+ if (proto_agent_deserialize_message(data, size, &decoded_message) < 0) {
+ err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_DECODING;
+ goto error;
+ }
+
+ // Undestand why these calculations take place
+ if ((decoded_message->msg_case > sizeof(agent_messages_callback) / (3*sizeof(proto_agent_message_decoded_callback))) ||
+ (decoded_message->msg_dir > PROTOCOL__FLEXSPLIT_DIRECTION__UNSUCCESSFUL_OUTCOME)){
+ err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_NOT_HANDLED;
+ goto error;
+ }
+
+ if (agent_messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1] == NULL) {
+ err_code= PROTOCOL__FLEXSPLIT_ERR__MSG_NOT_SUPPORTED;
+ goto error;
+
+ }
+
+ err_code = ((*agent_messages_callback[decoded_message->msg_case-1][decoded_message->msg_dir-1])(mod_id, (void *) decoded_message, &reply_message));
+ if ( err_code < 0 ){
+ goto error;
+ } else if (err_code == 1) { //If err_code > 1, we do not want to dispose the message yet
+ protocol__flexsplit_message__free_unpacked(decoded_message, NULL);
+ }
+ return reply_message;
+
+error:
+ LOG_E(PROTO_AGENT,"errno %d occured\n",err_code);
+ return NULL;
+
+}
+
+
+
+void * proto_agent_pack_message(Protocol__FlexsplitMessage *msg,
+ uint32_t * size){
+
+ void * buffer;
+ err_code_t err_code = PROTOCOL__FLEXSPLIT_ERR__NO_ERR;
+
+ if (proto_agent_serialize_message(msg, &buffer, size) < 0 ) {
+ err_code = PROTOCOL__FLEXSPLIT_ERR__MSG_ENCODING;
+ goto error;
+ }
+
+ // free the msg --> later keep this in the data struct and just update the values
+ //TODO call proper destroy function
+ err_code = ((*message_destruction_callback[msg->msg_case-1])(msg));
+
+ DevAssert(buffer !=NULL);
+
+ LOG_D(PROTO_AGENT,"Serilized the enb mac stats reply (size %d)\n", *size);
+
+ return buffer;
+
+ error :
+ LOG_E(PROTO_AGENT,"errno %d occured\n",err_code);
+
+ return NULL;
+}
+
+Protocol__FlexsplitMessage* proto_agent_process_timeout(long timer_id, void* timer_args){
+
+ struct proto_agent_timer_element_s *found = get_timer_entry(timer_id);
+
+ if (found == NULL ) goto error;
+// LOG_I(PROTO_AGENT, "Found the entry (%p): timer_id is 0x%lx 0x%lx\n", found, timer_id, found->timer_id);
+
+ if (timer_args == NULL)
+ LOG_W(PROTO_AGENT,"null timer args\n");
+
+// return found->cb(timer_args);
+ return 1;
+ error:
+ LOG_E(PROTO_AGENT, "can't get the timer element\n");
+ return TIMER_ELEMENT_NOT_FOUND;
+}
+
+err_code_t proto_agent_destroy_flexsplit_message(Protocol__FlexsplitMessage *msg) {
+ return ((*message_destruction_callback[msg->msg_case-1])(msg));
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
new file mode 100644
index 0000000000..51a909261f
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.c
@@ -0,0 +1,200 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2016 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_net_comm.c
+ * \brief enb agent network interface abstraction
+ * \author Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+
+#include "proto_agent_net_comm.h"
+#include "log.h"
+
+proto_agent_channel_t *agent_channel[NUM_MAX_ENB][ENB_AGENT_MAX];
+proto_agent_channel_instance_t channel_instance;
+int proto_agent_channel_id = 0;
+
+int proto_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int size, int priority) {
+ /*Check if agent id is valid*/
+ if (agent_id >= ENB_AGENT_MAX || agent_id < 0) {
+ goto error;
+ }
+ proto_agent_channel_t *channel;
+ channel = agent_channel[mod_id][agent_id];
+
+ /*Check if agent has a channel registered*/
+ if (channel == NULL) {
+ goto error;
+ }
+
+ return channel->msg_send(data, size, priority, channel->channel_info);
+
+ error:
+ LOG_E(PROTO_AGENT, "No channel registered for agent with id %d\n", agent_id);
+ return -1;
+}
+
+int proto_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *size, int *priority) {
+ /*Check if agent id is valid*/
+ if (agent_id >= ENB_AGENT_MAX || agent_id < 0) {
+ goto error;
+ }
+ proto_agent_channel_t *channel;
+ channel = agent_channel[mod_id][agent_id];
+
+ /*Check if agent has a channel registered*/
+ if (channel == NULL) {
+ goto error;
+ }
+
+ return channel->msg_recv(data, size, priority, channel->channel_info);
+
+ error:
+ LOG_E(PROTO_AGENT, "No channel registered for agent with id %d\n", agent_id);
+ return -1;
+}
+
+int proto_agent_register_channel(mid_t mod_id, proto_agent_channel_t *channel, agent_id_t agent_id) {
+ int i;
+
+ if (channel == NULL) {
+ return -1;
+ }
+
+ if (agent_id == ENB_AGENT_MAX) {
+ for (i = 0; i < ENB_AGENT_MAX; i++) {
+ agent_channel[mod_id][i] = channel;
+ }
+ } else {
+ agent_channel[mod_id][agent_id] = channel;
+ }
+ return 0;
+}
+
+void proto_agent_unregister_channel(mid_t mod_id, agent_id_t agent_id) {
+ int i;
+
+ if (agent_id == ENB_AGENT_MAX) {
+ for (i = 0; i < ENB_AGENT_MAX; i++) {
+ agent_channel[mod_id][i] = NULL;
+ }
+ } else {
+ agent_channel[mod_id][agent_id] = NULL;
+ }
+}
+
+int proto_agent_create_channel(void *channel_info,
+ int (*msg_send)(void *data, int size, int priority, void *channel_info),
+ int (*msg_recv)(void **data, int *size, int *priority, void *channel_info),
+ void (*release)(proto_agent_channel_t *channel)) {
+
+ int channel_id = ++proto_agent_channel_id;
+ proto_agent_channel_t *channel = (proto_agent_channel_t *) malloc(sizeof(proto_agent_channel_t));
+ channel->channel_id = channel_id;
+ channel->channel_info = channel_info;
+ channel->msg_send = msg_send;
+ channel->msg_recv = msg_recv;
+ channel->release = release;
+
+ /*element should be a real pointer*/
+ RB_INSERT(proto_agent_channel_map, &channel_instance.proto_agent_head, channel);
+
+ LOG_I(PROTO_AGENT,"Created a new channel with id 0x%lx\n", channel->channel_id);
+
+ return channel_id;
+}
+
+int proto_agent_destroy_channel(int channel_id) {
+ int i, j;
+
+ /*Check to see if channel exists*/
+ struct proto_agent_channel_s *e = NULL;
+ struct proto_agent_channel_s search;
+ memset(&search, 0, sizeof(struct proto_agent_channel_s));
+
+ e = RB_FIND(proto_agent_channel_map, &channel_instance.proto_agent_head, &search);
+
+ if (e == NULL) {
+ return -1;
+ }
+
+ /*Unregister the channel from all agents*/
+ for (i = 0; i < NUM_MAX_ENB; i++) {
+ for (j = 0; j < ENB_AGENT_MAX; j++) {
+ if (agent_channel[i][j] != NULL) {
+ if (agent_channel[i][j]->channel_id == e->channel_id) {
+ agent_channel[i][j] == NULL;
+ }
+ }
+ }
+ }
+
+ /*Remove the channel from the tree and free memory*/
+ RB_REMOVE(proto_agent_channel_map, &channel_instance.proto_agent_head, e);
+ e->release(e);
+ free(e);
+
+ return 0;
+}
+
+err_code_t proto_agent_init_channel_container(void) {
+ int i, j;
+ LOG_I(PROTO_AGENT, "init RB tree for channel container\n");
+
+ RB_INIT(&channel_instance.proto_agent_head);
+
+ for (i = 0; i < NUM_MAX_ENB; i++) {
+ for (j = 0; j < ENB_AGENT_MAX; j++) {
+ agent_channel[i][j] == NULL;
+ }
+ }
+
+ return 0;
+}
+
+RB_GENERATE(proto_agent_channel_map,proto_agent_channel_s, entry, proto_agent_compare_channel);
+
+int proto_agent_compare_channel(struct proto_agent_channel_s *a, struct proto_agent_channel_s *b) {
+ if (a->channel_id < b->channel_id) return -1;
+ if (a->channel_id > b->channel_id) return 1;
+
+ // equal timers
+ return 0;
+}
+
+proto_agent_channel_t * get_channel(int channel_id) {
+
+ struct proto_agent_channel_s search;
+ memset(&search, 0, sizeof(struct proto_agent_channel_s));
+ search.channel_id = channel_id;
+
+ return RB_FIND(proto_agent_channel_map, &channel_instance.proto_agent_head, &search);
+
+}
diff --git a/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h
new file mode 100644
index 0000000000..acdb5a5146
--- /dev/null
+++ b/openair2/LAYER2/PROTO_AGENT/proto_agent_net_comm.h
@@ -0,0 +1,90 @@
+/*******************************************************************************
+ OpenAirInterface
+ Copyright(c) 1999 - 2016 Eurecom
+
+ OpenAirInterface is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+
+ OpenAirInterface is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ 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,
+ see .
+
+ Contact Information
+ OpenAirInterface Admin: openair_admin@eurecom.fr
+ OpenAirInterface Tech : openair_tech@eurecom.fr
+ OpenAirInterface Dev : openair4g-devel@lists.eurecom.fr
+
+ Address : Eurecom, Compus SophiaTech 450, route des chappes, 06451 Biot, France.
+
+ *******************************************************************************/
+
+/*! \file enb_agent_net_comm.h
+ * \brief enb agent network interface abstraction
+ * \autho Xenofon Foukas
+ * \date 2016
+ * \version 0.1
+ */
+#ifndef PROTO_AGENT_NET_COMM_H_
+#define PROTO_AGENT_NET_COMM_H_
+
+#include "proto_agent_defs.h"
+
+#include "tree.h"
+
+/*Channel related information used for Tx/Rx of protocol messages*/
+typedef struct proto_agent_channel_s {
+ RB_ENTRY(proto_agent_channel_s) entry;
+int channel_id;
+void *channel_info;
+/*Callbacks for channel message Tx and Rx*/
+int (*msg_send)(void *data, int size, int priority, void *channel_info);
+int (*msg_recv)(void **data, int *size, int *priority, void *channel_info);
+void (*release)(struct proto_agent_channel_s *channel);
+} proto_agent_channel_t;
+
+typedef struct proto_agent_channel_instance_s{
+ RB_HEAD(proto_agent_channel_map, proto_agent_channel_s) proto_agent_head;
+} proto_agent_channel_instance_t;
+
+/*Send and receive messages using the channel registered for a specific agent*/
+int proto_agent_msg_send(mid_t mod_id, agent_id_t agent_id, void *data, int size, int priority);
+
+int proto_agent_msg_recv(mid_t mod_id, agent_id_t agent_id, void **data, int *size, int *priority);
+
+/*Register a channel to an agent. Use ENB_AGENT_MAX to register the
+ *same channel to all agents*/
+int proto_agent_register_channel(mid_t mod_id, proto_agent_channel_t *channel, agent_id_t agent_id);
+
+/*Unregister the current channel of an agent. Use ENB_AGENT_MAX to unregister all channels*/
+void proto_agent_unregister_channel(mid_t mod_id, agent_id_t agent_id);
+
+/*Create a new channel. Returns the id of the new channel or negative number otherwise*/
+int proto_agent_create_channel(void *channel_info,
+ int (*msg_send)(void *data, int size, int priority, void *channel_info),
+ int (*msg_recv)(void **data, int *size, int *priority, void *channel_info),
+ void (*release)(proto_agent_channel_t *channel));
+
+/*Unregister a channel from all agents and destroy it. Returns 0 in case of success*/
+int proto_agent_destroy_channel(int channel_id);
+
+/*Return an agent communication channel based on its id*/
+proto_agent_channel_t * get_channel(int channel_id);
+
+/*Should be called before performing any channel operations*/
+err_code_t proto_agent_init_channel_container(void);
+
+int proto_agent_compare_channel(struct proto_agent_channel_s *a, struct proto_agent_channel_s *b);
+
+/* RB_PROTOTYPE is for .h files */
+RB_PROTOTYPE(proto_agent_channel_map, proto_agent_channel_s, entry, proto_agent_compare_channel);
+
+#endif /*ENB_AGENT_COMM_H_*/
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_and_gnumake/Makefile b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_and_gnumake/Makefile
new file mode 100644
index 0000000000..27e4d91df3
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_and_gnumake/Makefile
@@ -0,0 +1,168 @@
+##### paths #####
+BINDIR := ../../bin
+INCDIR := ../../inc
+OBJDIR := ../../obj
+SRCDIR := ../../src
+
+##### misc #####
+QUIETLY := 1>/dev/null 2>/dev/null
+VERSION_NUMBER := 1
+MINOR_NUMBER := 0
+RELEASE_NUMBER := 0
+
+##### sources, objects and libraries #####
+BINNAME := liblfds700
+ARFILENAME := $(BINNAME).a
+ARPATHNAME := $(BINDIR)/$(ARFILENAME)
+SOBASENAME := $(BINNAME).so
+SONAME := $(SOBASENAME).$(VERSION_NUMBER)
+SOFILENAME := $(SONAME).$(MINOR_NUMBER).$(RELEASE_NUMBER)
+SOPATHNAME := $(BINDIR)/$(SOFILENAME)
+INCNAME := $(INCDIR)/$(BINNAME).h
+SRCDIRS := lfds700_btree_addonly_unbalanced lfds700_freelist lfds700_hash_addonly lfds700_list_addonly_ordered_singlylinked lfds700_list_addonly_singlylinked_unordered lfds700_misc lfds700_queue lfds700_queue_bounded_singleconsumer_singleproducer lfds700_ringbuffer lfds700_stack
+SOURCES := lfds700_hash_addonly_cleanup.c lfds700_hash_addonly_get.c lfds700_hash_addonly_init.c lfds700_hash_addonly_insert.c lfds700_hash_addonly_iterate.c lfds700_hash_addonly_query.c \
+ lfds700_list_addonly_ordered_singlylinked_cleanup.c lfds700_list_addonly_ordered_singlylinked_get.c lfds700_list_addonly_ordered_singlylinked_init.c lfds700_list_addonly_ordered_singlylinked_insert.c lfds700_list_addonly_ordered_singlylinked_query.c \
+ lfds700_list_addonly_singlylinked_unordered_cleanup.c lfds700_list_addonly_singlylinked_unordered_get.c lfds700_list_addonly_singlylinked_unordered_init.c lfds700_list_addonly_singlylinked_unordered_insert.c lfds700_list_addonly_singlylinked_unordered_query.c \
+ lfds700_btree_addonly_unbalanced_cleanup.c lfds700_btree_addonly_unbalanced_get.c lfds700_btree_addonly_unbalanced_init.c lfds700_btree_addonly_unbalanced_insert.c lfds700_btree_addonly_unbalanced_query.c \
+ lfds700_freelist_cleanup.c lfds700_freelist_init.c lfds700_freelist_pop.c lfds700_freelist_push.c lfds700_freelist_query.c \
+ lfds700_misc_cleanup.c lfds700_misc_globals.c lfds700_misc_init.c lfds700_misc_prng.c lfds700_misc_query.c \
+ lfds700_queue_cleanup.c lfds700_queue_dequeue.c lfds700_queue_enqueue.c lfds700_queue_init.c lfds700_queue_query.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c lfds700_queue_bounded_singleconsumer_singleproducer_init.c lfds700_queue_bounded_singleconsumer_singleproducer_query.c \
+ lfds700_ringbuffer_cleanup.c lfds700_ringbuffer_init.c lfds700_ringbuffer_query.c lfds700_ringbuffer_read.c lfds700_ringbuffer_write.c \
+ lfds700_stack_cleanup.c lfds700_stack_init.c lfds700_stack_pop.c lfds700_stack_push.c lfds700_stack_query.c
+OBJECTS := $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SOURCES)))
+SYSLIBS :=
+
+##### default paths fix up #####
+CPATH := $(subst : ,:,$(SRCDIR):$(INCDIR))
+
+##### tools #####
+MAKE := make
+MFLAGS :=
+
+DG := gcc
+DGFLAGS := -MM -std=gnu89
+
+CC := gcc
+CFBASE := -c -fno-strict-aliasing -std=gnu89 -Wall -Werror -Wno-unknown-pragmas -Wno-unused-but-set-variable -Wno-unused-variable
+CFCOV := -O0 -ggdb -DCOVERAGE -fprofile-arcs -ftest-coverage
+CFDBG := -O0 -ggdb -D_DEBUG
+CFPROF := -O0 -ggdb -DPROF -pg
+CFREL := -O2 -DNDEBUG -finline-functions
+CFTSAN := -O0 -ggdb -DTSAN -fsanitize=thread -fPIC
+CFBARE := -ffreestanding -nodefaultlibs -nostdinc -nostdlib
+
+AR := ar
+AFLAGS := -rcs
+
+LD := gcc
+LFBASE := -pthread -shared -std=gnu89 -Wl,-soname,$(SONAME) -o $(SOPATHNAME) -Wall -Werror
+LFCOV := -O0 -fprofile-arcs -ftest-coverage
+LFDBG := -O0 -ggdb
+LFPROF := -O0 -pg
+LFREL := -O2 -s -finline-functions
+LFTSAN := -O0 -fsanitize=thread -fPIC
+LFBARE := -ffreestanding -nodefaultlibs -nostdinc -nostdlib
+
+##### CPU variants #####
+GCCARCH := native
+CFBASE += -march=$(GCCARCH)
+
+##### build variants #####
+ifeq ($(findstring so,$(MAKECMDGOALS)),so)
+ CFBASE += -fPIC
+endif
+
+CFLAGS += $(CFBASE)
+LFLAGS += $(LFBASE)
+
+ifeq ($(MAKECMDGOALS),)
+ CFLAGS += $(CFDBG)
+ LFLAGS += $(LFDBG)
+endif
+
+ifeq ($(findstring cov,$(MAKECMDGOALS)),cov)
+ CFLAGS += $(CFCOV)
+ LFLAGS += $(LFCOV)
+ SYSLIBS += -lgcov
+endif
+
+ifeq ($(findstring dbg,$(MAKECMDGOALS)),dbg)
+ CFLAGS += $(CFDBG)
+ LFLAGS += $(LFDBG)
+endif
+
+ifeq ($(findstring prof,$(MAKECMDGOALS)),prof)
+ CFLAGS += $(CFPROF)
+ LFLAGS += $(LFPROF)
+endif
+
+ifeq ($(findstring rel,$(MAKECMDGOALS)),rel)
+ CFLAGS += $(CFREL)
+ LFLAGS += $(LFREL)
+endif
+
+ifeq ($(findstring tsan,$(MAKECMDGOALS)),tsan)
+ CFLAGS += $(CFTSAN)
+ LFLAGS += $(LFTSAN)
+endif
+
+ifeq ($(findstring b_,$(MAKECMDGOALS)),b_)
+ CFLAGS += $(CFBARE)
+ LFLAGS += $(CFBARE)
+endif
+
+##### search paths #####
+vpath %.c $(patsubst %,$(SRCDIR)/%:,$(SRCDIRS))
+
+##### implicit rules #####
+$(OBJDIR)/%.o : %.c
+ $(DG) $(DGFLAGS) $< >$(OBJDIR)/$*.d
+ $(CC) $(CFLAGS) -o $@ $<
+
+##### explicit rules #####
+$(ARPATHNAME) : $(OBJECTS)
+ $(AR) $(AFLAGS) $(ARPATHNAME) $(OBJECTS)
+
+$(SOPATHNAME) : $(OBJECTS)
+ $(LD) $(LFLAGS) $(OBJECTS) -o $(SOPATHNAME)
+ @ln -fs $(SOFILENAME) $(BINDIR)/$(SONAME)
+ @ln -fs $(SOFILENAME) $(BINDIR)/$(SOBASENAME)
+
+##### phony #####
+.PHONY : clean bare_ar_cov bare_ar_dbg bare_ar_prof bare_ar_rel bare_ar_tsan bare_so_cov bare_so_dbg bare_so_prof bare_so_rel bare_so_tsan hosted_ar_cov hosted_ar_dbg hosted_ar_prof hosted_ar_rel hosted_ar_tsan hosted_so_cov hosted_so_dbg hosted_so_prof hosted_so_rel hosted_so_tsan
+
+clean :
+ @rm -f $(BINDIR)/* $(OBJDIR)/*
+
+bare_ar_cov : $(ARPATHNAME) # bare, archive (.a), coverage
+bare_ar_dbg : $(ARPATHNAME) # bare, archive (.a), debug
+bare_ar_prof : $(ARPATHNAME) # bare, archive (.a), profiling
+bare_ar_rel : $(ARPATHNAME) # bare, archive (.a), release
+bare_ar_tsan : $(ARPATHNAME) # bare, archive (.a), thread sanitizer
+
+bare_so_cov : $(SOPATHNAME) # bare, shared (.so), coverage
+bare_so_dbg : $(SOPATHNAME) # bare, shared (.so), debug
+bare_so_prof : $(SOPATHNAME) # bare, shared (.so), profiling
+bare_so_rel : $(SOPATHNAME) # bare, shared (.so), release
+bare_so_tsan : $(SOPATHNAME) # bare, shared (.so), thread sanitizer
+
+hosted_ar_cov : $(ARPATHNAME) # hosted implementation, archive (.a), coverage
+hosted_ar_dbg : $(ARPATHNAME) # hosted implementation, archive (.a), debug
+hosted_ar_prof : $(ARPATHNAME) # hosted implementation, archive (.a), profiling
+hosted_ar_rel : $(ARPATHNAME) # hosted implementation, archive (.a), release
+hosted_ar_tsan : $(ARPATHNAME) # hosted implementation, archive (.a), thread sanitizer
+
+hosted_so_cov : $(SOPATHNAME) # hosted implementation, shared (.so), coverage
+hosted_so_dbg : $(SOPATHNAME) # hosted implementation, shared (.so), debug
+hosted_so_prof : $(SOPATHNAME) # hosted implementation, shared (.so), profiling
+hosted_so_rel : $(SOPATHNAME) # hosted implementation, shared (.so), release
+hosted_so_tsan : $(SOPATHNAME) # hosted implementation, shared (.so), thread sanitizer
+
+##### dependencies #####
+-include $(DEPENDS)
+
+##### notes #####
+# TRD : we use -std=gnu89 for C++ style comments
+# hosted implementation differs from bare simply in that ends up being included
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_kbuild_and_gnumake/Kbuild b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_kbuild_and_gnumake/Kbuild
new file mode 100644
index 0000000000..1ae6b36240
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_kbuild_and_gnumake/Kbuild
@@ -0,0 +1,76 @@
+lib-y :=
+
+lib-y += ../../src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_cleanup.o
+lib-y += ../../src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_get.o
+lib-y += ../../src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_init.o
+lib-y += ../../src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_insert.o
+lib-y += ../../src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_query.o
+
+lib-y += ../../src/lfds700_freelist/lfds700_freelist_cleanup.o
+lib-y += ../../src/lfds700_freelist/lfds700_freelist_init.o
+lib-y += ../../src/lfds700_freelist/lfds700_freelist_pop.o
+lib-y += ../../src/lfds700_freelist/lfds700_freelist_push.o
+lib-y += ../../src/lfds700_freelist/lfds700_freelist_query.o
+
+lib-y += ../../src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.o
+lib-y += ../../src/lfds700_hash_addonly/lfds700_hash_addonly_get.o
+lib-y += ../../src/lfds700_hash_addonly/lfds700_hash_addonly_init.o
+lib-y += ../../src/lfds700_hash_addonly/lfds700_hash_addonly_insert.o
+lib-y += ../../src/lfds700_hash_addonly/lfds700_hash_addonly_iterate.o
+lib-y += ../../src/lfds700_hash_addonly/lfds700_hash_addonly_query.o
+
+lib-y += ../../src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_cleanup.o
+lib-y += ../../src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_get.o
+lib-y += ../../src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_init.o
+lib-y += ../../src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_insert.o
+lib-y += ../../src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_query.o
+
+lib-y += ../../src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_cleanup.o
+lib-y += ../../src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_get.o
+lib-y += ../../src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_init.o
+lib-y += ../../src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_insert.o
+lib-y += ../../src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_query.o
+
+lib-y += ../../src/lfds700_misc/lfds700_misc_cleanup.o
+lib-y += ../../src/lfds700_misc/lfds700_misc_globals.o
+lib-y += ../../src/lfds700_misc/lfds700_misc_init.o
+lib-y += ../../src/lfds700_misc/lfds700_misc_prng.o
+lib-y += ../../src/lfds700_misc/lfds700_misc_query.o
+
+lib-y += ../../src/lfds700_queue/lfds700_queue_cleanup.o
+lib-y += ../../src/lfds700_queue/lfds700_queue_dequeue.o
+lib-y += ../../src/lfds700_queue/lfds700_queue_enqueue.o
+lib-y += ../../src/lfds700_queue/lfds700_queue_init.o
+lib-y += ../../src/lfds700_queue/lfds700_queue_query.o
+
+lib-y += ../../src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.o
+lib-y += ../../src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.o
+lib-y += ../../src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.o
+lib-y += ../../src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_init.o
+lib-y += ../../src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_query.o
+
+lib-y += ../../src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.o
+lib-y += ../../src/lfds700_ringbuffer/lfds700_ringbuffer_init.o
+lib-y += ../../src/lfds700_ringbuffer/lfds700_ringbuffer_query.o
+lib-y += ../../src/lfds700_ringbuffer/lfds700_ringbuffer_read.o
+lib-y += ../../src/lfds700_ringbuffer/lfds700_ringbuffer_write.o
+
+lib-y += ../../src/lfds700_stack/lfds700_stack_cleanup.o
+lib-y += ../../src/lfds700_stack/lfds700_stack_init.o
+lib-y += ../../src/lfds700_stack/lfds700_stack_pop.o
+lib-y += ../../src/lfds700_stack/lfds700_stack_push.o
+lib-y += ../../src/lfds700_stack/lfds700_stack_query.o
+
+libs-y := ../../bin/
+
+ccflags-y := -I$(src)/../../inc
+ccflags-y += -I$(src)/../../inc/liblfds700
+ccflags-y += -D_KERNEL_MODE
+ccflags-y += -fno-strict-aliasing
+ccflags-y += -std=gnu89
+ccflags-y += -Wall
+ccflags-y += -Werror
+ccflags-y += -Wno-unknown-pragmas
+ccflags-y += -Wno-unused-but-set-variable
+ccflags-y += -Wno-unused-variable
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_kbuild_and_gnumake/Makefile b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_kbuild_and_gnumake/Makefile
new file mode 100644
index 0000000000..d6de5f4b5d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/gcc_kbuild_and_gnumake/Makefile
@@ -0,0 +1,14 @@
+default:
+ $(MAKE) -C /lib/modules/`uname -r`/build M=$(PWD)
+
+clean:
+ $(MAKE) -C /lib/modules/`uname -r`/build M=$(PWD) clean
+ find ../../src/ -name "*.o" -type f -delete
+
+help:
+ $(MAKE) -C /lib/modules/`uname -r`/build M=$(PWD) help
+
+modules:
+ $(MAKE) -C /lib/modules/`uname -r`/build M=$(PWD) modules
+
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/sdk_for_windows_7_and_gnumake/liblfds700.def b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/sdk_for_windows_7_and_gnumake/liblfds700.def
new file mode 100644
index 0000000000..583ce35dbd
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/sdk_for_windows_7_and_gnumake/liblfds700.def
@@ -0,0 +1,69 @@
+EXPORTS
+
+lfds700_btree_au_init_valid_on_current_logical_core = lfds700_btree_au_init_valid_on_current_logical_core
+lfds700_btree_au_cleanup = lfds700_btree_au_cleanup
+lfds700_btree_au_insert = lfds700_btree_au_insert
+lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position = lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position
+lfds700_btree_au_get_by_absolute_position = lfds700_btree_au_get_by_absolute_position
+lfds700_btree_au_get_by_relative_position = lfds700_btree_au_get_by_relative_position
+lfds700_btree_au_get_by_key = lfds700_btree_au_get_by_key
+lfds700_btree_au_query = lfds700_btree_au_query
+
+lfds700_freelist_init_valid_on_current_logical_core = lfds700_freelist_init_valid_on_current_logical_core
+lfds700_freelist_cleanup = lfds700_freelist_cleanup
+lfds700_freelist_push = lfds700_freelist_push
+lfds700_freelist_pop = lfds700_freelist_pop
+lfds700_freelist_query = lfds700_freelist_query
+
+lfds700_hash_a_init_valid_on_current_logical_core = lfds700_hash_a_init_valid_on_current_logical_core
+lfds700_hash_a_cleanup = lfds700_hash_a_cleanup
+lfds700_hash_a_insert = lfds700_hash_a_insert
+lfds700_hash_a_get_by_key = lfds700_hash_a_get_by_key
+lfds700_hash_a_iterate_init = lfds700_hash_a_iterate_init
+lfds700_hash_a_iterate = lfds700_hash_a_iterate
+lfds700_hash_a_query = lfds700_hash_a_query
+
+lfds700_list_aos_init_valid_on_current_logical_core = lfds700_list_aos_init_valid_on_current_logical_core
+lfds700_list_aos_cleanup = lfds700_list_aos_cleanup
+lfds700_list_aos_insert = lfds700_list_aos_insert
+lfds700_list_aos_get_by_key = lfds700_list_aos_get_by_key
+lfds700_list_aos_query = lfds700_list_aos_query
+
+lfds700_list_asu_init_valid_on_current_logical_core = lfds700_list_asu_init_valid_on_current_logical_core
+lfds700_list_asu_cleanup = lfds700_list_asu_cleanup
+lfds700_list_asu_insert_at_position = lfds700_list_asu_insert_at_position
+lfds700_list_asu_insert_at_start = lfds700_list_asu_insert_at_start
+lfds700_list_asu_insert_at_end = lfds700_list_asu_insert_at_end
+lfds700_list_asu_insert_after_element = lfds700_list_asu_insert_after_element
+lfds700_list_asu_get_by_key = lfds700_list_asu_get_by_key
+lfds700_list_asu_query = lfds700_list_asu_query
+
+lfds700_misc_library_init_valid_on_current_logical_core = lfds700_misc_library_init_valid_on_current_logical_core
+lfds700_misc_library_cleanup = lfds700_misc_library_cleanup
+lfds700_misc_prng_init = lfds700_misc_prng_init
+lfds700_misc_query = lfds700_misc_query
+
+lfds700_queue_init_valid_on_current_logical_core = lfds700_queue_init_valid_on_current_logical_core
+lfds700_queue_cleanup = lfds700_queue_cleanup
+lfds700_queue_enqueue = lfds700_queue_enqueue
+lfds700_queue_dequeue = lfds700_queue_dequeue
+lfds700_queue_query = lfds700_queue_query
+
+lfds700_queue_bss_init_valid_on_current_logical_core = lfds700_queue_bss_init_valid_on_current_logical_core
+lfds700_queue_bss_cleanup = lfds700_queue_bss_cleanup
+lfds700_queue_bss_enqueue = lfds700_queue_bss_enqueue
+lfds700_queue_bss_dequeue = lfds700_queue_bss_dequeue
+lfds700_queue_bss_query = lfds700_queue_bss_query
+
+lfds700_ringbuffer_init_valid_on_current_logical_core = lfds700_ringbuffer_init_valid_on_current_logical_core
+lfds700_ringbuffer_cleanup = lfds700_ringbuffer_cleanup
+lfds700_ringbuffer_read = lfds700_ringbuffer_read
+lfds700_ringbuffer_write = lfds700_ringbuffer_write
+lfds700_ringbuffer_query = lfds700_ringbuffer_query
+
+lfds700_stack_init_valid_on_current_logical_core = lfds700_stack_init_valid_on_current_logical_core
+lfds700_stack_cleanup = lfds700_stack_cleanup
+lfds700_stack_push = lfds700_stack_push
+lfds700_stack_pop = lfds700_stack_pop
+lfds700_stack_query = lfds700_stack_query
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/sdk_for_windows_7_and_gnumake/makefile b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/sdk_for_windows_7_and_gnumake/makefile
new file mode 100644
index 0000000000..7b257c9277
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/sdk_for_windows_7_and_gnumake/makefile
@@ -0,0 +1,114 @@
+##### paths #####
+BINDIR := ..\..\bin
+INCDIR := ..\..\inc
+OBJDIR := ..\..\obj
+SRCDIR := ..\..\src
+
+##### misc #####
+QUIETLY := 1>nul 2>nul
+NULL :=
+SPACE := $(NULL) # TRD : with a trailing space
+
+##### sources, objects and libraries #####
+BINNAME := liblfds700
+LIB_BINARY := $(BINDIR)\$(BINNAME).lib
+DLL_BINARY := $(BINDIR)\$(BINNAME).dll
+SRCDIRS := lfds700_btree_addonly_unbalanced lfds700_freelist lfds700_hash_addonly lfds700_list_addonly_ordered_singlylinked lfds700_list_addonly_singlylinked_unordered lfds700_misc lfds700_queue lfds700_queue_bounded_singleconsumer_singleproducer lfds700_ringbuffer lfds700_stack
+SOURCES := lfds700_hash_addonly_cleanup.c lfds700_hash_addonly_get.c lfds700_hash_addonly_init.c lfds700_hash_addonly_insert.c lfds700_hash_addonly_iterate.c lfds700_hash_addonly_query.c \
+ lfds700_list_addonly_ordered_singlylinked_cleanup.c lfds700_list_addonly_ordered_singlylinked_get.c lfds700_list_addonly_ordered_singlylinked_init.c lfds700_list_addonly_ordered_singlylinked_insert.c lfds700_list_addonly_ordered_singlylinked_query.c \
+ lfds700_list_addonly_singlylinked_unordered_cleanup.c lfds700_list_addonly_singlylinked_unordered_get.c lfds700_list_addonly_singlylinked_unordered_init.c lfds700_list_addonly_singlylinked_unordered_insert.c lfds700_list_addonly_singlylinked_unordered_query.c \
+ lfds700_btree_addonly_unbalanced_cleanup.c lfds700_btree_addonly_unbalanced_get.c lfds700_btree_addonly_unbalanced_init.c lfds700_btree_addonly_unbalanced_insert.c lfds700_btree_addonly_unbalanced_query.c \
+ lfds700_freelist_cleanup.c lfds700_freelist_init.c lfds700_freelist_pop.c lfds700_freelist_push.c lfds700_freelist_query.c \
+ lfds700_misc_cleanup.c lfds700_misc_globals.c lfds700_misc_init.c lfds700_misc_prng.c lfds700_misc_query.c \
+ lfds700_queue_cleanup.c lfds700_queue_dequeue.c lfds700_queue_enqueue.c lfds700_queue_init.c lfds700_queue_query.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c lfds700_queue_bounded_singleconsumer_singleproducer_init.c lfds700_queue_bounded_singleconsumer_singleproducer_query.c \
+ lfds700_ringbuffer_cleanup.c lfds700_ringbuffer_init.c lfds700_ringbuffer_query.c lfds700_ringbuffer_read.c lfds700_ringbuffer_write.c \
+ lfds700_stack_cleanup.c lfds700_stack_init.c lfds700_stack_pop.c lfds700_stack_push.c lfds700_stack_query.c
+OBJECTS := $(patsubst %.c,$(OBJDIR)/%.obj,$(notdir $(SOURCES)))
+SYSLIBS := kernel32.lib
+
+##### default paths fix up #####
+INCDIRS := $(patsubst %,%;,$(INCDIR))
+INCLUDE += $(subst $(SPACE),,$(INCDIRS))
+
+##### tools #####
+MAKE := make
+MFLAGS :=
+
+CC := cl
+CBASE := /c "-I$(SRCDIR)" "/Fd$(BINDIR)\$(BINNAME).pdb" /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN /DUNICODE /D_UNICODE /DUNICODE /nologo /W4 /wd 4068 /WX
+CFREL := /DNDEBUG /Ox
+CFDBG := /D_DEBUG /Gm /Od /Zi
+
+AR := lib
+AFLAGS := /nologo /subsystem:console /verbose /wx
+
+LD := link
+LFBASE := /def:$(BINNAME).def /dll /nodefaultlib /nologo /nxcompat /subsystem:console /wx
+LFREL := /incremental:no
+LFDBG := /debug "/pdb:$(BINDIR)\$(BINNAME).pdb"
+
+##### variants #####
+CFLAGS := $(CBASE) $(CFDBG) /MTd
+ASFLAGS := $(ASBASE) $(ASDBG)
+LFLAGS := $(LFBASE) $(LFDBG)
+CLIB := libcmtd.lib
+
+ifeq ($(MAKECMDGOALS),librel)
+ CFLAGS := $(CBASE) $(CFREL) /MT
+ ASFLAGS := $(ASBASE) $(ASREL)
+ LFLAGS := $(LFBASE) $(LFREL)
+ CLIB := libcmt.lib
+endif
+
+ifeq ($(MAKECMDGOALS),libdbg)
+ CFLAGS := $(CBASE) $(CFDBG) /MTd
+ ASFLAGS := $(ASBASE) $(ASDBG)
+ LFLAGS := $(LFBASE) $(LFDBG)
+ CLIB := libcmtd.lib
+endif
+
+ifeq ($(MAKECMDGOALS),dllrel)
+ CFLAGS := $(CBASE) $(CFREL) /MD
+ ASFLAGS := $(ASBASE) $(ASREL)
+ LFLAGS := $(LFBASE) $(LFREL)
+ CLIB := msvcrt.lib
+endif
+
+ifeq ($(MAKECMDGOALS),dlldbg)
+ CFLAGS := $(CBASE) $(CFDBG) /MDd
+ ASFLAGS := $(ASBASE) $(ASDBG)
+ LFLAGS := $(LFBASE) $(LFDBG)
+ CLIB := msvcrtd.lib
+endif
+
+##### search paths #####
+vpath %.c $(patsubst %,$(SRCDIR)/%;,$(SRCDIRS))
+
+##### implicit rules #####
+$(OBJDIR)/%.obj : %.c
+ $(CC) $(CFLAGS) "/Fo$@" $<
+
+##### explicit rules #####
+$(LIB_BINARY) : $(OBJECTS)
+ $(AR) $(AFLAGS) $(OBJECTS) /out:$(LIB_BINARY)
+
+$(DLL_BINARY) : $(OBJECTS)
+ $(LD) $(LFLAGS) $(CLIB) $(SYSLIBS) $(OBJECTS) /out:$(DLL_BINARY)
+
+##### phony #####
+.PHONY : clean librel libdbg dllrel dlldbg
+
+clean :
+ @erase /Q $(BINDIR)\$(BINNAME).* $(OBJDIR)\*.obj $(QUIETLY)
+
+dlldbg : $(DLL_BINARY)
+dllrel : $(DLL_BINARY)
+
+libdbg : $(LIB_BINARY)
+librel : $(LIB_BINARY)
+
+##### notes #####
+# /wd 4068 : turn off "unknown pragma" warning
+
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.def b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.def
new file mode 100644
index 0000000000..583ce35dbd
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.def
@@ -0,0 +1,69 @@
+EXPORTS
+
+lfds700_btree_au_init_valid_on_current_logical_core = lfds700_btree_au_init_valid_on_current_logical_core
+lfds700_btree_au_cleanup = lfds700_btree_au_cleanup
+lfds700_btree_au_insert = lfds700_btree_au_insert
+lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position = lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position
+lfds700_btree_au_get_by_absolute_position = lfds700_btree_au_get_by_absolute_position
+lfds700_btree_au_get_by_relative_position = lfds700_btree_au_get_by_relative_position
+lfds700_btree_au_get_by_key = lfds700_btree_au_get_by_key
+lfds700_btree_au_query = lfds700_btree_au_query
+
+lfds700_freelist_init_valid_on_current_logical_core = lfds700_freelist_init_valid_on_current_logical_core
+lfds700_freelist_cleanup = lfds700_freelist_cleanup
+lfds700_freelist_push = lfds700_freelist_push
+lfds700_freelist_pop = lfds700_freelist_pop
+lfds700_freelist_query = lfds700_freelist_query
+
+lfds700_hash_a_init_valid_on_current_logical_core = lfds700_hash_a_init_valid_on_current_logical_core
+lfds700_hash_a_cleanup = lfds700_hash_a_cleanup
+lfds700_hash_a_insert = lfds700_hash_a_insert
+lfds700_hash_a_get_by_key = lfds700_hash_a_get_by_key
+lfds700_hash_a_iterate_init = lfds700_hash_a_iterate_init
+lfds700_hash_a_iterate = lfds700_hash_a_iterate
+lfds700_hash_a_query = lfds700_hash_a_query
+
+lfds700_list_aos_init_valid_on_current_logical_core = lfds700_list_aos_init_valid_on_current_logical_core
+lfds700_list_aos_cleanup = lfds700_list_aos_cleanup
+lfds700_list_aos_insert = lfds700_list_aos_insert
+lfds700_list_aos_get_by_key = lfds700_list_aos_get_by_key
+lfds700_list_aos_query = lfds700_list_aos_query
+
+lfds700_list_asu_init_valid_on_current_logical_core = lfds700_list_asu_init_valid_on_current_logical_core
+lfds700_list_asu_cleanup = lfds700_list_asu_cleanup
+lfds700_list_asu_insert_at_position = lfds700_list_asu_insert_at_position
+lfds700_list_asu_insert_at_start = lfds700_list_asu_insert_at_start
+lfds700_list_asu_insert_at_end = lfds700_list_asu_insert_at_end
+lfds700_list_asu_insert_after_element = lfds700_list_asu_insert_after_element
+lfds700_list_asu_get_by_key = lfds700_list_asu_get_by_key
+lfds700_list_asu_query = lfds700_list_asu_query
+
+lfds700_misc_library_init_valid_on_current_logical_core = lfds700_misc_library_init_valid_on_current_logical_core
+lfds700_misc_library_cleanup = lfds700_misc_library_cleanup
+lfds700_misc_prng_init = lfds700_misc_prng_init
+lfds700_misc_query = lfds700_misc_query
+
+lfds700_queue_init_valid_on_current_logical_core = lfds700_queue_init_valid_on_current_logical_core
+lfds700_queue_cleanup = lfds700_queue_cleanup
+lfds700_queue_enqueue = lfds700_queue_enqueue
+lfds700_queue_dequeue = lfds700_queue_dequeue
+lfds700_queue_query = lfds700_queue_query
+
+lfds700_queue_bss_init_valid_on_current_logical_core = lfds700_queue_bss_init_valid_on_current_logical_core
+lfds700_queue_bss_cleanup = lfds700_queue_bss_cleanup
+lfds700_queue_bss_enqueue = lfds700_queue_bss_enqueue
+lfds700_queue_bss_dequeue = lfds700_queue_bss_dequeue
+lfds700_queue_bss_query = lfds700_queue_bss_query
+
+lfds700_ringbuffer_init_valid_on_current_logical_core = lfds700_ringbuffer_init_valid_on_current_logical_core
+lfds700_ringbuffer_cleanup = lfds700_ringbuffer_cleanup
+lfds700_ringbuffer_read = lfds700_ringbuffer_read
+lfds700_ringbuffer_write = lfds700_ringbuffer_write
+lfds700_ringbuffer_query = lfds700_ringbuffer_query
+
+lfds700_stack_init_valid_on_current_logical_core = lfds700_stack_init_valid_on_current_logical_core
+lfds700_stack_cleanup = lfds700_stack_cleanup
+lfds700_stack_push = lfds700_stack_push
+lfds700_stack_pop = lfds700_stack_pop
+lfds700_stack_query = lfds700_stack_query
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.sln b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.sln
new file mode 100644
index 0000000000..b52c44e46f
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblfds700", "liblfds700.vcxproj", "{1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug DLL|Win32 = Debug DLL|Win32
+ Debug DLL|x64 = Debug DLL|x64
+ Debug LIB|Win32 = Debug LIB|Win32
+ Debug LIB|x64 = Debug LIB|x64
+ Release DLL|Win32 = Release DLL|Win32
+ Release DLL|x64 = Release DLL|x64
+ Release LIB|Win32 = Release LIB|Win32
+ Release LIB|x64 = Release LIB|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.Deploy.0 = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.ActiveCfg = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.Build.0 = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.Deploy.0 = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.ActiveCfg = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.Build.0 = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.Deploy.0 = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.ActiveCfg = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.Build.0 = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.Deploy.0 = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.Build.0 = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.Deploy.0 = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.ActiveCfg = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.Build.0 = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.Deploy.0 = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.ActiveCfg = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.Build.0 = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.Deploy.0 = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.ActiveCfg = Release LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.Build.0 = Release LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.Deploy.0 = Release LIB|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj
new file mode 100644
index 0000000000..3d4bf6364f
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj
@@ -0,0 +1,705 @@
+
+
+
+
+ Debug DLL
+ Win32
+
+
+ Debug DLL
+ x64
+
+
+ Debug LIB
+ Win32
+
+
+ Debug LIB
+ x64
+
+
+ Release DLL
+ Win32
+
+
+ Release DLL
+ x64
+
+
+ Release LIB
+ Win32
+
+
+ Release LIB
+ x64
+
+
+
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}
+ Win32Proj
+
+
+
+ StaticLibrary
+ true
+ v110
+
+
+ DynamicLibrary
+ true
+ v110
+
+
+ StaticLibrary
+ true
+ v110
+
+
+ DynamicLibrary
+ true
+ v110
+
+
+ StaticLibrary
+ false
+ v110
+ true
+
+
+ DynamicLibrary
+ false
+ v110
+ true
+
+
+ StaticLibrary
+ false
+ v110
+ true
+
+
+ DynamicLibrary
+ false
+ v110
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+
+
+ MachineX86
+ true
+ Windows
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+
+
+ false
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+
+
+ MachineX86
+ true
+ Console
+ kernel32.lib;msvcrtd.lib
+
+
+ true
+ true
+ liblfds700.def
+ true
+ NoErrorReport
+ true
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+
+
+ false
+ true
+
+
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ false
+
+
+ true
+ Windows
+
+
+ true
+
+
+ MachineX64
+
+
+ Console
+
+
+ false
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ false
+
+
+ true
+ Console
+ true
+ true
+ liblfds700.def
+ true
+ false
+ NoErrorReport
+ kernel32.lib;msvcrtd.lib
+ true
+
+
+ true
+
+
+ MachineX64
+
+
+ Console
+
+
+ false
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+
+
+ MachineX86
+ true
+ Windows
+ true
+ true
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDLL
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+
+
+ MachineX86
+ false
+ Console
+ true
+ true
+ kernel32.lib;msvcrt.lib
+
+
+ true
+ true
+ liblfds700.def
+ NoErrorReport
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+ true
+
+
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+
+
+ true
+ Windows
+ true
+ true
+
+
+ true
+
+
+ MachineX64
+
+
+ Console
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDLL
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+
+
+ false
+ Console
+ true
+ true
+ true
+ true
+ liblfds700.def
+ NoErrorReport
+ kernel32.lib;msvcrt.lib
+
+
+ true
+
+
+ MachineX64
+
+
+ Console
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj.filters b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj.filters
new file mode 100644
index 0000000000..5ec0bea579
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj.filters
@@ -0,0 +1,279 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
+
+
+ {258be429-7dac-4999-b995-753aa2f0c505}
+
+
+ {469abf8e-47d8-4678-bd66-7c7e65c5f52e}
+
+
+ {62ee141b-2acb-4555-b016-7be20a57f2bf}
+
+
+ {19c73b0f-25e0-4166-9093-427f1dfb4f70}
+
+
+ {00eb30fe-e638-4c2b-8ca1-1f09c4a0ed45}
+
+
+ {400ae4e9-2281-4549-b918-59d1a27a2d07}
+
+
+ {0b1fafc3-817b-4c18-8eb1-121884e3a29b}
+
+
+ {bcbadc74-1748-4696-aad7-7fdbe5614624}
+
+
+ {c45194af-7b41-4c28-bc0e-1095ec347664}
+
+
+ {6250c4d5-ac8e-4c28-93de-0954c5bed1cb}
+
+
+ {3ac93721-1d81-49e4-9581-dbc12ace5c0c}
+
+
+
+
+ Header Files
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_stack
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj.user b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj.user
new file mode 100644
index 0000000000..7cbb3216ad
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012/liblfds700.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/driver_entry.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/driver_entry.c
new file mode 100644
index 0000000000..9ea5612e54
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/driver_entry.c
@@ -0,0 +1 @@
+#include
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.def b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.def
new file mode 100644
index 0000000000..583ce35dbd
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.def
@@ -0,0 +1,69 @@
+EXPORTS
+
+lfds700_btree_au_init_valid_on_current_logical_core = lfds700_btree_au_init_valid_on_current_logical_core
+lfds700_btree_au_cleanup = lfds700_btree_au_cleanup
+lfds700_btree_au_insert = lfds700_btree_au_insert
+lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position = lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position
+lfds700_btree_au_get_by_absolute_position = lfds700_btree_au_get_by_absolute_position
+lfds700_btree_au_get_by_relative_position = lfds700_btree_au_get_by_relative_position
+lfds700_btree_au_get_by_key = lfds700_btree_au_get_by_key
+lfds700_btree_au_query = lfds700_btree_au_query
+
+lfds700_freelist_init_valid_on_current_logical_core = lfds700_freelist_init_valid_on_current_logical_core
+lfds700_freelist_cleanup = lfds700_freelist_cleanup
+lfds700_freelist_push = lfds700_freelist_push
+lfds700_freelist_pop = lfds700_freelist_pop
+lfds700_freelist_query = lfds700_freelist_query
+
+lfds700_hash_a_init_valid_on_current_logical_core = lfds700_hash_a_init_valid_on_current_logical_core
+lfds700_hash_a_cleanup = lfds700_hash_a_cleanup
+lfds700_hash_a_insert = lfds700_hash_a_insert
+lfds700_hash_a_get_by_key = lfds700_hash_a_get_by_key
+lfds700_hash_a_iterate_init = lfds700_hash_a_iterate_init
+lfds700_hash_a_iterate = lfds700_hash_a_iterate
+lfds700_hash_a_query = lfds700_hash_a_query
+
+lfds700_list_aos_init_valid_on_current_logical_core = lfds700_list_aos_init_valid_on_current_logical_core
+lfds700_list_aos_cleanup = lfds700_list_aos_cleanup
+lfds700_list_aos_insert = lfds700_list_aos_insert
+lfds700_list_aos_get_by_key = lfds700_list_aos_get_by_key
+lfds700_list_aos_query = lfds700_list_aos_query
+
+lfds700_list_asu_init_valid_on_current_logical_core = lfds700_list_asu_init_valid_on_current_logical_core
+lfds700_list_asu_cleanup = lfds700_list_asu_cleanup
+lfds700_list_asu_insert_at_position = lfds700_list_asu_insert_at_position
+lfds700_list_asu_insert_at_start = lfds700_list_asu_insert_at_start
+lfds700_list_asu_insert_at_end = lfds700_list_asu_insert_at_end
+lfds700_list_asu_insert_after_element = lfds700_list_asu_insert_after_element
+lfds700_list_asu_get_by_key = lfds700_list_asu_get_by_key
+lfds700_list_asu_query = lfds700_list_asu_query
+
+lfds700_misc_library_init_valid_on_current_logical_core = lfds700_misc_library_init_valid_on_current_logical_core
+lfds700_misc_library_cleanup = lfds700_misc_library_cleanup
+lfds700_misc_prng_init = lfds700_misc_prng_init
+lfds700_misc_query = lfds700_misc_query
+
+lfds700_queue_init_valid_on_current_logical_core = lfds700_queue_init_valid_on_current_logical_core
+lfds700_queue_cleanup = lfds700_queue_cleanup
+lfds700_queue_enqueue = lfds700_queue_enqueue
+lfds700_queue_dequeue = lfds700_queue_dequeue
+lfds700_queue_query = lfds700_queue_query
+
+lfds700_queue_bss_init_valid_on_current_logical_core = lfds700_queue_bss_init_valid_on_current_logical_core
+lfds700_queue_bss_cleanup = lfds700_queue_bss_cleanup
+lfds700_queue_bss_enqueue = lfds700_queue_bss_enqueue
+lfds700_queue_bss_dequeue = lfds700_queue_bss_dequeue
+lfds700_queue_bss_query = lfds700_queue_bss_query
+
+lfds700_ringbuffer_init_valid_on_current_logical_core = lfds700_ringbuffer_init_valid_on_current_logical_core
+lfds700_ringbuffer_cleanup = lfds700_ringbuffer_cleanup
+lfds700_ringbuffer_read = lfds700_ringbuffer_read
+lfds700_ringbuffer_write = lfds700_ringbuffer_write
+lfds700_ringbuffer_query = lfds700_ringbuffer_query
+
+lfds700_stack_init_valid_on_current_logical_core = lfds700_stack_init_valid_on_current_logical_core
+lfds700_stack_cleanup = lfds700_stack_cleanup
+lfds700_stack_push = lfds700_stack_push
+lfds700_stack_pop = lfds700_stack_pop
+lfds700_stack_query = lfds700_stack_query
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.sln b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.sln
new file mode 100644
index 0000000000..b52c44e46f
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.sln
@@ -0,0 +1,46 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblfds700", "liblfds700.vcxproj", "{1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug DLL|Win32 = Debug DLL|Win32
+ Debug DLL|x64 = Debug DLL|x64
+ Debug LIB|Win32 = Debug LIB|Win32
+ Debug LIB|x64 = Debug LIB|x64
+ Release DLL|Win32 = Release DLL|Win32
+ Release DLL|x64 = Release DLL|x64
+ Release LIB|Win32 = Release LIB|Win32
+ Release LIB|x64 = Release LIB|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.Deploy.0 = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.ActiveCfg = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.Build.0 = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.Deploy.0 = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.ActiveCfg = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.Build.0 = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.Deploy.0 = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.ActiveCfg = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.Build.0 = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.Deploy.0 = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.Build.0 = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.Deploy.0 = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.ActiveCfg = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.Build.0 = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.Deploy.0 = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.ActiveCfg = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.Build.0 = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.Deploy.0 = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.ActiveCfg = Release LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.Build.0 = Release LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.Deploy.0 = Release LIB|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj
new file mode 100644
index 0000000000..f19ead0c18
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj
@@ -0,0 +1,733 @@
+
+
+
+
+ Debug DLL
+ Win32
+
+
+ Debug DLL
+ x64
+
+
+ Debug LIB
+ Win32
+
+
+ Debug LIB
+ x64
+
+
+ Release DLL
+ Win32
+
+
+ Release DLL
+ x64
+
+
+ Release LIB
+ Win32
+
+
+ Release LIB
+ x64
+
+
+
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}
+ Win32Proj
+
+
+
+ StaticLibrary
+ true
+ WindowsKernelModeDriver8.0
+
+
+ DynamicLibrary
+ true
+ WindowsKernelModeDriver8.0
+
+
+ StaticLibrary
+ true
+ WindowsKernelModeDriver8.0
+
+
+ DynamicLibrary
+ true
+ WindowsKernelModeDriver8.0
+
+
+ StaticLibrary
+ false
+ WindowsKernelModeDriver8.0
+ true
+
+
+ DynamicLibrary
+ false
+ WindowsKernelModeDriver8.0
+ true
+
+
+ StaticLibrary
+ false
+ WindowsKernelModeDriver8.0
+ true
+
+
+ DynamicLibrary
+ false
+ WindowsKernelModeDriver8.0
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ /kernel %(AdditionalOptions)
+
+
+ MachineX86
+ true
+ Windows
+
+
+ true
+
+
+ MachineX86
+
+
+ Native
+
+
+ false
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ /kernel %(AdditionalOptions)
+
+
+ MachineX86
+ true
+ Native
+ kernel32.lib;msvcrtd.lib
+
+
+ true
+ true
+ liblfds700.def
+ true
+ NoErrorReport
+ true
+ WDM
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+
+
+ false
+ true
+
+
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ false
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Windows
+
+
+ true
+
+
+ MachineX64
+
+
+ Native
+
+
+ false
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ false
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Native
+ true
+ true
+ liblfds700.def
+ true
+ false
+ NoErrorReport
+ kernel32.lib;msvcrtd.lib
+ true
+ WDM
+
+
+ true
+
+
+ MachineX64
+
+
+ Console
+
+
+ false
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ MachineX86
+ true
+ Windows
+ true
+ true
+
+
+ true
+
+
+ MachineX86
+
+
+ Native
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDLL
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ MachineX86
+ false
+ Native
+ true
+ true
+ kernel32.lib;msvcrt.lib
+
+
+ true
+ true
+ liblfds700.def
+ NoErrorReport
+ WDM
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+ true
+
+
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Windows
+ true
+ true
+
+
+ true
+
+
+ MachineX64
+
+
+ Native
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDLL
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ false
+ Native
+ true
+ true
+ true
+ true
+ liblfds700.def
+ NoErrorReport
+ kernel32.lib;msvcrt.lib
+ WDM
+
+
+ true
+
+
+ MachineX64
+
+
+ Console
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj.filters b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj.filters
new file mode 100644
index 0000000000..978f8ec1c9
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj.filters
@@ -0,0 +1,279 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
+
+
+ {258be429-7dac-4999-b995-753aa2f0c505}
+
+
+ {469abf8e-47d8-4678-bd66-7c7e65c5f52e}
+
+
+ {62ee141b-2acb-4555-b016-7be20a57f2bf}
+
+
+ {19c73b0f-25e0-4166-9093-427f1dfb4f70}
+
+
+ {00eb30fe-e638-4c2b-8ca1-1f09c4a0ed45}
+
+
+ {6250c4d5-ac8e-4c28-93de-0954c5bed1cb}
+
+
+ {400ae4e9-2281-4549-b918-59d1a27a2d07}
+
+
+ {c45194af-7b41-4c28-bc0e-1095ec347664}
+
+
+ {8b3cbb5c-7436-429f-9b72-bae1f4721746}
+
+
+ {bcbadc74-1748-4696-aad7-7fdbe5614624}
+
+
+ {0b1fafc3-817b-4c18-8eb1-121884e3a29b}
+
+
+
+
+ Header Files
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_queue
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_ringbuffer
+
+
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj.user b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj.user
new file mode 100644
index 0000000000..7cbb3216ad
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2012_and_wdk_8.0/liblfds700.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/driver_entry.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/driver_entry.c
new file mode 100644
index 0000000000..9ea5612e54
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/driver_entry.c
@@ -0,0 +1 @@
+#include
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.def b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.def
new file mode 100644
index 0000000000..583ce35dbd
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.def
@@ -0,0 +1,69 @@
+EXPORTS
+
+lfds700_btree_au_init_valid_on_current_logical_core = lfds700_btree_au_init_valid_on_current_logical_core
+lfds700_btree_au_cleanup = lfds700_btree_au_cleanup
+lfds700_btree_au_insert = lfds700_btree_au_insert
+lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position = lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position
+lfds700_btree_au_get_by_absolute_position = lfds700_btree_au_get_by_absolute_position
+lfds700_btree_au_get_by_relative_position = lfds700_btree_au_get_by_relative_position
+lfds700_btree_au_get_by_key = lfds700_btree_au_get_by_key
+lfds700_btree_au_query = lfds700_btree_au_query
+
+lfds700_freelist_init_valid_on_current_logical_core = lfds700_freelist_init_valid_on_current_logical_core
+lfds700_freelist_cleanup = lfds700_freelist_cleanup
+lfds700_freelist_push = lfds700_freelist_push
+lfds700_freelist_pop = lfds700_freelist_pop
+lfds700_freelist_query = lfds700_freelist_query
+
+lfds700_hash_a_init_valid_on_current_logical_core = lfds700_hash_a_init_valid_on_current_logical_core
+lfds700_hash_a_cleanup = lfds700_hash_a_cleanup
+lfds700_hash_a_insert = lfds700_hash_a_insert
+lfds700_hash_a_get_by_key = lfds700_hash_a_get_by_key
+lfds700_hash_a_iterate_init = lfds700_hash_a_iterate_init
+lfds700_hash_a_iterate = lfds700_hash_a_iterate
+lfds700_hash_a_query = lfds700_hash_a_query
+
+lfds700_list_aos_init_valid_on_current_logical_core = lfds700_list_aos_init_valid_on_current_logical_core
+lfds700_list_aos_cleanup = lfds700_list_aos_cleanup
+lfds700_list_aos_insert = lfds700_list_aos_insert
+lfds700_list_aos_get_by_key = lfds700_list_aos_get_by_key
+lfds700_list_aos_query = lfds700_list_aos_query
+
+lfds700_list_asu_init_valid_on_current_logical_core = lfds700_list_asu_init_valid_on_current_logical_core
+lfds700_list_asu_cleanup = lfds700_list_asu_cleanup
+lfds700_list_asu_insert_at_position = lfds700_list_asu_insert_at_position
+lfds700_list_asu_insert_at_start = lfds700_list_asu_insert_at_start
+lfds700_list_asu_insert_at_end = lfds700_list_asu_insert_at_end
+lfds700_list_asu_insert_after_element = lfds700_list_asu_insert_after_element
+lfds700_list_asu_get_by_key = lfds700_list_asu_get_by_key
+lfds700_list_asu_query = lfds700_list_asu_query
+
+lfds700_misc_library_init_valid_on_current_logical_core = lfds700_misc_library_init_valid_on_current_logical_core
+lfds700_misc_library_cleanup = lfds700_misc_library_cleanup
+lfds700_misc_prng_init = lfds700_misc_prng_init
+lfds700_misc_query = lfds700_misc_query
+
+lfds700_queue_init_valid_on_current_logical_core = lfds700_queue_init_valid_on_current_logical_core
+lfds700_queue_cleanup = lfds700_queue_cleanup
+lfds700_queue_enqueue = lfds700_queue_enqueue
+lfds700_queue_dequeue = lfds700_queue_dequeue
+lfds700_queue_query = lfds700_queue_query
+
+lfds700_queue_bss_init_valid_on_current_logical_core = lfds700_queue_bss_init_valid_on_current_logical_core
+lfds700_queue_bss_cleanup = lfds700_queue_bss_cleanup
+lfds700_queue_bss_enqueue = lfds700_queue_bss_enqueue
+lfds700_queue_bss_dequeue = lfds700_queue_bss_dequeue
+lfds700_queue_bss_query = lfds700_queue_bss_query
+
+lfds700_ringbuffer_init_valid_on_current_logical_core = lfds700_ringbuffer_init_valid_on_current_logical_core
+lfds700_ringbuffer_cleanup = lfds700_ringbuffer_cleanup
+lfds700_ringbuffer_read = lfds700_ringbuffer_read
+lfds700_ringbuffer_write = lfds700_ringbuffer_write
+lfds700_ringbuffer_query = lfds700_ringbuffer_query
+
+lfds700_stack_init_valid_on_current_logical_core = lfds700_stack_init_valid_on_current_logical_core
+lfds700_stack_cleanup = lfds700_stack_cleanup
+lfds700_stack_push = lfds700_stack_push
+lfds700_stack_pop = lfds700_stack_pop
+lfds700_stack_query = lfds700_stack_query
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.sln b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.sln
new file mode 100644
index 0000000000..1cc19a8e23
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.sln
@@ -0,0 +1,59 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2013
+VisualStudioVersion = 12.0.40629.0
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblfds700", "liblfds700.vcxproj", "{1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug DLL|ARM = Debug DLL|ARM
+ Debug DLL|Win32 = Debug DLL|Win32
+ Debug DLL|x64 = Debug DLL|x64
+ Debug LIB|ARM = Debug LIB|ARM
+ Debug LIB|Win32 = Debug LIB|Win32
+ Debug LIB|x64 = Debug LIB|x64
+ Release DLL|ARM = Release DLL|ARM
+ Release DLL|Win32 = Release DLL|Win32
+ Release DLL|x64 = Release DLL|x64
+ Release LIB|ARM = Release LIB|ARM
+ Release LIB|Win32 = Release LIB|Win32
+ Release LIB|x64 = Release LIB|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|ARM.ActiveCfg = Debug DLL|ARM
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|ARM.Build.0 = Debug DLL|ARM
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.Deploy.0 = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.ActiveCfg = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.Build.0 = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.Deploy.0 = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|ARM.ActiveCfg = Debug LIB|ARM
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|ARM.Build.0 = Debug LIB|ARM
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.ActiveCfg = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.Build.0 = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.Deploy.0 = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.ActiveCfg = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.Build.0 = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.Deploy.0 = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|ARM.ActiveCfg = Release DLL|ARM
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|ARM.Build.0 = Release DLL|ARM
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.Build.0 = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.Deploy.0 = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.ActiveCfg = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.Build.0 = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.Deploy.0 = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|ARM.ActiveCfg = Release LIB|ARM
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|ARM.Build.0 = Release LIB|ARM
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.ActiveCfg = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.Build.0 = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.Deploy.0 = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.ActiveCfg = Release LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.Build.0 = Release LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.Deploy.0 = Release LIB|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj
new file mode 100644
index 0000000000..e67a540e37
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj
@@ -0,0 +1,1054 @@
+
+
+
+
+ Debug DLL
+ ARM
+
+
+ Debug DLL
+ Win32
+
+
+ Debug DLL
+ x64
+
+
+ Debug LIB
+ ARM
+
+
+ Debug LIB
+ Win32
+
+
+ Debug LIB
+ x64
+
+
+ Release DLL
+ ARM
+
+
+ Release DLL
+ Win32
+
+
+ Release DLL
+ x64
+
+
+ Release LIB
+ ARM
+
+
+ Release LIB
+ Win32
+
+
+ Release LIB
+ x64
+
+
+
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}
+ Win32Proj
+
+
+
+ StaticLibrary
+ true
+ WindowsKernelModeDriver8.1
+
+
+ StaticLibrary
+ true
+ WindowsKernelModeDriver8.1
+
+
+ DynamicLibrary
+ true
+ WindowsKernelModeDriver8.1
+
+
+ DynamicLibrary
+ true
+ WindowsKernelModeDriver8.1
+
+
+ StaticLibrary
+ true
+ WindowsKernelModeDriver8.1
+
+
+ DynamicLibrary
+ true
+ WindowsKernelModeDriver8.1
+
+
+ StaticLibrary
+ false
+ WindowsKernelModeDriver8.1
+ true
+
+
+ StaticLibrary
+ false
+ WindowsKernelModeDriver8.1
+ true
+
+
+ DynamicLibrary
+ false
+ WindowsKernelModeDriver8.1
+ true
+
+
+ DynamicLibrary
+ false
+ WindowsKernelModeDriver8.1
+ true
+
+
+ StaticLibrary
+ false
+ WindowsKernelModeDriver8.1
+ true
+
+
+ DynamicLibrary
+ false
+ WindowsKernelModeDriver8.1
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);$(WDKContentRoot)include\km\;$(WDKContentRoot)include\wdf\kmdf\1.11\
+ $(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);$(WDKContentRoot)lib\wdf\kmdf\x86\
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath)
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath)
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);$(WDKContentRoot)include\km\;$(WDKContentRoot)include\wdf\kmdf\1.11\
+ $(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);$(WDKContentRoot)lib\wdf\kmdf\x86\
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath)
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath)
+ $(VC_IncludePath);$(WindowsSDK_IncludePath);$(MSBuildToolsPath);$(MSBuildFrameworkToolsPath);$(MSBuild_ExecutablePath);$(VC_LibraryPath_ARM);
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);$(WDKContentRoot)include\km\;$(WDKContentRoot)include\wdf\kmdf\1.11\
+ $(VCInstallDir)lib\amd64;$(VCInstallDir)atlmfc\lib\amd64;$(WindowsSDK_LibraryPath_x64);;$(WDKContentRoot)lib\wdf\kmdf\x64\
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);$(WDKContentRoot)include\km\;$(WDKContentRoot)include\wdf\kmdf\1.11\
+ $(VCInstallDir)lib\amd64;$(VCInstallDir)atlmfc\lib\amd64;$(WindowsSDK_LibraryPath_x64);;$(WDKContentRoot)lib\wdf\kmdf\x64\
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);$(WDKContentRoot)include\km\;$(WDKContentRoot)include\wdf\kmdf\1.11\
+ $(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);$(WDKContentRoot)lib\wdf\kmdf\x86\
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath)
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath)
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);$(WDKContentRoot)include\km\;$(WDKContentRoot)include\wdf\kmdf\1.11\
+ $(VCInstallDir)lib;$(VCInstallDir)atlmfc\lib;$(WindowsSDK_LibraryPath_x86);$(WDKContentRoot)lib\wdf\kmdf\x86\
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath)
+ $(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath)
+
+
+ true
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);$(WDKContentRoot)include\km\;$(WDKContentRoot)include\wdf\kmdf\1.11\
+ $(VCInstallDir)lib\amd64;$(VCInstallDir)atlmfc\lib\amd64;$(WindowsSDK_LibraryPath_x64);;$(WDKContentRoot)lib\wdf\kmdf\x64\
+
+
+
+
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+ $(ProjectDir);$(IncludePath);$(WDKContentRoot)include\km\;$(WDKContentRoot)include\wdf\kmdf\1.11\
+ $(VCInstallDir)lib\amd64;$(VCInstallDir)atlmfc\lib\amd64;$(WindowsSDK_LibraryPath_x64);;$(WDKContentRoot)lib\wdf\kmdf\x64\
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ /kernel %(AdditionalOptions)
+
+
+ MachineX86
+ true
+ Windows
+
+
+ true
+
+
+ MachineX86
+
+
+ Native
+
+
+ false
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Windows
+
+
+ true
+
+
+ MachineARM
+
+
+ Native
+
+
+ false
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ /kernel %(AdditionalOptions)
+
+
+ MachineX86
+ true
+ Native
+ kernel32.lib;msvcrtd.lib
+
+
+ true
+ true
+ liblfds700.def
+ true
+ NoErrorReport
+ true
+ WDM
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+
+
+ false
+ true
+
+
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Native
+ kernel32.lib;msvcrtd.lib
+
+
+ true
+ true
+ liblfds700.def
+ true
+ NoErrorReport
+ true
+ WDM
+
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+
+
+ false
+ true
+
+
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ false
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Windows
+
+
+ true
+
+
+ MachineX64
+
+
+ Native
+
+
+ false
+ true
+
+
+
+
+ WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ false
+ true
+
+
+
+
+
+
+ true
+ false
+ false
+ false
+ true
+ CompileAsC
+ true
+ None
+ true
+ false
+ 4068
+ false
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Native
+ true
+ true
+ liblfds700.def
+ true
+ false
+ NoErrorReport
+ kernel32.lib;msvcrtd.lib
+ true
+ WDM
+
+
+ true
+
+
+ MachineX64
+
+
+ Console
+
+
+ false
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ MachineX86
+ true
+ Windows
+ true
+ true
+
+
+ true
+
+
+ MachineX86
+
+
+ Native
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Windows
+ true
+ true
+
+
+ true
+
+
+ MachineARM
+
+
+ Native
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDLL
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ MachineX86
+ false
+ Native
+ true
+ true
+ kernel32.lib;msvcrt.lib
+
+
+ true
+ true
+ liblfds700.def
+ NoErrorReport
+ WDM
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+ true
+
+
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDLL
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ false
+ Native
+ true
+ true
+ kernel32.lib;msvcrt.lib
+
+
+ true
+ true
+ liblfds700.def
+ NoErrorReport
+ WDM
+
+
+
+ true
+
+
+ MachineX86
+
+
+ Console
+ true
+
+
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ true
+ Windows
+ true
+ true
+
+
+ true
+
+
+ MachineX64
+
+
+ Native
+ true
+
+
+
+
+ WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)
+
+
+ MultiThreadedDLL
+ Level4
+ None
+ false
+ false
+ true
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ false
+ false
+
+
+
+
+
+
+ false
+
+
+ false
+ false
+ CompileAsC
+ true
+ None
+ true
+ 4068
+ true
+ /kernel %(AdditionalOptions)
+
+
+ false
+ Native
+ true
+ true
+ true
+ true
+ liblfds700.def
+ NoErrorReport
+ kernel32.lib;msvcrt.lib
+ WDM
+
+
+ true
+
+
+ MachineX64
+
+
+ Console
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj.filters b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj.filters
new file mode 100644
index 0000000000..978f8ec1c9
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj.filters
@@ -0,0 +1,279 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
+
+
+ {258be429-7dac-4999-b995-753aa2f0c505}
+
+
+ {469abf8e-47d8-4678-bd66-7c7e65c5f52e}
+
+
+ {62ee141b-2acb-4555-b016-7be20a57f2bf}
+
+
+ {19c73b0f-25e0-4166-9093-427f1dfb4f70}
+
+
+ {00eb30fe-e638-4c2b-8ca1-1f09c4a0ed45}
+
+
+ {6250c4d5-ac8e-4c28-93de-0954c5bed1cb}
+
+
+ {400ae4e9-2281-4549-b918-59d1a27a2d07}
+
+
+ {c45194af-7b41-4c28-bc0e-1095ec347664}
+
+
+ {8b3cbb5c-7436-429f-9b72-bae1f4721746}
+
+
+ {bcbadc74-1748-4696-aad7-7fdbe5614624}
+
+
+ {0b1fafc3-817b-4c18-8eb1-121884e3a29b}
+
+
+
+
+ Header Files
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_queue
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Header Files\liblfds700
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_ringbuffer
+
+
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_freelist
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_stack
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_queue
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_hash_addonly
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_list_addonly_ordered_singlylinked
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_btree_addonly_unbalanced
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_misc
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_queue_bounded_singleconsumer_singleproducer
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_list_addonly_singlylinked_unordered
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+ Source Files\lfds700_ringbuffer
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj.user b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj.user
new file mode 100644
index 0000000000..7cbb3216ad
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/visual_studio_professional_2013_and_wdk_8.1/liblfds700.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/dirs b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/dirs
new file mode 100644
index 0000000000..64e002cc57
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/dirs
@@ -0,0 +1,3 @@
+DIRS = single_dir_for_windows_kernel
+
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/driver_entry_renamed_to_avoid_compiler_warning.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/driver_entry_renamed_to_avoid_compiler_warning.c
new file mode 100644
index 0000000000..09d7acb7fc
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/driver_entry_renamed_to_avoid_compiler_warning.c
@@ -0,0 +1,23 @@
+#include "liblfds700_internal.h"
+
+
+
+
+
+/****************************************************************************/
+DRIVER_INITIALIZE DriverEntry;
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+NTSTATUS DriverEntry( struct _DRIVER_OBJECT *DriverObject, PUNICODE_STRING RegistryPath )
+{
+ return( STATUS_SUCCESS );
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/liblfds700.def b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/liblfds700.def
new file mode 100644
index 0000000000..583ce35dbd
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/liblfds700.def
@@ -0,0 +1,69 @@
+EXPORTS
+
+lfds700_btree_au_init_valid_on_current_logical_core = lfds700_btree_au_init_valid_on_current_logical_core
+lfds700_btree_au_cleanup = lfds700_btree_au_cleanup
+lfds700_btree_au_insert = lfds700_btree_au_insert
+lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position = lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position
+lfds700_btree_au_get_by_absolute_position = lfds700_btree_au_get_by_absolute_position
+lfds700_btree_au_get_by_relative_position = lfds700_btree_au_get_by_relative_position
+lfds700_btree_au_get_by_key = lfds700_btree_au_get_by_key
+lfds700_btree_au_query = lfds700_btree_au_query
+
+lfds700_freelist_init_valid_on_current_logical_core = lfds700_freelist_init_valid_on_current_logical_core
+lfds700_freelist_cleanup = lfds700_freelist_cleanup
+lfds700_freelist_push = lfds700_freelist_push
+lfds700_freelist_pop = lfds700_freelist_pop
+lfds700_freelist_query = lfds700_freelist_query
+
+lfds700_hash_a_init_valid_on_current_logical_core = lfds700_hash_a_init_valid_on_current_logical_core
+lfds700_hash_a_cleanup = lfds700_hash_a_cleanup
+lfds700_hash_a_insert = lfds700_hash_a_insert
+lfds700_hash_a_get_by_key = lfds700_hash_a_get_by_key
+lfds700_hash_a_iterate_init = lfds700_hash_a_iterate_init
+lfds700_hash_a_iterate = lfds700_hash_a_iterate
+lfds700_hash_a_query = lfds700_hash_a_query
+
+lfds700_list_aos_init_valid_on_current_logical_core = lfds700_list_aos_init_valid_on_current_logical_core
+lfds700_list_aos_cleanup = lfds700_list_aos_cleanup
+lfds700_list_aos_insert = lfds700_list_aos_insert
+lfds700_list_aos_get_by_key = lfds700_list_aos_get_by_key
+lfds700_list_aos_query = lfds700_list_aos_query
+
+lfds700_list_asu_init_valid_on_current_logical_core = lfds700_list_asu_init_valid_on_current_logical_core
+lfds700_list_asu_cleanup = lfds700_list_asu_cleanup
+lfds700_list_asu_insert_at_position = lfds700_list_asu_insert_at_position
+lfds700_list_asu_insert_at_start = lfds700_list_asu_insert_at_start
+lfds700_list_asu_insert_at_end = lfds700_list_asu_insert_at_end
+lfds700_list_asu_insert_after_element = lfds700_list_asu_insert_after_element
+lfds700_list_asu_get_by_key = lfds700_list_asu_get_by_key
+lfds700_list_asu_query = lfds700_list_asu_query
+
+lfds700_misc_library_init_valid_on_current_logical_core = lfds700_misc_library_init_valid_on_current_logical_core
+lfds700_misc_library_cleanup = lfds700_misc_library_cleanup
+lfds700_misc_prng_init = lfds700_misc_prng_init
+lfds700_misc_query = lfds700_misc_query
+
+lfds700_queue_init_valid_on_current_logical_core = lfds700_queue_init_valid_on_current_logical_core
+lfds700_queue_cleanup = lfds700_queue_cleanup
+lfds700_queue_enqueue = lfds700_queue_enqueue
+lfds700_queue_dequeue = lfds700_queue_dequeue
+lfds700_queue_query = lfds700_queue_query
+
+lfds700_queue_bss_init_valid_on_current_logical_core = lfds700_queue_bss_init_valid_on_current_logical_core
+lfds700_queue_bss_cleanup = lfds700_queue_bss_cleanup
+lfds700_queue_bss_enqueue = lfds700_queue_bss_enqueue
+lfds700_queue_bss_dequeue = lfds700_queue_bss_dequeue
+lfds700_queue_bss_query = lfds700_queue_bss_query
+
+lfds700_ringbuffer_init_valid_on_current_logical_core = lfds700_ringbuffer_init_valid_on_current_logical_core
+lfds700_ringbuffer_cleanup = lfds700_ringbuffer_cleanup
+lfds700_ringbuffer_read = lfds700_ringbuffer_read
+lfds700_ringbuffer_write = lfds700_ringbuffer_write
+lfds700_ringbuffer_query = lfds700_ringbuffer_query
+
+lfds700_stack_init_valid_on_current_logical_core = lfds700_stack_init_valid_on_current_logical_core
+lfds700_stack_cleanup = lfds700_stack_cleanup
+lfds700_stack_push = lfds700_stack_push
+lfds700_stack_pop = lfds700_stack_pop
+lfds700_stack_query = lfds700_stack_query
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/readme_before_win_kernel_build.txt b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/readme_before_win_kernel_build.txt
new file mode 100644
index 0000000000..1481c8d08a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/readme_before_win_kernel_build.txt
@@ -0,0 +1,32 @@
+The Windows kernel build environment is primitive and has a number
+of severe limitations; in particular, all source files must be in
+one directory and it is not possible to choose the output binary type
+(static or dynamic library) from the build command line; rather,
+a string has to be modified in a text file used by the build (!)
+
+To deal with these limitations, it is necessary for a Windows kernel
+build to run a batch file prior to building.
+
+There are two batch files, one for static library builds and the other
+for dynamic library builds.
+
+They are both idempotent; you can run them as often as you like and
+switch between them as often as you want. It's all fine; whenever
+you run one of them, it will take you from whatever state you were
+previously in, into the state you want to be in.
+
+Both batch files copy all the sources file into a single directory,
+"/src/single_dir_for_windows_kernel/".
+
+The static library batch file will then copy "/sources.static" into
+"/src/single_dir_for_windows_kernel/", which will cause a static
+library to be built.
+
+The dynamic library batch file will then copy "/sources.dynamic" into
+"/src/single_dir_for_windows_kernel/", which will cause a dynamic
+library to be built. It will also copy "src/driver_entry.c" into
+"/src/single_dir_for_windows_kernel/", since the linker requires
+the DriverEntry function to exist for dynamic libraries, even
+though it's not used.
+
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/runme_before_win_kernel_dynamic_lib_build.bat b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/runme_before_win_kernel_dynamic_lib_build.bat
new file mode 100644
index 0000000000..ff6fc8a1f3
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/runme_before_win_kernel_dynamic_lib_build.bat
@@ -0,0 +1,22 @@
+@echo off
+rmdir /q /s single_dir_for_windows_kernel 1>nul 2>nul
+mkdir single_dir_for_windows_kernel 1>nul 2>nul
+
+copy /y ..\..\src\lfds700_btree_addonly_unbalanced\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_freelist\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_hash_addonly\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_list_addonly_ordered_singlylinked\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_list_addonly_singlylinked_unordered\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_misc\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_queue\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_ringbuffer\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_stack\* single_dir_for_windows_kernel\ 1>nul 2>nul
+
+copy /y ..\..\src\liblfds700_internal.h single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y driver_entry_renamed_to_avoid_compiler_warning.c single_dir_for_windows_kernel\driver_entry.c 1>nul 2>nul
+copy /y sources.dynamic single_dir_for_windows_kernel\sources 1>nul 2>nul
+
+echo Windows kernel dynamic library build directory structure created.
+echo (Note the effects of this batch file are idempotent).
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/runme_before_win_kernel_static_lib_build.bat b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/runme_before_win_kernel_static_lib_build.bat
new file mode 100644
index 0000000000..81c35e99c8
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/runme_before_win_kernel_static_lib_build.bat
@@ -0,0 +1,21 @@
+@echo off
+rmdir /q /s single_dir_for_windows_kernel 1>nul 2>nul
+mkdir single_dir_for_windows_kernel 1>nul 2>nul
+
+copy /y ..\..\src\lfds700_btree_addonly_unbalanced\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_freelist\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_hash_addonly\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_list_addonly_ordered_singlylinked\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_list_addonly_singlylinked_unordered\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_misc\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_queue\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_ringbuffer\* single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y ..\..\src\lfds700_stack\* single_dir_for_windows_kernel\ 1>nul 2>nul
+
+copy /y ..\..\src\liblfds700_internal.h single_dir_for_windows_kernel\ 1>nul 2>nul
+copy /y sources.static single_dir_for_windows_kernel\sources 1>nul 2>nul
+
+echo Windows kernel static library build directory structure created.
+echo (Note the effects of this batch file are idempotent).
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/sources.dynamic b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/sources.dynamic
new file mode 100644
index 0000000000..b0d241f85f
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/sources.dynamic
@@ -0,0 +1,62 @@
+MSC_WARNING_LEVEL = /WX /wd4127 /W4
+DLLDEF = ../liblfds700.def
+TARGETNAME = liblfds700
+TARGETPATH = ../../../bin/
+TARGETTYPE = EXPORT_DRIVER
+UMTYPE = nt
+USER_C_FLAGS = /D_KERNEL_MODE
+
+INCLUDES = ../../../inc/
+SOURCES = lfds700_hash_addonly_cleanup.c \
+ lfds700_hash_addonly_get.c \
+ lfds700_hash_addonly_init.c \
+ lfds700_hash_addonly_insert.c \
+ lfds700_hash_addonly_iterate.c \
+ lfds700_hash_addonly_query.c \
+ lfds700_list_addonly_ordered_singlylinked_cleanup.c \
+ lfds700_list_addonly_ordered_singlylinked_get.c \
+ lfds700_list_addonly_ordered_singlylinked_init.c \
+ lfds700_list_addonly_ordered_singlylinked_insert.c \
+ lfds700_list_addonly_ordered_singlylinked_query.c \
+ lfds700_list_addonly_singlylinked_unordered_cleanup.c \
+ lfds700_list_addonly_singlylinked_unordered_get.c \
+ lfds700_list_addonly_singlylinked_unordered_init.c \
+ lfds700_list_addonly_singlylinked_unordered_insert.c \
+ lfds700_list_addonly_singlylinked_unordered_query.c \
+ lfds700_btree_addonly_unbalanced_cleanup.c \
+ lfds700_btree_addonly_unbalanced_get.c \
+ lfds700_btree_addonly_unbalanced_init.c \
+ lfds700_btree_addonly_unbalanced_insert.c \
+ lfds700_btree_addonly_unbalanced_query.c \
+ lfds700_freelist_cleanup.c \
+ lfds700_freelist_init.c \
+ lfds700_freelist_pop.c \
+ lfds700_freelist_push.c \
+ lfds700_freelist_query.c \
+ lfds700_misc_cleanup.c \
+ lfds700_misc_globals.c \
+ lfds700_misc_init.c \
+ lfds700_misc_prng.c \
+ lfds700_misc_query.c \
+ lfds700_queue_cleanup.c \
+ lfds700_queue_dequeue.c \
+ lfds700_queue_enqueue.c \
+ lfds700_queue_init.c \
+ lfds700_queue_query.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_init.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_query.c \
+ lfds700_ringbuffer_cleanup.c \
+ lfds700_ringbuffer_init.c \
+ lfds700_ringbuffer_query.c \
+ lfds700_ringbuffer_read.c \
+ lfds700_ringbuffer_write.c \
+ lfds700_stack_cleanup.c \
+ lfds700_stack_init.c \
+ lfds700_stack_pop.c \
+ lfds700_stack_push.c \
+ lfds700_stack_query.c \
+ driver_entry.c
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/sources.static b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/sources.static
new file mode 100644
index 0000000000..401b381c7d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/build/wdk_7.1/sources.static
@@ -0,0 +1,60 @@
+MSC_WARNING_LEVEL = /WX /wd4127 /W4
+TARGETNAME = liblfds700
+TARGETPATH = ../../../bin/
+TARGETTYPE = DRIVER_LIBRARY
+UMTYPE = nt
+USER_C_FLAGS = /D_KERNEL_MODE
+
+INCLUDES = ../../../inc/
+SOURCES = lfds700_hash_addonly_cleanup.c \
+ lfds700_hash_addonly_get.c \
+ lfds700_hash_addonly_init.c \
+ lfds700_hash_addonly_insert.c \
+ lfds700_hash_addonly_iterate.c \
+ lfds700_hash_addonly_query.c \
+ lfds700_list_addonly_ordered_singlylinked_cleanup.c \
+ lfds700_list_addonly_ordered_singlylinked_get.c \
+ lfds700_list_addonly_ordered_singlylinked_init.c \
+ lfds700_list_addonly_ordered_singlylinked_insert.c \
+ lfds700_list_addonly_ordered_singlylinked_query.c \
+ lfds700_list_addonly_singlylinked_unordered_cleanup.c \
+ lfds700_list_addonly_singlylinked_unordered_get.c \
+ lfds700_list_addonly_singlylinked_unordered_init.c \
+ lfds700_list_addonly_singlylinked_unordered_insert.c \
+ lfds700_list_addonly_singlylinked_unordered_query.c \
+ lfds700_btree_addonly_unbalanced_cleanup.c \
+ lfds700_btree_addonly_unbalanced_get.c \
+ lfds700_btree_addonly_unbalanced_init.c \
+ lfds700_btree_addonly_unbalanced_insert.c \
+ lfds700_btree_addonly_unbalanced_query.c \
+ lfds700_freelist_cleanup.c \
+ lfds700_freelist_init.c \
+ lfds700_freelist_pop.c \
+ lfds700_freelist_push.c \
+ lfds700_freelist_query.c \
+ lfds700_misc_cleanup.c \
+ lfds700_misc_globals.c \
+ lfds700_misc_init.c \
+ lfds700_misc_prng.c \
+ lfds700_misc_query.c \
+ lfds700_queue_cleanup.c \
+ lfds700_queue_dequeue.c \
+ lfds700_queue_enqueue.c \
+ lfds700_queue_init.c \
+ lfds700_queue_query.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_init.c \
+ lfds700_queue_bounded_singleconsumer_singleproducer_query.c \
+ lfds700_ringbuffer_cleanup.c \
+ lfds700_ringbuffer_init.c \
+ lfds700_ringbuffer_query.c \
+ lfds700_ringbuffer_read.c \
+ lfds700_ringbuffer_write.c \
+ lfds700_stack_cleanup.c \
+ lfds700_stack_init.c \
+ lfds700_stack_pop.c \
+ lfds700_stack_push.c \
+ lfds700_stack_query.c
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700.h
new file mode 100644
index 0000000000..fdda50cefb
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700.h
@@ -0,0 +1,31 @@
+#ifndef LIBLFDS700_H
+
+ /***** defines *****/
+ #define LIBLFDS700_H
+
+ /***** pragmas on *****/
+ #pragma warning( disable : 4324 ) // TRD : 4324 disables MSVC warnings for structure alignment padding due to alignment specifiers
+
+ #pragma prefast( disable : 28113 28182 28183, "blah" )
+
+ /***** includes *****/
+ #include "liblfds700/lfds700_porting_abstraction_layer_compiler.h"
+ #include "liblfds700/lfds700_porting_abstraction_layer_operating_system.h"
+ #include "liblfds700/lfds700_porting_abstraction_layer_processor.h"
+
+ #include "liblfds700/lfds700_misc.h" // TRD : everything after depends on misc
+ #include "liblfds700/lfds700_btree_addonly_unbalanced.h" // TRD : hash_addonly depends on btree_addonly_unbalanced
+ #include "liblfds700/lfds700_freelist.h"
+ #include "liblfds700/lfds700_hash_addonly.h"
+ #include "liblfds700/lfds700_list_addonly_ordered_singlylinked.h"
+ #include "liblfds700/lfds700_list_addonly_singlylinked_unordered.h"
+ #include "liblfds700/lfds700_queue.h"
+ #include "liblfds700/lfds700_queue_bounded_singleconsumer_singleproducer.h"
+ #include "liblfds700/lfds700_ringbuffer.h"
+ #include "liblfds700/lfds700_stack.h"
+
+ /***** pragmas off *****/
+ #pragma warning( default : 4324 )
+
+#endif
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_btree_addonly_unbalanced.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_btree_addonly_unbalanced.h
new file mode 100644
index 0000000000..bdc63a4273
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_btree_addonly_unbalanced.h
@@ -0,0 +1,113 @@
+/***** defines *****/
+#define LFDS700_BTREE_AU_GET_KEY_FROM_ELEMENT( btree_au_element ) ( (btree_au_element).key )
+#define LFDS700_BTREE_AU_SET_KEY_IN_ELEMENT( btree_au_element, new_key ) ( (btree_au_element).key = (void *) (lfds700_pal_uint_t) (new_key) )
+#define LFDS700_BTREE_AU_GET_VALUE_FROM_ELEMENT( btree_au_element ) ( LFDS700_MISC_BARRIER_LOAD, (btree_au_element).value )
+#define LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( btree_au_element, new_value ) { void *local_new_value = (void *) (lfds700_pal_uint_t) (new_value); LFDS700_PAL_ATOMIC_EXCHANGE( &(btree_au_element).value, &local_new_value ); }
+#define LFDS700_BTREE_AU_GET_USER_STATE_FROM_STATE( btree_au_state ) ( (btree_au_state).user_state )
+
+/***** enums *****/
+enum lfds700_btree_au_absolute_position
+{
+ LFDS700_BTREE_AU_ABSOLUTE_POSITION_ROOT,
+ LFDS700_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE,
+ LFDS700_BTREE_AU_ABSOLUTE_POSITION_LARGEST_IN_TREE
+};
+
+enum lfds700_btree_au_existing_key
+{
+ LFDS700_BTREE_AU_EXISTING_KEY_OVERWRITE,
+ LFDS700_BTREE_AU_EXISTING_KEY_FAIL
+};
+
+enum lfds700_btree_au_insert_result
+{
+ LFDS700_BTREE_AU_INSERT_RESULT_FAILURE_EXISTING_KEY,
+ LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS_OVERWRITE,
+ LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS
+};
+
+enum lfds700_btree_au_relative_position
+{
+ LFDS700_BTREE_AU_RELATIVE_POSITION_UP,
+ LFDS700_BTREE_AU_RELATIVE_POSITION_LEFT,
+ LFDS700_BTREE_AU_RELATIVE_POSITION_RIGHT,
+ LFDS700_BTREE_AU_RELATIVE_POSITION_SMALLEST_ELEMENT_BELOW_CURRENT_ELEMENT,
+ LFDS700_BTREE_AU_RELATIVE_POSITION_LARGEST_ELEMENT_BELOW_CURRENT_ELEMENT,
+ LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE,
+ LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE
+};
+
+enum lfds700_btree_au_query
+{
+ LFDS700_BTREE_AU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT,
+ LFDS700_BTREE_AU_QUERY_SINGLETHREADED_VALIDATE
+};
+
+/***** structs *****/
+struct lfds700_btree_au_element
+{
+ struct lfds700_btree_au_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile left,
+ *volatile right,
+ *volatile up;
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile value;
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *key;
+};
+
+struct lfds700_btree_au_state
+{
+ struct lfds700_btree_au_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile root;
+
+ int LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ (*key_compare_function)( void const *new_key, void const *existing_key );
+
+ enum lfds700_btree_au_existing_key
+ existing_key;
+
+ void
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_btree_au_init_valid_on_current_logical_core( struct lfds700_btree_au_state *baus,
+ int (*key_compare_function)(void const *new_key, void const *existing_key),
+ enum lfds700_btree_au_existing_key existing_key,
+ void *user_state );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_btree_au_cleanup( struct lfds700_btree_au_state *baus,
+ void (*element_cleanup_callback)(struct lfds700_btree_au_state *baus, struct lfds700_btree_au_element *baue) );
+
+enum lfds700_btree_au_insert_result lfds700_btree_au_insert( struct lfds700_btree_au_state *baus,
+ struct lfds700_btree_au_element *baue,
+ struct lfds700_btree_au_element **existing_baue,
+ struct lfds700_misc_prng_state *ps );
+ // TRD : if a link collides with an existing key and existing_baue is non-NULL, existing_baue is set to the existing element
+
+int lfds700_btree_au_get_by_key( struct lfds700_btree_au_state *baus,
+ void *key,
+ struct lfds700_btree_au_element **baue );
+
+int lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position( struct lfds700_btree_au_state *baus,
+ struct lfds700_btree_au_element **baue,
+ enum lfds700_btree_au_absolute_position absolute_position,
+ enum lfds700_btree_au_relative_position relative_position );
+ // TRD : if *baue is NULL, we get the element at position, otherwise we move from *baue according to direction
+
+int lfds700_btree_au_get_by_absolute_position( struct lfds700_btree_au_state *baus,
+ struct lfds700_btree_au_element **baue,
+ enum lfds700_btree_au_absolute_position absolute_position );
+
+int lfds700_btree_au_get_by_relative_position( struct lfds700_btree_au_element **baue,
+ enum lfds700_btree_au_relative_position relative_position );
+
+void lfds700_btree_au_query( struct lfds700_btree_au_state *baus,
+ enum lfds700_btree_au_query query_type,
+ void *query_input,
+ void *query_output );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_freelist.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_freelist.h
new file mode 100644
index 0000000000..6a89386c5d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_freelist.h
@@ -0,0 +1,54 @@
+/***** defines *****/
+#define LFDS700_FREELIST_GET_KEY_FROM_ELEMENT( freelist_element ) ( (freelist_element).key )
+#define LFDS700_FREELIST_SET_KEY_IN_ELEMENT( freelist_element, new_key ) ( (freelist_element).key = (void *) (lfds700_pal_uint_t) (new_key) )
+#define LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( freelist_element ) ( (freelist_element).value )
+#define LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( freelist_element, new_value ) ( (freelist_element).value = (void *) (lfds700_pal_uint_t) (new_value) )
+#define LFDS700_FREELIST_GET_USER_STATE_FROM_STATE( freelist_state ) ( (freelist_state).user_state )
+
+/***** enums *****/
+enum lfds700_freelist_query
+{
+ LFDS700_FREELIST_QUERY_SINGLETHREADED_GET_COUNT,
+ LFDS700_FREELIST_QUERY_SINGLETHREADED_VALIDATE
+};
+
+/***** structures *****/
+struct lfds700_freelist_element
+{
+ struct lfds700_freelist_element
+ *volatile next;
+
+ void
+ *key,
+ *value;
+};
+
+struct lfds700_freelist_state
+{
+ struct lfds700_freelist_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile top[PAC_SIZE];
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_freelist_init_valid_on_current_logical_core( struct lfds700_freelist_state *fs, void *user_state );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_freelist_cleanup( struct lfds700_freelist_state *fs,
+ void (*element_cleanup_callback)(struct lfds700_freelist_state *fs, struct lfds700_freelist_element *fe) );
+
+void lfds700_freelist_push( struct lfds700_freelist_state *fs,
+ struct lfds700_freelist_element *fe,
+ struct lfds700_misc_prng_state *ps );
+
+int lfds700_freelist_pop( struct lfds700_freelist_state *fs,
+ struct lfds700_freelist_element **fe,
+ struct lfds700_misc_prng_state *ps );
+
+void lfds700_freelist_query( struct lfds700_freelist_state *fs,
+ enum lfds700_freelist_query query_type,
+ void *query_input,
+ void *query_output );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_hash_addonly.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_hash_addonly.h
new file mode 100644
index 0000000000..f7962db9e0
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_hash_addonly.h
@@ -0,0 +1,127 @@
+/***** defines *****/
+#define LFDS700_HASH_A_GET_KEY_FROM_ELEMENT( hash_a_element ) ( (hash_a_element).key )
+#define LFDS700_HASH_A_SET_KEY_IN_ELEMENT( hash_a_element, new_key ) ( (hash_a_element).key = (void *) (lfds700_pal_uint_t) (new_key) )
+#define LFDS700_HASH_A_GET_VALUE_FROM_ELEMENT( hash_a_element ) ( LFDS700_MISC_BARRIER_LOAD, (hash_a_element).value )
+#define LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( hash_a_element, new_value ) { void *local_new_value = (void *) (lfds700_pal_uint_t) (new_value); LFDS700_PAL_ATOMIC_EXCHANGE( &(hash_a_element).value, &local_new_value ); }
+#define LFDS700_HASH_A_GET_USER_STATE_FROM_STATE( hash_a_state ) ( (hash_a_state).user_state )
+
+#define LFDS700_HASH_A_32BIT_HASH_FUNCTION( data, data_length_in_bytes, hash ) { \
+ lfds700_pal_uint_t \
+ loop; \
+ \
+ for( loop = 0 ; loop < (data_length_in_bytes) ; loop++ ) \
+ { \
+ (hash) += *( (char unsigned *) (data) + loop ); \
+ (hash) += ((hash) << 10); \
+ (hash) ^= ((hash) >> 6); \
+ } \
+ \
+ (hash) += ((hash) << 3); \
+ (hash) ^= ((hash) >> 11); \
+ (hash) += ((hash) << 15); \
+ }
+ /* TRD : this is the Jenkins one-at-a-time hash
+ it produces a 32 bit hash
+ http://en.wikipedia.org/wiki/Jenkins_hash_function
+
+ we ourselves do *not* initialize the value of *hash, so that
+ our caller has the option to call us multiple times, each
+ time with for example a different member of a struct, which is
+ then hashed into the existing, built-up-so-far hash value, and
+ so build up a quality hash
+ */
+
+/***** enums *****/
+enum lfds700_hash_a_existing_key
+{
+ LFDS700_HASH_A_EXISTING_KEY_OVERWRITE,
+ LFDS700_HASH_A_EXISTING_KEY_FAIL
+};
+
+enum lfds700_hash_a_insert_result
+{
+ LFDS700_HASH_A_PUT_RESULT_FAILURE_EXISTING_KEY,
+ LFDS700_HASH_A_PUT_RESULT_SUCCESS_OVERWRITE,
+ LFDS700_HASH_A_PUT_RESULT_SUCCESS
+};
+
+enum lfds700_hash_a_query
+{
+ LFDS700_HASH_A_QUERY_GET_POTENTIALLY_INACCURATE_COUNT,
+ LFDS700_HASH_A_QUERY_SINGLETHREADED_VALIDATE
+};
+
+/***** structs *****/
+struct lfds700_hash_a_element
+{
+ struct lfds700_btree_au_element
+ baue;
+
+ void
+ *key;
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile value;
+};
+
+struct lfds700_hash_a_iterate
+{
+ struct lfds700_btree_au_element
+ *baue;
+
+ struct lfds700_btree_au_state
+ *baus,
+ *baus_end;
+};
+
+struct lfds700_hash_a_state
+{
+ enum lfds700_hash_a_existing_key
+ existing_key;
+
+ int
+ (*key_compare_function)( void const *new_key, void const *existing_key );
+
+ lfds700_pal_uint_t
+ array_size;
+
+ struct lfds700_btree_au_state
+ *baus_array;
+
+ void
+ (*element_cleanup_callback)( struct lfds700_hash_a_state *has, struct lfds700_hash_a_element *hae ),
+ (*key_hash_function)( void const *key, lfds700_pal_uint_t *hash ),
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_hash_a_init_valid_on_current_logical_core( struct lfds700_hash_a_state *has,
+ struct lfds700_btree_au_state *baus_array,
+ lfds700_pal_uint_t array_size,
+ int (*key_compare_function)(void const *new_key, void const *existing_key),
+ void (*key_hash_function)(void const *key, lfds700_pal_uint_t *hash),
+ enum lfds700_hash_a_existing_key existing_key,
+ void *user_state );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_hash_a_cleanup( struct lfds700_hash_a_state *has,
+ void (*element_cleanup_function)(struct lfds700_hash_a_state *has, struct lfds700_hash_a_element *hae) );
+
+enum lfds700_hash_a_insert_result lfds700_hash_a_insert( struct lfds700_hash_a_state *has,
+ struct lfds700_hash_a_element *hae,
+ struct lfds700_hash_a_element **existing_hae,
+ struct lfds700_misc_prng_state *ps );
+ // TRD : if existing_value is not NULL and the key exists, existing_value is set to the value of the existing key
+
+int lfds700_hash_a_get_by_key( struct lfds700_hash_a_state *has,
+ void *key,
+ struct lfds700_hash_a_element **hae );
+
+void lfds700_hash_a_iterate_init( struct lfds700_hash_a_state *has, struct lfds700_hash_a_iterate *hai );
+int lfds700_hash_a_iterate( struct lfds700_hash_a_iterate *hai, struct lfds700_hash_a_element **hae );
+
+void lfds700_hash_a_query( struct lfds700_hash_a_state *has,
+ enum lfds700_hash_a_query query_type,
+ void *query_input,
+ void *query_output );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_list_addonly_ordered_singlylinked.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_list_addonly_ordered_singlylinked.h
new file mode 100644
index 0000000000..dffab0aa6b
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_list_addonly_ordered_singlylinked.h
@@ -0,0 +1,85 @@
+/***** defines *****/
+#define LFDS700_LIST_AOS_GET_START( list_aos_state ) ( LFDS700_MISC_BARRIER_LOAD, (list_aos_state).start->next )
+#define LFDS700_LIST_AOS_GET_NEXT( list_aos_element ) ( LFDS700_MISC_BARRIER_LOAD, (list_aos_element).next )
+#define LFDS700_LIST_AOS_GET_START_AND_THEN_NEXT( list_aos_state, pointer_to_list_aos_element ) ( (pointer_to_list_aos_element) == NULL ? ( (pointer_to_list_aos_element) = LFDS700_LIST_AOS_GET_START(list_aos_state) ) : ( (pointer_to_list_aos_element) = LFDS700_LIST_AOS_GET_NEXT(*(pointer_to_list_aos_element)) ) )
+#define LFDS700_LIST_AOS_GET_KEY_FROM_ELEMENT( list_aos_element ) ( (list_aos_element).key )
+#define LFDS700_LIST_AOS_SET_KEY_IN_ELEMENT( list_aos_element, new_key ) ( (list_aos_element).key = (void *) (lfds700_pal_uint_t) (new_key) )
+#define LFDS700_LIST_AOS_GET_VALUE_FROM_ELEMENT( list_aos_element ) ( LFDS700_MISC_BARRIER_LOAD, (list_aos_element).value )
+#define LFDS700_LIST_AOS_SET_VALUE_IN_ELEMENT( list_aos_element, new_value ) { void *local_new_value = (void *) (lfds700_pal_uint_t) (new_value); LFDS700_PAL_ATOMIC_EXCHANGE( &(list_aos_element).value, &local_new_value ); }
+#define LFDS700_LIST_AOS_GET_USER_STATE_FROM_STATE( list_aos_state ) ( (list_aos_state).user_state )
+
+/***** enums *****/
+enum lfds700_list_aos_existing_key
+{
+ LFDS700_LIST_AOS_EXISTING_KEY_OVERWRITE,
+ LFDS700_LIST_AOS_EXISTING_KEY_FAIL
+};
+
+enum lfds700_list_aos_insert_result
+{
+ LFDS700_LIST_AOS_INSERT_RESULT_FAILURE_EXISTING_KEY,
+ LFDS700_LIST_AOS_INSERT_RESULT_SUCCESS_OVERWRITE,
+ LFDS700_LIST_AOS_INSERT_RESULT_SUCCESS
+};
+
+enum lfds700_list_aos_query
+{
+ LFDS700_LIST_AOS_QUERY_GET_POTENTIALLY_INACCURATE_COUNT,
+ LFDS700_LIST_AOS_QUERY_SINGLETHREADED_VALIDATE
+};
+
+/***** structures *****/
+struct lfds700_list_aos_element
+{
+ struct lfds700_list_aos_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile next;
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile value;
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *key;
+};
+
+struct lfds700_list_aos_state
+{
+ struct lfds700_list_aos_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile start;
+
+ struct lfds700_list_aos_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ dummy_element;
+
+ int LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ (*key_compare_function)( void const *new_key, void const *existing_key );
+
+ enum lfds700_list_aos_existing_key
+ existing_key;
+
+ void
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_list_aos_init_valid_on_current_logical_core( struct lfds700_list_aos_state *laoss,
+ int (*key_compare_function)(void const *new_key, void const *existing_key),
+ enum lfds700_list_aos_existing_key existing_key,
+ void *user_state );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_list_aos_cleanup( struct lfds700_list_aos_state *laoss,
+ void (*element_cleanup_callback)(struct lfds700_list_aos_state *laoss, struct lfds700_list_aos_element *laose) );
+
+enum lfds700_list_aos_insert_result lfds700_list_aos_insert( struct lfds700_list_aos_state *laoss,
+ struct lfds700_list_aos_element *laose,
+ struct lfds700_list_aos_element **existing_laose,
+ struct lfds700_misc_prng_state *ps );
+
+int lfds700_list_aos_get_by_key( struct lfds700_list_aos_state *laoss,
+ void *key,
+ struct lfds700_list_aos_element **laose );
+
+void lfds700_list_aos_query( struct lfds700_list_aos_state *laoss,
+ enum lfds700_list_aos_query query_type,
+ void *query_input,
+ void *query_output );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_list_addonly_singlylinked_unordered.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_list_addonly_singlylinked_unordered.h
new file mode 100644
index 0000000000..38d21511a1
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_list_addonly_singlylinked_unordered.h
@@ -0,0 +1,90 @@
+/***** defines *****/
+#define LFDS700_LIST_ASU_GET_START( list_asu_state ) ( LFDS700_MISC_BARRIER_LOAD, (list_asu_state).start->next )
+#define LFDS700_LIST_ASU_GET_NEXT( list_asu_element ) ( LFDS700_MISC_BARRIER_LOAD, (list_asu_element).next )
+#define LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT( list_asu_state, pointer_to_list_asu_element ) ( (pointer_to_list_asu_element) == NULL ? ( (pointer_to_list_asu_element) = LFDS700_LIST_ASU_GET_START(list_asu_state) ) : ( (pointer_to_list_asu_element) = LFDS700_LIST_ASU_GET_NEXT(*(pointer_to_list_asu_element)) ) )
+#define LFDS700_LIST_ASU_GET_KEY_FROM_ELEMENT( list_asu_element ) ( (list_asu_element).key )
+#define LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( list_asu_element, new_key ) ( (list_asu_element).key = (void *) (lfds700_pal_uint_t) (new_key) )
+#define LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( list_asu_element ) ( LFDS700_MISC_BARRIER_LOAD, (list_asu_element).value )
+#define LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( list_asu_element, new_value ) { void *local_new_value = (void *) (lfds700_pal_uint_t) (new_value); LFDS700_PAL_ATOMIC_EXCHANGE( &(list_asu_element).value, &local_new_value ); }
+#define LFDS700_LIST_ASU_GET_USER_STATE_FROM_STATE( list_asu_state ) ( (list_asu_state).user_state )
+
+/***** enums *****/
+enum lfds700_list_asu_position
+{
+ LFDS700_LIST_ASU_POSITION_START,
+ LFDS700_LIST_ASU_POSITION_END,
+ LFDS700_LIST_ASU_POSITION_AFTER
+};
+
+enum lfds700_list_asu_query
+{
+ LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT,
+ LFDS700_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE
+};
+
+/***** structures *****/
+struct lfds700_list_asu_element
+{
+ struct lfds700_list_asu_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile next;
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile value;
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *key;
+};
+
+struct lfds700_list_asu_state
+{
+ struct lfds700_list_asu_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile end,
+ *volatile start;
+
+ struct lfds700_list_asu_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ dummy_element;
+
+ int LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ (*key_compare_function)( void const *new_key, void const *existing_key );
+
+ void
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_list_asu_init_valid_on_current_logical_core( struct lfds700_list_asu_state *lasus,
+ int (*key_compare_function)(void const *new_key, void const *existing_key),
+ void *user_state );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_list_asu_cleanup( struct lfds700_list_asu_state *lasus,
+ void (*element_cleanup_callback)(struct lfds700_list_asu_state *lasus, struct lfds700_list_asu_element *lasue) );
+
+void lfds700_list_asu_insert_at_position( struct lfds700_list_asu_state *lasus,
+ struct lfds700_list_asu_element *lasue,
+ struct lfds700_list_asu_element *lasue_predecessor,
+ enum lfds700_list_asu_position position,
+ struct lfds700_misc_prng_state *ps );
+
+void lfds700_list_asu_insert_at_start( struct lfds700_list_asu_state *lasus,
+ struct lfds700_list_asu_element *lasue,
+ struct lfds700_misc_prng_state *ps );
+
+void lfds700_list_asu_insert_at_end( struct lfds700_list_asu_state *lasus,
+ struct lfds700_list_asu_element *lasue,
+ struct lfds700_misc_prng_state *ps );
+
+void lfds700_list_asu_insert_after_element( struct lfds700_list_asu_state *lasus,
+ struct lfds700_list_asu_element *lasue,
+ struct lfds700_list_asu_element *lasue_predecessor,
+ struct lfds700_misc_prng_state *ps );
+
+int lfds700_list_asu_get_by_key( struct lfds700_list_asu_state *lasus,
+ void *key,
+ struct lfds700_list_asu_element **lasue );
+
+void lfds700_list_asu_query( struct lfds700_list_asu_state *lasus,
+ enum lfds700_list_asu_query query_type,
+ void *query_input,
+ void *query_output );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_misc.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_misc.h
new file mode 100644
index 0000000000..014f72dac5
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_misc.h
@@ -0,0 +1,192 @@
+/***** defines *****/
+#define LFDS700_MISC_VERSION_STRING "7.0.0"
+#define LFDS700_MISC_VERSION_INTEGER 700
+
+#ifndef NULL
+ #define NULL ( (void *) 0 )
+#endif
+
+#define POINTER 0
+#define COUNTER 1
+#define PAC_SIZE 2
+
+#define LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE 0
+#define LFDS700_MISC_PRNG_MAX ( (lfds700_pal_uint_t) -1 )
+#define LFDS700_MISC_DELIBERATELY_CRASH { char *c = 0; *c = 0; }
+#define LFDS700_MISC_PRNG_SEED 0x0a34655d34c092feULL
+ /* TRD : from an on-line hardware RNG, using atmospheric noise
+ the URL eblow will generate another 16 random hex digits (e.g. a 64-bit number) and is
+ the RNG used to generate the number above (0x0a34655d34c092fe)
+ http://www.random.org/integers/?num=16&min=0&max=15&col=1&base=16&format=plain&rnd=new
+
+ this seed is a fixed seed which is used for the slow, high quality PRNG,
+ which in turn is used when thread start to generate a single high quality seed
+ for the fast, low quality PRNG used for the CAS exponential backoff
+ */
+
+#if( LFDS700_PAL_ALIGN_SINGLE_POINTER == 4 ) // TRD : any 32-bit platform
+ // TRD : PRNG is a 32-bit xorshift, numbers suggested by George Marsaglia, in his paper http://www.jstatsoft.org/v08/i14/paper
+ #define LFDS700_MISC_PRNG_GENERATE( pointer_to_lfds700_misc_prng_state ) ( (pointer_to_lfds700_misc_prng_state)->prng_state ^= (pointer_to_lfds700_misc_prng_state)->prng_state >> 13, (pointer_to_lfds700_misc_prng_state)->prng_state ^= (pointer_to_lfds700_misc_prng_state)->prng_state << 17, (pointer_to_lfds700_misc_prng_state)->prng_state ^= (pointer_to_lfds700_misc_prng_state)->prng_state >> 5 )
+#endif
+
+#if( LFDS700_PAL_ALIGN_SINGLE_POINTER == 8 ) // TRD : any 64-bit platform
+ // TRD : PRNG is 64-bit xorshift (xorshift64*), from Sebastiano Vigna (vigna at acm dot org), http://creativecommons.org/publicdomain/zero/1.0/
+ #define LFDS700_MISC_PRNG_GENERATE( pointer_to_lfds700_misc_prng_state ) ( (pointer_to_lfds700_misc_prng_state)->prng_state ^= (pointer_to_lfds700_misc_prng_state)->prng_state >> 12, (pointer_to_lfds700_misc_prng_state)->prng_state ^= (pointer_to_lfds700_misc_prng_state)->prng_state << 25, (pointer_to_lfds700_misc_prng_state)->prng_state ^= (pointer_to_lfds700_misc_prng_state)->prng_state >> 27, (pointer_to_lfds700_misc_prng_state)->prng_state *= 2685821657736338717LL )
+#endif
+
+#if( !defined LFDS700_PAL_ATOMIC_CAS )
+ #define LFDS700_PAL_NO_ATOMIC_CAS
+
+ // TRD : lfds700_pal_atom_t volatile *destination, lfds700_pal_atom_t *compare, lfds700_pal_atom_t new_destination, enum lfds700_misc_cas_strength cas_strength, char unsigned result
+
+ #define LFDS700_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result ) \
+ { \
+ LFDS700_PAL_ASSERT( !"LFDS700_PAL_ATOMIC_CAS not implemented for this platform." ); \
+ LFDS700_MISC_DELIBERATELY_CRASH; \
+ (result) = (char unsigned) 1; \
+ }
+#endif
+
+#if( !defined LFDS700_PAL_ATOMIC_DWCAS )
+ #define LFDS700_PAL_NO_ATOMIC_DWCAS
+
+ // TRD : lfds700_pal_atom_t volatile (*destination)[2], lfds700_pal_atom_t (*compare)[2], lfds700_pal_atom_t (*new_destination)[2], enum lfds700_misc_cas_strength cas_strength, unsigned char result
+
+ #define LFDS700_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result ) \
+ { \
+ LFDS700_PAL_ASSERT( !"LFDS700_PAL_ATOMIC_DWCAS not implemented for this platform." ); \
+ LFDS700_MISC_DELIBERATELY_CRASH; \
+ (result) = (char unsigned) 1; \
+ }
+#endif
+
+#if( !defined LFDS700_PAL_ATOMIC_EXCHANGE )
+ #define LFDS700_PAL_NO_ATOMIC_EXCHANGE
+ // TRD : lfds700_pal_atom_t volatile *destination, lfds700_pal_atom_t *exchange
+ #define LFDS700_PAL_ATOMIC_EXCHANGE( pointer_to_destination, pointer_to_exchange ) \
+ { \
+ LFDS700_PAL_ASSERT( !"LFDS700_PAL_ATOMIC_EXCHANGE not implemented for this platform." ); \
+ LFDS700_MISC_DELIBERATELY_CRASH; \
+ }
+#endif
+
+#if( defined LFDS700_PAL_NO_COMPILER_BARRIERS )
+ #define LFDS700_MISC_BARRIER_LOAD ( LFDS700_PAL_BARRIER_PROCESSOR_LOAD )
+ #define LFDS700_MISC_BARRIER_STORE ( LFDS700_PAL_BARRIER_PROCESSOR_STORE )
+ #define LFDS700_MISC_BARRIER_FULL ( LFDS700_PAL_BARRIER_PROCESSOR_FULL )
+#else
+ #define LFDS700_MISC_BARRIER_LOAD ( LFDS700_PAL_BARRIER_COMPILER_LOAD, LFDS700_PAL_BARRIER_PROCESSOR_LOAD, LFDS700_PAL_BARRIER_COMPILER_LOAD )
+ #define LFDS700_MISC_BARRIER_STORE ( LFDS700_PAL_BARRIER_COMPILER_STORE, LFDS700_PAL_BARRIER_PROCESSOR_STORE, LFDS700_PAL_BARRIER_COMPILER_STORE )
+ #define LFDS700_MISC_BARRIER_FULL ( LFDS700_PAL_BARRIER_COMPILER_FULL, LFDS700_PAL_BARRIER_PROCESSOR_FULL, LFDS700_PAL_BARRIER_COMPILER_FULL )
+#endif
+
+#define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE LFDS700_MISC_BARRIER_LOAD
+
+#if( defined LFDS700_PAL_NO_ATOMIC_CAS )
+ #define LFDS700_MISC_ATOMIC_SUPPORT_CAS 0
+#else
+ #define LFDS700_MISC_ATOMIC_SUPPORT_CAS 1
+#endif
+
+#if( defined LFDS700_PAL_NO_ATOMIC_DWCAS )
+ #define LFDS700_MISC_ATOMIC_SUPPORT_DWCAS 0
+#else
+ #define LFDS700_MISC_ATOMIC_SUPPORT_DWCAS 1
+#endif
+
+#if( defined LFDS700_PAL_NO_ATOMIC_EXCHANGE )
+ #define LFDS700_MISC_ATOMIC_SUPPORT_EXCHANGE 0
+#else
+ #define LFDS700_MISC_ATOMIC_SUPPORT_EXCHANGE 1
+#endif
+
+/***** enums *****/
+enum lfds700_misc_cas_strength
+{
+ // TRD : yes, weak is 1 (one) - blame GCC!
+ LFDS700_MISC_CAS_STRENGTH_WEAK = 1,
+ LFDS700_MISC_CAS_STRENGTH_STRONG = 0
+};
+
+enum lfds700_misc_validity
+{
+ LFDS700_MISC_VALIDITY_VALID,
+ LFDS700_MISC_VALIDITY_INVALID_LOOP,
+ LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS,
+ LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS,
+ LFDS700_MISC_VALIDITY_INVALID_TEST_DATA,
+ LFDS700_MISC_VALIDITY_INVALID_ORDER
+};
+
+enum lfds700_misc_flag
+{
+ LFDS700_MISC_FLAG_LOWERED,
+ LFDS700_MISC_FLAG_RAISED
+};
+
+enum lfds700_misc_query
+{
+ LFDS700_MISC_QUERY_GET_EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_LOOP_ITERATIONS_FOR_CAS,
+ LFDS700_MISC_QUERY_SET_EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_LOOP_ITERATIONS_FOR_CAS,
+ LFDS700_MISC_QUERY_GET_EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_LOOP_ITERATIONS_FOR_DWCAS,
+ LFDS700_MISC_QUERY_SET_EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_LOOP_ITERATIONS_FOR_DWCAS,
+ LFDS700_MISC_QUERY_GET_BUILD_AND_VERSION_STRING
+};
+
+/***** struct *****/
+struct lfds700_misc_globals
+{
+ lfds700_pal_atom_t
+ exponential_backoff_timeslot_length_in_loop_iterations_for_cas,
+ exponential_backoff_timeslot_length_in_loop_iterations_for_dwcas;
+};
+
+struct lfds700_misc_prng_state
+{
+ lfds700_pal_uint_t
+ prng_state;
+
+ // TRD : here to be on the same cache-line as prng_state, and so all are obtained from one cache-line read
+ lfds700_pal_atom_t
+ local_copy_of_global_exponential_backoff_timeslot_length_in_loop_iterations_for_cas,
+ local_copy_of_global_exponential_backoff_timeslot_length_in_loop_iterations_for_dwcas;
+};
+
+struct lfds700_misc_validation_info
+{
+ lfds700_pal_uint_t
+ min_elements,
+ max_elements;
+};
+
+/***** externs *****/
+extern struct lfds700_misc_globals
+ lfds700_misc_globals;
+
+/***** public prototypes *****/
+void lfds700_misc_library_init_valid_on_current_logical_core( void );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+void lfds700_misc_library_cleanup( void );
+
+static LFDS700_PAL_INLINE void lfds700_misc_force_store( void );
+
+void lfds700_misc_prng_init( struct lfds700_misc_prng_state *ps );
+
+void lfds700_misc_query( enum lfds700_misc_query query_type, void *query_input, void *query_output );
+
+/***** public in-line functions *****/
+#pragma prefast( disable : 28112, "blah" )
+
+static LFDS700_PAL_INLINE void lfds700_misc_force_store()
+{
+ lfds700_pal_uint_t
+ exchange = 0;
+
+ lfds700_pal_atom_t volatile LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ destination;
+
+ LFDS700_PAL_ATOMIC_EXCHANGE( &destination, &exchange );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_compiler.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_compiler.h
new file mode 100644
index 0000000000..c628ddd03a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_compiler.h
@@ -0,0 +1,478 @@
+/****************************************************************************/
+#if( defined __GNUC__ )
+ // TRD : makes checking GCC versions much tidier
+ #define LFDS700_PAL_GCC_VERSION ( __GNUC__ * 100 + __GNUC_MINOR__ * 10 + __GNUC_PATCHLEVEL__ )
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined _MSC_VER && _MSC_VER >= 1400 )
+
+ /* TRD : MSVC 8.0 and greater
+
+ _MSC_VER indicates Microsoft C compiler and version
+ - __declspec(align) requires 7.1 (1310)
+ - __nop requires 8.0 (1400)
+ - _ReadBarrier requires 8.0 (1400)
+ - _WriteBarrier requires 8.0 (1400)
+ - _ReadWriteBarrier requires 7.1 (1310)
+ - _InterlockedCompareExchangePointer requires 8.0 (1400)
+ - _InterlockedExchange requires 7.1 (1310)
+ - _InterlockedExchangePointer requires 8.0 (1400)
+ - _InterlockedCompareExchange64 requires 8.0 (1400) (seems to, docs unclear)
+ - _InterlockedCompareExchange128 requires 9.0 (1500)
+
+ load/store barriers are mandatory for liblfds, which means the earliest viable version of MSCV is 1400
+ strictly we could get away with 1310 and use _ReadWriteBarrier, but the difference between 1310 and 1400 is small, so WTH
+
+ _InterlockedCompareExchange128 is needed on 64-bit platforms to provide DWCAS, but DWCAS is not mandatory,
+ so we check against the compiler version - remember, any unimplemented atomic will be masked by its dummy define,
+ so everything will compile - it just means you can't use data structures which require that atomic
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_COMPILER
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_compiler.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_COMPILER
+
+ #define LFDS700_PAL_COMPILER_STRING "MSVC"
+
+ #define LFDS700_PAL_ALIGN(alignment) __declspec( align(alignment) )
+ #define LFDS700_PAL_INLINE __forceinline
+
+ #define LFDS700_PAL_BARRIER_COMPILER_LOAD _ReadBarrier()
+ #define LFDS700_PAL_BARRIER_COMPILER_STORE _WriteBarrier()
+ #define LFDS700_PAL_BARRIER_COMPILER_FULL _ReadWriteBarrier()
+
+ /* TRD : there are four processors to consider;
+
+ . ARM32 (32 bit, CAS, DWCAS) (defined _M_ARM)
+ . Itanium (64 bit, CAS) (defined _M_IA64)
+ . x64 (64 bit, CAS, DWCAS) (defined _M_X64 || defined _M_AMD64)
+ . x86 (32 bit, CAS, DWCAS) (defined _M_IX86)
+
+ can't find any indications of 64-bit ARM support yet
+
+ ARM has better intrinsics than the others, as there are no-fence variants
+
+ in theory we also have to deal with 32-bit Windows on a 64-bit platform,
+ and I presume we'd see the compiler properly indicate this in its macros,
+ but this would require that we use 32-bit atomics on the 64-bit platforms,
+ while keeping 64-bit cache line lengths and so on, and this is just so
+ wierd a thing to do these days that it's not supported
+
+ note that _InterlockedCompareExchangePointer performs CAS on all processors
+ however, it is documented as being available for x86 when in fact it is not
+ so we have to #if for processor type and use the length specific intrinsics
+ */
+
+ #if( defined _M_ARM )
+ #define LFDS700_PAL_BARRIER_PROCESSOR_LOAD __dmb( _ARM_BARRIER_ISH )
+ #define LFDS700_PAL_BARRIER_PROCESSOR_STORE __dmb( _ARM_BARRIER_ISHST )
+ #define LFDS700_PAL_BARRIER_PROCESSOR_FULL __dmb( _ARM_BARRIER_ISH )
+
+ #define LFDS700_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result ) \
+ { \
+ lfds700_pal_atom_t \
+ original_compare; \
+ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* TRD : new_destination can be any value in its range */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ original_compare = (lfds700_pal_atom_t) *(pointer_to_compare); \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(lfds700_pal_atom_t *) (pointer_to_compare) = (lfds700_pal_atom_t) _InterlockedCompareExchange_nf( (long volatile *) (pointer_to_destination), (long) (new_destination), (long) *(pointer_to_compare) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ \
+ result = (char unsigned) ( original_compare == (lfds700_pal_atom_t) *(pointer_to_compare) ); \
+ }
+
+ #define LFDS700_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result ) \
+ { \
+ __int64 \
+ original_compare; \
+ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_new_destination) != NULL ); */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ original_compare = *(__int64 *) (pointer_to_compare); \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(__int64 *) (pointer_to_compare) = _InterlockedCompareExchange64_nf( (__int64 volatile *) (pointer_to_destination), *(__int64 *) (pointer_to_new_destination), *(__int64 *) (pointer_to_compare) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ \
+ result = (char unsigned) ( *(__int64 *) (pointer_to_compare) == original_compare ); \
+ }
+
+ #define LFDS700_PAL_ATOMIC_EXCHANGE( pointer_to_destination, pointer_to_exchange ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_exchange) != NULL ); */ \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(lfds700_pal_atom_t *) (pointer_to_exchange) = (lfds700_pal_atom_t) _InterlockedExchange_nf( (int long volatile *) (pointer_to_destination), (int long) *(pointer_to_exchange) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ }
+ #endif
+
+ #if( defined _M_IA64 )
+ #define LFDS700_PAL_BARRIER_PROCESSOR_LOAD __mf()
+ #define LFDS700_PAL_BARRIER_PROCESSOR_STORE __mf()
+ #define LFDS700_PAL_BARRIER_PROCESSOR_FULL __mf()
+
+ #define LFDS700_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result ) \
+ { \
+ lfds700_pal_atom_t \
+ original_compare; \
+ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* TRD : new_destination can be any value in its range */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ original_compare = (lfds700_pal_atom_t) *(pointer_to_compare); \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(lfds700_pal_atom_t *) (pointer_to_compare) = (lfds700_pal_atom_t) _InterlockedCompareExchange64_acq( (__int64 volatile *) (pointer_to_destination), (__int64) (new_destination), (__int64) *(pointer_to_compare) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ \
+ result = (char unsigned) ( original_compare == (lfds700_pal_atom_t) *(pointer_to_compare) ); \
+ }
+
+ #define LFDS700_PAL_ATOMIC_EXCHANGE( pointer_to_destination, pointer_to_exchange ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_exchange) != NULL ); */ \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(lfds700_pal_atom_t *) (pointer_to_exchange) = (lfds700_pal_atom_t) _InterlockedExchange64_acq( (__int64 volatile *) (pointer_to_destination), (__int64) *(pointer_to_exchange) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ }
+ #endif
+
+ #if( defined _M_X64 || defined _M_AMD64 )
+ #define LFDS700_PAL_BARRIER_PROCESSOR_LOAD _mm_lfence()
+ #define LFDS700_PAL_BARRIER_PROCESSOR_STORE _mm_sfence()
+ #define LFDS700_PAL_BARRIER_PROCESSOR_FULL _mm_mfence()
+
+ #define LFDS700_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result ) \
+ { \
+ lfds700_pal_atom_t \
+ original_compare; \
+ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* TRD : new_destination can be any value in its range */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ original_compare = (lfds700_pal_atom_t) *(pointer_to_compare); \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(lfds700_pal_atom_t *) (pointer_to_compare) = (lfds700_pal_atom_t) _InterlockedCompareExchange64( (__int64 volatile *) (pointer_to_destination), (__int64) (new_destination), (__int64) *(pointer_to_compare) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ \
+ result = (char unsigned) ( original_compare == (lfds700_pal_atom_t) *(pointer_to_compare) ); \
+ }
+
+ #if( _MSC_VER >= 1500 )
+ #define LFDS700_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_new_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ result = (char unsigned) _InterlockedCompareExchange128( (__int64 volatile *) (pointer_to_destination), (__int64) (pointer_to_new_destination[1]), (__int64) (pointer_to_new_destination[0]), (__int64 *) (pointer_to_compare) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ }
+ #endif
+
+ #define LFDS700_PAL_ATOMIC_EXCHANGE( pointer_to_destination, pointer_to_exchange ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_exchange) != NULL ); */ \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(lfds700_pal_atom_t *) (pointer_to_exchange) = (lfds700_pal_atom_t) _InterlockedExchangePointer( (void * volatile *) (pointer_to_destination), (void *) *(pointer_to_exchange) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ }
+ #endif
+
+ #if( defined _M_IX86 )
+ #define LFDS700_PAL_BARRIER_PROCESSOR_LOAD lfds700_misc_force_store()
+ #define LFDS700_PAL_BARRIER_PROCESSOR_STORE lfds700_misc_force_store()
+ #define LFDS700_PAL_BARRIER_PROCESSOR_FULL lfds700_misc_force_store()
+
+ #define LFDS700_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result ) \
+ { \
+ lfds700_pal_atom_t \
+ original_compare; \
+ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* TRD : new_destination can be any value in its range */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ original_compare = (lfds700_pal_atom_t) *(pointer_to_compare); \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(lfds700_pal_atom_t *) (pointer_to_compare) = (lfds700_pal_atom_t) _InterlockedCompareExchange( (long volatile *) (pointer_to_destination), (long) (new_destination), (long) *(pointer_to_compare) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ \
+ result = (char unsigned) ( original_compare == (lfds700_pal_atom_t) *(pointer_to_compare) ); \
+ }
+
+ #define LFDS700_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result ) \
+ { \
+ __int64 \
+ original_compare; \
+ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_new_destination) != NULL ); */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ original_compare = *(__int64 *) (pointer_to_compare); \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(__int64 *) (pointer_to_compare) = _InterlockedCompareExchange64( (__int64 volatile *) (pointer_to_destination), *(__int64 *) (pointer_to_new_destination), *(__int64 *) (pointer_to_compare) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ \
+ result = (char unsigned) ( *(__int64 *) (pointer_to_compare) == original_compare ); \
+ }
+
+ #define LFDS700_PAL_ATOMIC_EXCHANGE( pointer_to_destination, pointer_to_exchange ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_exchange) != NULL ); */ \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(lfds700_pal_atom_t *) (pointer_to_exchange) = (lfds700_pal_atom_t) _InterlockedExchange( (int long volatile *) (pointer_to_destination), (int long) *(pointer_to_exchange) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ }
+ #endif
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && LFDS700_PAL_GCC_VERSION >= 412 && LFDS700_PAL_GCC_VERSION < 473 )
+
+ /* TRD : GCC 4.1.2 up to 4.7.3
+
+ __GNUC__ indicates GCC
+ LFDS700_PAL_GCC_VERSION indicates which version
+ - __sync_synchronize requires 4.1.2
+
+ GCC 4.1.2 introduced the __sync_*() atomic intrinsics
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_COMPILER
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_compiler.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_COMPILER
+
+ #define LFDS700_PAL_COMPILER_STRING "GCC < 4.7.3"
+
+ #define LFDS700_PAL_ALIGN(alignment) __attribute__( (aligned(alignment)) )
+ #define LFDS700_PAL_INLINE inline
+
+ static LFDS700_PAL_INLINE void lfds700_pal_barrier_compiler( void )
+ {
+ __asm__ __volatile__ ( "" : : : "memory" );
+ }
+
+ #define LFDS700_PAL_BARRIER_COMPILER_LOAD lfds700_pal_barrier_compiler()
+ #define LFDS700_PAL_BARRIER_COMPILER_STORE lfds700_pal_barrier_compiler()
+ #define LFDS700_PAL_BARRIER_COMPILER_FULL lfds700_pal_barrier_compiler()
+
+ #define LFDS700_PAL_BARRIER_PROCESSOR_LOAD __sync_synchronize()
+ #define LFDS700_PAL_BARRIER_PROCESSOR_STORE __sync_synchronize()
+ #define LFDS700_PAL_BARRIER_PROCESSOR_FULL __sync_synchronize()
+
+ #define LFDS700_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result ) \
+ { \
+ lfds700_pal_atom_t \
+ original_compare; \
+ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* TRD : new_destination can be any value in its range */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ original_compare = (lfds700_pal_atom_t) *(pointer_to_compare); \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *(pointer_to_compare) = __sync_val_compare_and_swap( pointer_to_destination, *(pointer_to_compare), new_destination ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ \
+ result = (unsigned char) ( original_compare == (lfds700_pal_atom_t) *(pointer_to_compare) ); \
+ }
+
+ // TRD : ARM and x86 have DWCAS which we can get via GCC intrinsics
+ #if( defined __arm__ || defined __i686__ || defined __i586__ || defined __i486__ )
+ #define LFDS700_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result ) \
+ { \
+ int long long unsigned \
+ original_destination; \
+ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_new_destination) != NULL ); */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ original_destination = __sync_val_compare_and_swap( (int long long unsigned volatile *) (pointer_to_destination), *(int long long unsigned *) (pointer_to_compare), *(int long long unsigned *) (pointer_to_new_destination) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ \
+ result = (char unsigned) ( original_destination == *(int long long unsigned *) (pointer_to_compare) ); \
+ \
+ *(int long long unsigned *) (pointer_to_compare) = original_destination; \
+ }
+ #endif
+
+ #define LFDS700_PAL_ATOMIC_EXCHANGE( pointer_to_destination, pointer_to_exchange ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_exchange) != NULL ); */ \
+ \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ *( (lfds700_pal_atom_t *) pointer_to_exchange) = (lfds700_pal_atom_t) __sync_lock_test_and_set( pointer_to_destination, *(pointer_to_exchange) ); \
+ LFDS700_PAL_BARRIER_COMPILER_FULL; \
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && LFDS700_PAL_GCC_VERSION >= 473 )
+
+ /* TRD : GCC 4.7.3 and greater
+
+ __GNUC__ indicates GCC
+ LFDS700_PAL_GCC_VERSION indicates which version
+ - __atomic_thread_fence requires 4.7.3
+
+ GCC 4.7.3 introduced the better __atomic*() atomic intrinsics
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_COMPILER
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_compiler.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_COMPILER
+
+ #define LFDS700_PAL_COMPILER_STRING "GCC >= 4.7.3"
+
+ #define LFDS700_PAL_ALIGN(alignment) __attribute__( (aligned(alignment)) )
+ #define LFDS700_PAL_INLINE inline
+
+ // TRD : GCC >= 4.7.3 compiler barriers are built into the intrinsics
+ #define LFDS700_PAL_NO_COMPILER_BARRIERS
+
+ #define LFDS700_PAL_BARRIER_PROCESSOR_LOAD __atomic_thread_fence( __ATOMIC_ACQUIRE )
+ #define LFDS700_PAL_BARRIER_PROCESSOR_STORE __atomic_thread_fence( __ATOMIC_RELEASE )
+ #define LFDS700_PAL_BARRIER_PROCESSOR_FULL __atomic_thread_fence( __ATOMIC_ACQ_REL )
+
+ #define LFDS700_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* TRD : new_destination can be any value in its range */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ result = (char unsigned) __atomic_compare_exchange_n( pointer_to_destination, (void *) (pointer_to_compare), (new_destination), (cas_strength), __ATOMIC_RELAXED, __ATOMIC_RELAXED ); \
+ }
+
+ // TRD : ARM and x86 have DWCAS which we can get via GCC intrinsics
+ #if( defined __arm__ || defined __i686__ || defined __i586__ || defined __i486__ )
+ #define LFDS700_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_new_destination) != NULL ); */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ (result) = (char unsigned) __atomic_compare_exchange_n( (int long long unsigned volatile *) (pointer_to_destination), (int long long unsigned *) (pointer_to_compare), *(int long long unsigned *) (pointer_to_new_destination), (cas_strength), __ATOMIC_RELAXED, __ATOMIC_RELAXED ); \
+ }
+ #endif
+
+ #if( defined __x86_64__ )
+ /* TRD : __GNUC__ indicates GCC
+ - __asm__ requires GCC
+ - __volatile__ requires GCC
+ __x86_64__ indicates x64
+ - cmpxchg16b requires x64
+
+ On 64 bit platforms, unsigned long long int is 64 bit, so we must manually use cmpxchg16b,
+ as __sync_val_compare_and_swap() will only emit cmpxchg8b
+ */
+
+ // TRD : lfds700_pal_atom_t volatile (*destination)[2], lfds700_pal_atom_t (*compare)[2], lfds700_pal_atom_t (*new_destination)[2], enum lfds700_misc_cas_strength cas_strength, char unsigned result
+
+ #define LFDS700_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_compare) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_new_destination) != NULL ); */ \
+ /* TRD : cas_strength can be any value in its range */ \
+ /* TRD : result can be any value in its range */ \
+ \
+ (result) = 0; \
+ \
+ __asm__ __volatile__ \
+ ( \
+ "lock;" /* make cmpxchg16b atomic */ \
+ "cmpxchg16b %0;" /* cmpxchg16b sets ZF on success */ \
+ "setz %3;" /* if ZF set, set result to 1 */ \
+ \
+ /* output */ \
+ : "+m" (*pointer_to_destination), "+a" ((pointer_to_compare)[0]), "+d" ((pointer_to_compare)[1]), "=q" (result) \
+ \
+ /* input */ \
+ : "b" ((pointer_to_new_destination)[0]), "c" ((pointer_to_new_destination)[1]) \
+ \
+ /* clobbered */ \
+ : "cc", "memory" \
+ ); \
+ }
+ #endif
+
+ #define LFDS700_PAL_ATOMIC_EXCHANGE( pointer_to_destination, pointer_to_exchange ) \
+ { \
+ /* LFDS700_PAL_ASSERT( (pointer_to_destination) != NULL ); */ \
+ /* LFDS700_PAL_ASSERT( (pointer_to_exchange) != NULL ); */ \
+ \
+ *(pointer_to_exchange) = __atomic_exchange_n( (pointer_to_destination), *(pointer_to_exchange), __ATOMIC_RELAXED ); \
+ }
+
+#endif
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_operating_system.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_operating_system.h
new file mode 100644
index 0000000000..0c1eba628a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_operating_system.h
@@ -0,0 +1,133 @@
+/****************************************************************************/
+#if( defined _MSC_VER )
+ /* TRD : MSVC compiler
+
+ an unfortunately necessary hack for MSVC
+ MSVC only defines __STDC__ if /Za is given, where /Za turns off MSVC C extensions -
+ which prevents Windows header files from compiling.
+ */
+
+ #define __STDC__ 1
+ #define __STDC_HOSTED__ 1
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined _MSC_VER && _MSC_VER >= 1400 && __STDC_HOSTED__ == 1 && !defined _KERNEL_MODE )
+
+ // TRD : MSVC
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_operating_system.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+
+ #include
+
+ #define LFDS700_PAL_OS_STRING "Windows"
+ #define LFDS700_PAL_ASSERT( expression ) assert( expression )
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined _MSC_VER && _MSC_VER >= 1400 && defined __STDC_HOSTED__ && __STDC_HOSTED__ == 1 && defined _WIN32 && defined _KERNEL_MODE )
+
+ // TRD : MSVC, Windows kernel-mode
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_operating_system.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+
+ #include
+ #include
+
+ #define LFDS700_PAL_OS_STRING "Windows"
+ #define LFDS700_PAL_ASSERT( expression ) assert( expression )
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && __STDC_HOSTED__ == 1 && !(defined __linux__ && defined _KERNEL_MODE) )
+
+ // TRD : GCC, hosted implementation (except for Linux kernel mode)
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_operating_system.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+
+ #include
+
+ #define LFDS700_PAL_OS_STRING "Embedded (hosted)"
+ #define LFDS700_PAL_ASSERT( expression ) assert( expression )
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && __STDC_HOSTED__ == 0 )
+
+ // TRD : GCC, freestanding or bare implementation
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_operating_system.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+
+ #define LFDS700_PAL_OS_STRING "Embedded (freestanding/bare)"
+ #define LFDS700_PAL_ASSERT( expression )
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __linux__ && defined _KERNEL_MODE )
+
+ // TRD : GCC, Linux kernel-mode
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_operating_system.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM
+
+ #include
+
+ #define LFDS700_PAL_OS_STRING "Linux"
+ #define LFDS700_PAL_ASSERT( expression ) BUG_ON( expression )
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( !defined LFDS700_PAL_PORTING_ABSTRACTION_LAYER_OPERATING_SYSTEM )
+
+ #error No matching porting abstraction layer in lfds700_porting_abstraction_layer_operating_system.h
+
+#endif
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_processor.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_processor.h
new file mode 100644
index 0000000000..1e81c0eae2
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_porting_abstraction_layer_processor.h
@@ -0,0 +1,544 @@
+/****************************************************************************/
+#if( defined _MSC_VER && _MSC_VER >= 1400 && defined _M_IX86 )
+
+ /* TRD : MSVC, x86
+ x86 is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "x86"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 4
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 8
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 32
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined _MSC_VER && _MSC_VER >= 1400 && (defined _M_X64 || defined _M_AMD64) )
+
+ /* TRD : MSVC, x64
+ x64 is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long long unsigned lfds700_pal_atom_t;
+ typedef int long long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "x64"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 64
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 64
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined _MSC_VER && _MSC_VER >= 1400 && defined _M_IA64 )
+
+ /* TRD : MSVC, Itanium
+ IA64 is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long long unsigned lfds700_pal_atom_t;
+ typedef int long long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "IA64"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 64
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 64
+
+#endif
+
+
+
+
+
+ /****************************************************************************/
+#if( defined _MSC_VER && _MSC_VER >= 1400 && defined _M_ARM )
+
+ /* TRD : MSVC, 32-bit ARM
+
+ ARM is LL/SC and uses a reservation granule of 8 to 2048 bytes
+ so the isolation value used here is worst-case - be sure to set
+ this correctly, otherwise structures are painfully large
+ */
+
+#ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+#error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+#endif
+
+#define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+#define LFDS700_PAL_PROCESSOR_STRING "ARM (32-bit)"
+
+#define LFDS700_PAL_ALIGN_SINGLE_POINTER 4
+#define LFDS700_PAL_ALIGN_DOUBLE_POINTER 8
+
+#define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+#define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 2048
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __arm__ )
+
+ /* TRD : GCC, 32-bit ARM
+
+ ARM is LL/SC and uses a reservation granule of 8 to 2048 bytes
+ so the isolation value used here is worst-case - be sure to set
+ this correctly, otherwise structures are painfully large
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "ARM (32-bit)"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 4
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 8
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 2048
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __aarch64__ )
+
+ /* TRD : GCC, 64-bit ARM
+
+ ARM is LL/SC and uses a reservation granule of 8 to 2048 bytes
+ so the isolation value used here is worst-case - be sure to set
+ this correctly, otherwise structures are painfully large
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long long unsigned lfds700_pal_atom_t;
+ typedef int long long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "ARM (64-bit)"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 64
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 2048
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && (defined __i686__ || defined __i586__ || defined __i486__) )
+
+ /* TRD : GCC, x86
+
+ x86 is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "x86"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 4
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 8
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 32
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __x86_64__ )
+
+ /* TRD : GCC, x86
+
+ x64 is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long long unsigned lfds700_pal_atom_t;
+ typedef int long long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "x64"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 64
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 64
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __alpha__ )
+
+ /* TRD : GCC, alpha
+
+ alpha is LL/SC, but there is only one reservation per processor,
+ so the isolation value used here is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "alpha"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 64
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __ia64__ )
+
+ /* TRD : GCC, Itanium
+
+ Itanium is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long long unsigned lfds700_pal_atom_t;
+ typedef int long long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "IA64"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 64
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 64
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __mips__ )
+
+ /* TRD : GCC, MIPS (32-bit)
+
+ MIPS is LL/SC, but there is only one reservation per processor,
+ so the isolation value used here is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "MIPS (32-bit)"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 4
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 8
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 32
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __mips64 )
+
+ /* TRD : GCC, MIPS (64-bit)
+
+ MIPS is LL/SC, but there is only one reservation per processor,
+ so the isolation value used here is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long long unsigned lfds700_pal_atom_t;
+ typedef int long long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "MIPS (64-bit)"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 64
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 64
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __ppc__ )
+
+ /* TRD : GCC, POWERPC (32-bit)
+
+ POWERPC is LL/SC and uses a reservation granule but I can't find
+ canonical documentation for its size - 128 bytes seems to be the
+ largest value I've found
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "POWERPC (32-bit)"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 4
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 8
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 128
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __ppc64__ )
+
+ /* TRD : GCC, POWERPC (64-bit)
+
+ POWERPC is LL/SC and uses a reservation granule but I can't find
+ canonical documentation for its size - 128 bytes seems to be the
+ largest value I've found
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long long unsigned lfds700_pal_atom_t;
+ typedef int long long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "POWERPC (64-bit)"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 64
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 128
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __sparc__ && !defined __sparc_v9__ )
+
+ /* TRD : GCC, SPARC (32-bit)
+
+ SPARC is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "SPARC (32-bit)"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 4
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 8
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 32
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __sparc__ && defined __sparc_v9__ )
+
+ /* TRD : GCC, SPARC (64-bit)
+
+ SPARC is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long long unsigned lfds700_pal_atom_t;
+ typedef int long long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "SPARC (64-bit)"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 8
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 16
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 64
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 64
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __m68k__ )
+
+ /* TRD : GCC, 680x0
+
+ 680x0 is CAS, so isolation is cache-line length
+ */
+
+ #ifdef LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+ #error More than one porting abstraction layer matches the current platform in lfds700_porting_abstraction_layer_processor.h
+ #endif
+
+ #define LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR
+
+ typedef int long unsigned lfds700_pal_atom_t;
+ typedef int long unsigned lfds700_pal_uint_t;
+
+ #define LFDS700_PAL_PROCESSOR_STRING "680x0"
+
+ #define LFDS700_PAL_ALIGN_SINGLE_POINTER 4
+ #define LFDS700_PAL_ALIGN_DOUBLE_POINTER 8
+
+ #define LFDS700_PAL_CACHE_LINE_LENGTH_IN_BYTES 32
+ #define LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES 32
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( !defined LFDS700_PAL_PORTING_ABSTRACTION_LAYER_PROCESSOR )
+
+ #error No matching porting abstraction layer in lfds700_porting_abstraction_layer_processor.h
+
+#endif
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_queue.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_queue.h
new file mode 100644
index 0000000000..025b0673e9
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_queue.h
@@ -0,0 +1,60 @@
+/***** defines *****/
+#define LFDS700_QUEUE_GET_KEY_FROM_ELEMENT( queue_element ) ( (queue_element).key )
+#define LFDS700_QUEUE_SET_KEY_IN_ELEMENT( queue_element, new_key ) ( (queue_element).key = (void *) (lfds700_pal_uint_t) (new_key) )
+#define LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( queue_element ) ( (queue_element).value )
+#define LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( queue_element, new_value ) ( (queue_element).value = (void *) (lfds700_pal_uint_t) (new_value) )
+#define LFDS700_QUEUE_GET_USER_STATE_FROM_STATE( queue_state ) ( (queue_state).user_state )
+
+/***** enums *****/
+enum lfds700_queue_query
+{
+ LFDS700_QUEUE_QUERY_SINGLETHREADED_GET_COUNT,
+ LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE
+};
+
+/***** structures *****/
+struct lfds700_queue_element
+{
+ struct lfds700_queue_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile next[PAC_SIZE];
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *key;
+
+ void
+ *value;
+};
+
+struct lfds700_queue_state
+{
+ struct lfds700_queue_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile enqueue[PAC_SIZE],
+ *volatile dequeue[PAC_SIZE];
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_queue_init_valid_on_current_logical_core( struct lfds700_queue_state *qs,
+ struct lfds700_queue_element *qe_dummy,
+ struct lfds700_misc_prng_state *ps,
+ void *user_state );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_queue_cleanup( struct lfds700_queue_state *qs,
+ void (*element_cleanup_callback)(struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag) );
+
+void lfds700_queue_enqueue( struct lfds700_queue_state *qs,
+ struct lfds700_queue_element *qe,
+ struct lfds700_misc_prng_state *ps );
+
+int lfds700_queue_dequeue( struct lfds700_queue_state *qs,
+ struct lfds700_queue_element **qe,
+ struct lfds700_misc_prng_state *ps );
+
+void lfds700_queue_query( struct lfds700_queue_state *qs,
+ enum lfds700_queue_query query_type,
+ void *query_input,
+ void *query_output );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_queue_bounded_singleconsumer_singleproducer.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_queue_bounded_singleconsumer_singleproducer.h
new file mode 100644
index 0000000000..3b090e1d45
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_queue_bounded_singleconsumer_singleproducer.h
@@ -0,0 +1,59 @@
+/***** defines *****/
+#define LFDS700_QUEUE_BSS_GET_USER_STATE_FROM_STATE( queue_bss_state ) ( (queue_bss_state).user_state )
+
+/***** enums *****/
+enum lfds700_queue_bss_query
+{
+ LFDS700_QUEUE_BSS_QUERY_GET_POTENTIALLY_INACCURATE_COUNT,
+ LFDS700_QUEUE_BSS_QUERY_VALIDATE
+};
+
+/***** structures *****/
+struct lfds700_queue_bss_element
+{
+ void
+ *volatile key,
+ *volatile value;
+};
+
+struct lfds700_queue_bss_state
+{
+ lfds700_pal_uint_t
+ number_elements,
+ mask;
+
+ lfds700_pal_uint_t volatile
+ read_index,
+ write_index;
+
+ struct lfds700_queue_bss_element
+ *element_array;
+
+ void
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_queue_bss_init_valid_on_current_logical_core( struct lfds700_queue_bss_state *qbsss,
+ struct lfds700_queue_bss_element *element_array,
+ lfds700_pal_uint_t number_elements,
+ void *user_state );
+ // TRD : number_elements must be a positive integer power of 2
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_queue_bss_cleanup( struct lfds700_queue_bss_state *qbsss,
+ void (*element_cleanup_callback)(struct lfds700_queue_bss_state *qbsss, void *key, void *value) );
+
+int lfds700_queue_bss_enqueue( struct lfds700_queue_bss_state *qbsss,
+ void *key,
+ void *value );
+
+int lfds700_queue_bss_dequeue( struct lfds700_queue_bss_state *qbsss,
+ void **key,
+ void **value );
+
+void lfds700_queue_bss_query( struct lfds700_queue_bss_state *qbsss,
+ enum lfds700_queue_bss_query query_type,
+ void *query_input,
+ void *query_output );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_ringbuffer.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_ringbuffer.h
new file mode 100644
index 0000000000..fbb21d2be4
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_ringbuffer.h
@@ -0,0 +1,69 @@
+/***** enums *****/
+#define LFDS700_RINGBUFFER_GET_USER_STATE_FROM_STATE( ringbuffer_state ) ( (ringbuffer_state).user_state )
+
+/***** enums *****/
+enum lfds700_ringbuffer_query
+{
+ LFDS700_RINGBUFFER_QUERY_SINGLETHREADED_GET_COUNT,
+ LFDS700_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE
+};
+
+/***** structures *****/
+struct lfds700_ringbuffer_element
+{
+ struct lfds700_freelist_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ fe;
+
+ struct lfds700_queue_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ qe;
+
+ struct lfds700_queue_element
+ *qe_use; // TRD : hack for 7.0.0; we need a new queue with no dummy element
+
+ void
+ *key,
+ *value;
+};
+
+struct lfds700_ringbuffer_state
+{
+ struct lfds700_freelist_state LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ fs;
+
+ struct lfds700_queue_state LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ qs;
+
+ void
+ (*element_cleanup_callback)( struct lfds700_ringbuffer_state *rs, void *key, void *value, enum lfds700_misc_flag unread_flag ),
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_ringbuffer_init_valid_on_current_logical_core( struct lfds700_ringbuffer_state *rs,
+ struct lfds700_ringbuffer_element *re_array_inc_dummy,
+ lfds700_pal_uint_t number_elements,
+ struct lfds700_misc_prng_state *ps,
+ void *user_state );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_ringbuffer_cleanup( struct lfds700_ringbuffer_state *rs,
+ void (*element_cleanup_callback)(struct lfds700_ringbuffer_state *rs, void *key, void *value, enum lfds700_misc_flag unread_flag) );
+
+int lfds700_ringbuffer_read( struct lfds700_ringbuffer_state *rs,
+ void **key,
+ void **value,
+ struct lfds700_misc_prng_state *ps );
+
+void lfds700_ringbuffer_write( struct lfds700_ringbuffer_state *rs,
+ void *key,
+ void *value,
+ enum lfds700_misc_flag *overwrite_occurred_flag,
+ void **overwritten_key,
+ void **overwritten_value,
+ struct lfds700_misc_prng_state *ps );
+
+void lfds700_ringbuffer_query( struct lfds700_ringbuffer_state *rs,
+ enum lfds700_ringbuffer_query query_type,
+ void *query_input,
+ void *query_output );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_stack.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_stack.h
new file mode 100644
index 0000000000..3faed80308
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/inc/liblfds700/lfds700_stack.h
@@ -0,0 +1,55 @@
+/***** defines *****/
+#define LFDS700_STACK_GET_KEY_FROM_ELEMENT( stack_element ) ( (stack_element).key )
+#define LFDS700_STACK_SET_KEY_IN_ELEMENT( stack_element, new_key ) ( (stack_element).key = (void *) (lfds700_pal_uint_t) (new_key) )
+#define LFDS700_STACK_GET_VALUE_FROM_ELEMENT( stack_element ) ( (stack_element).value )
+#define LFDS700_STACK_SET_VALUE_IN_ELEMENT( stack_element, new_value ) ( (stack_element).value = (void *) (lfds700_pal_uint_t) (new_value) )
+#define LFDS700_STACK_GET_USER_STATE_FROM_STATE( stack_state ) ( (stack_state).user_state )
+
+/***** enums *****/
+enum lfds700_stack_query
+{
+ LFDS700_STACK_QUERY_SINGLETHREADED_GET_COUNT,
+ LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE
+};
+
+/***** structures *****/
+struct lfds700_stack_element
+{
+ struct lfds700_stack_element
+ *volatile next;
+
+ void
+ *key,
+ *value;
+};
+
+struct lfds700_stack_state
+{
+ struct lfds700_stack_element LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *volatile top[PAC_SIZE];
+
+ void LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ *user_state;
+};
+
+/***** public prototypes *****/
+void lfds700_stack_init_valid_on_current_logical_core( struct lfds700_stack_state *ss, void *user_state );
+ // TRD : used in conjunction with the #define LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE
+
+void lfds700_stack_cleanup( struct lfds700_stack_state *ss,
+ void (*element_cleanup_callback)(struct lfds700_stack_state *ss, struct lfds700_stack_element *se) );
+
+void lfds700_stack_push( struct lfds700_stack_state *ss,
+ struct lfds700_stack_element *se,
+ struct lfds700_misc_prng_state *ps );
+
+int lfds700_stack_pop( struct lfds700_stack_state *ss,
+ struct lfds700_stack_element **se,
+ struct lfds700_misc_prng_state *ps );
+
+void lfds700_stack_query( struct lfds700_stack_state *ss,
+ enum lfds700_stack_query query_type,
+ void *query_input,
+ void *query_output );
+
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_cleanup.c
new file mode 100644
index 0000000000..2927c98628
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_cleanup.c
@@ -0,0 +1,117 @@
+/***** includes *****/
+#include "lfds700_btree_addonly_unbalanced_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_btree_au_cleanup( struct lfds700_btree_au_state *baus,
+ void (*element_cleanup_callback)(struct lfds700_btree_au_state *baus, struct lfds700_btree_au_element *baue) )
+{
+ enum lfds700_btree_au_delete_action
+ delete_action = LFDS700_BTREE_AU_DELETE_SELF; // TRD : to remove compiler warning
+
+ struct lfds700_btree_au_element
+ *baue;
+
+ struct lfds700_btree_au_element
+ *temp;
+
+ LFDS700_PAL_ASSERT( baus != NULL );
+ // TRD : element_delete_function can be NULL
+
+ /* TRD : we're not lock-free now, so delete at will
+ but be iterative, so can be used in kernels (where there's little stack)
+ and be performant, since the user may be
+ creating/destroying many of these trees
+ also remember the user may be deallocating user data
+ so we cannot visit an element twice
+
+ we start at the root and iterate till we go to NULL
+ if the element has zero children, we delete it and move up to its parent
+ if the element has one child, we delete it, move its child into its place, and continue from its child
+ if the element has two children, we move left
+
+ the purpose of this is to minimize walking around the tree
+ to prevent visiting an element twice
+ while also minimizing code complexity
+ */
+
+ if( element_cleanup_callback == NULL )
+ return;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lfds700_btree_au_get_by_absolute_position( baus, &baue, LFDS700_BTREE_AU_ABSOLUTE_POSITION_ROOT );
+
+ while( baue != NULL )
+ {
+ if( baue->left == NULL and baue->right == NULL )
+ delete_action = LFDS700_BTREE_AU_DELETE_SELF;
+
+ if( baue->left != NULL and baue->right == NULL )
+ delete_action = LFDS700_BTREE_AU_DELETE_SELF_REPLACE_WITH_LEFT_CHILD;
+
+ if( baue->left == NULL and baue->right != NULL )
+ delete_action = LFDS700_BTREE_AU_DELETE_SELF_REPLACE_WITH_RIGHT_CHILD;
+
+ if( baue->left != NULL and baue->right != NULL )
+ delete_action = LFDS700_BTREE_AU_DELETE_MOVE_LEFT;
+
+ switch( delete_action )
+ {
+ case LFDS700_BTREE_AU_DELETE_SELF:
+ // TRD : if we have a parent (we could be root) set his point to us to NULL
+ if( baue->up != NULL )
+ {
+ if( baue->up->left == baue )
+ baue->up->left = NULL;
+ if( baue->up->right == baue )
+ baue->up->right = NULL;
+ }
+
+ temp = baue;
+ lfds700_btree_au_get_by_relative_position( &baue, LFDS700_BTREE_AU_RELATIVE_POSITION_UP );
+ element_cleanup_callback( baus, temp );
+ break;
+
+ case LFDS700_BTREE_AU_DELETE_SELF_REPLACE_WITH_LEFT_CHILD:
+ baue->left->up = baue->up;
+ if( baue->up != NULL )
+ {
+ if( baue->up->left == baue )
+ baue->up->left = baue->left;
+ if( baue->up->right == baue )
+ baue->up->right = baue->left;
+ }
+
+ temp = baue;
+ lfds700_btree_au_get_by_relative_position( &baue, LFDS700_BTREE_AU_RELATIVE_POSITION_LEFT );
+ element_cleanup_callback( baus, temp );
+ break;
+
+ case LFDS700_BTREE_AU_DELETE_SELF_REPLACE_WITH_RIGHT_CHILD:
+ baue->right->up = baue->up;
+ if( baue->up != NULL )
+ {
+ if( baue->up->left == baue )
+ baue->up->left = baue->right;
+ if( baue->up->right == baue )
+ baue->up->right = baue->right;
+ }
+
+ temp = baue;
+ lfds700_btree_au_get_by_relative_position( &baue, LFDS700_BTREE_AU_RELATIVE_POSITION_RIGHT );
+ element_cleanup_callback( baus, temp );
+ break;
+
+ case LFDS700_BTREE_AU_DELETE_MOVE_LEFT:
+ lfds700_btree_au_get_by_relative_position( &baue, LFDS700_BTREE_AU_RELATIVE_POSITION_LEFT );
+ break;
+ }
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_get.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_get.c
new file mode 100644
index 0000000000..8a2cdf93e8
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_get.c
@@ -0,0 +1,467 @@
+/***** includes *****/
+#include "lfds700_btree_addonly_unbalanced_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_btree_au_internal_inorder_walk_from_largest_get_next_smallest_element( struct lfds700_btree_au_element **baue );
+static void lfds700_btree_au_internal_inorder_walk_from_smallest_get_next_largest_element( struct lfds700_btree_au_element **baue );
+
+
+
+
+
+/****************************************************************************/
+int lfds700_btree_au_get_by_key( struct lfds700_btree_au_state *baus,
+ void *key,
+ struct lfds700_btree_au_element **baue )
+{
+ int
+ compare_result = !0,
+ rv = 1;
+
+ LFDS700_PAL_ASSERT( baus != NULL );
+ // TRD : key can be NULL
+ LFDS700_PAL_ASSERT( baue != NULL );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ *baue = baus->root;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ while( *baue != NULL and compare_result != 0 )
+ {
+ compare_result = baus->key_compare_function( key, (*baue)->key );
+
+ if( compare_result < 0 )
+ {
+ *baue = (*baue)->left;
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+
+ if( compare_result > 0 )
+ {
+ *baue = (*baue)->right;
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+ }
+
+ if( *baue == NULL )
+ rv = 0;
+
+ return( rv );
+}
+
+
+
+
+
+/****************************************************************************/
+int lfds700_btree_au_get_by_absolute_position( struct lfds700_btree_au_state *baus, struct lfds700_btree_au_element **baue, enum lfds700_btree_au_absolute_position absolute_position )
+{
+ int
+ rv = 1;
+
+ LFDS700_PAL_ASSERT( baus != NULL );
+ LFDS700_PAL_ASSERT( baue != NULL );
+ // TRD : absolute_position can be any value in its range
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ *baue = baus->root;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ switch( absolute_position )
+ {
+ case LFDS700_BTREE_AU_ABSOLUTE_POSITION_ROOT:
+ break;
+
+ case LFDS700_BTREE_AU_ABSOLUTE_POSITION_LARGEST_IN_TREE:
+ if( *baue != NULL )
+ while( (*baue)->right != NULL )
+ {
+ *baue = (*baue)->right;
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+ break;
+
+ case LFDS700_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE:
+ if( *baue != NULL )
+ while( (*baue)->left != NULL )
+ {
+ *baue = (*baue)->left;
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+ break;
+ }
+
+ if( *baue == NULL )
+ rv = 0;
+
+ return( rv );
+}
+
+
+
+
+
+/****************************************************************************/
+int lfds700_btree_au_get_by_relative_position( struct lfds700_btree_au_element **baue, enum lfds700_btree_au_relative_position relative_position )
+{
+ int
+ rv = 1;
+
+ LFDS700_PAL_ASSERT( baue != NULL );
+ // TRD : relative_position can baue any value in its range
+
+ if( *baue == NULL )
+ return( 0 );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ switch( relative_position )
+ {
+ case LFDS700_BTREE_AU_RELATIVE_POSITION_UP:
+ *baue = (*baue)->up;
+ // TRD : no load barrier - up already existed, so is known to be safely propagated
+ break;
+
+ case LFDS700_BTREE_AU_RELATIVE_POSITION_LEFT:
+ *baue = (*baue)->left;
+ LFDS700_MISC_BARRIER_LOAD;
+ break;
+
+ case LFDS700_BTREE_AU_RELATIVE_POSITION_RIGHT:
+ *baue = (*baue)->right;
+ LFDS700_MISC_BARRIER_LOAD;
+ break;
+
+ case LFDS700_BTREE_AU_RELATIVE_POSITION_SMALLEST_ELEMENT_BELOW_CURRENT_ELEMENT:
+ *baue = (*baue)->left;
+ if( *baue != NULL )
+ {
+ LFDS700_MISC_BARRIER_LOAD;
+ while( (*baue)->right != NULL )
+ {
+ *baue = (*baue)->right;
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+ }
+ break;
+
+ case LFDS700_BTREE_AU_RELATIVE_POSITION_LARGEST_ELEMENT_BELOW_CURRENT_ELEMENT:
+ *baue = (*baue)->right;
+ if( *baue != NULL )
+ {
+ LFDS700_MISC_BARRIER_LOAD;
+ while( (*baue)->left != NULL )
+ {
+ *baue = (*baue)->left;
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+ }
+ break;
+
+ case LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_SMALLER_ELEMENT_IN_ENTIRE_TREE:
+ lfds700_btree_au_internal_inorder_walk_from_largest_get_next_smallest_element( baue );
+ break;
+
+ case LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE:
+ lfds700_btree_au_internal_inorder_walk_from_smallest_get_next_largest_element( baue );
+ break;
+ }
+
+ if( *baue == NULL )
+ rv = 0;
+
+ return( rv );
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_btree_au_internal_inorder_walk_from_largest_get_next_smallest_element( struct lfds700_btree_au_element **baue )
+{
+ enum lfds700_btree_au_move
+ action = LFDS700_BTREE_AU_MOVE_INVALID;
+
+ enum lfds700_misc_flag
+ finished_flag = LFDS700_MISC_FLAG_LOWERED,
+ load_finished_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ struct lfds700_btree_au_element
+ *left = NULL,
+ *right = NULL,
+ *up = NULL,
+ *up_left = NULL,
+ *up_right = NULL;
+
+ LFDS700_PAL_ASSERT( baue != NULL );
+
+ /* TRD : from any given element, the next smallest element is;
+ 1. if we have a left, it's the largest element on the right branch of our left child
+ 2. if we don't have a left, and we're on the right of our parent, then it's our parent
+ 3. if we don't have a left, and we're on the left of our parent or we have no parent,
+ iterative up the tree until we find the first child who is on the right of its parent; then it's the parent
+ */
+
+ /* TRD : we need to ensure the variables we use to decide our action are self-consistent
+ to do this, we make local copies of them all
+ then, if they are all not NULL, we can know they cannot change and we can continue
+ if however any of them are NULL, they could have changed while we were reading
+ and so our variables could be non-self-consistent
+ to check for this, we issue another processor read barrier
+ and then compare our local variables with the values in the tree
+ if they all match, then we know our variable set is self-consistent
+ (even though it may now be wrong - but we will discover this when we try the atomic operation)
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ while( load_finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ left = (*baue)->left;
+ right = (*baue)->right;
+ up = (*baue)->up;
+ if( up != NULL )
+ {
+ up_left = (*baue)->up->left;
+ up_right = (*baue)->up->right;
+ }
+
+ if( left != NULL and right != NULL and (up == NULL or (up != NULL and up_left != NULL and up_right != NULL)) )
+ break;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( left == (*baue)->left and right == (*baue)->right and (up == NULL or (up != NULL and up == (*baue)->up and up_left == (*baue)->up->left and up_right == (*baue)->up->right)) )
+ load_finished_flag = LFDS700_MISC_FLAG_RAISED;
+ }
+
+ if( left != NULL )
+ action = LFDS700_BTREE_AU_MOVE_LARGEST_FROM_LEFT_CHILD;
+
+ if( left == NULL and up != NULL and up_right == *baue )
+ action = LFDS700_BTREE_AU_MOVE_GET_PARENT;
+
+ if( (left == NULL and up == NULL) or (up != NULL and up_left == *baue and left == NULL) )
+ action = LFDS700_BTREE_AU_MOVE_MOVE_UP_TREE;
+
+ switch( action )
+ {
+ case LFDS700_BTREE_AU_MOVE_INVALID:
+ case LFDS700_BTREE_AU_MOVE_SMALLEST_FROM_RIGHT_CHILD:
+ // TRD : eliminates a compiler warning
+ break;
+
+ case LFDS700_BTREE_AU_MOVE_LARGEST_FROM_LEFT_CHILD:
+ *baue = left;
+ if( *baue != NULL )
+ {
+ LFDS700_MISC_BARRIER_LOAD;
+ while( (*baue)->right != NULL )
+ {
+ *baue = (*baue)->right;
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+ }
+ break;
+
+ case LFDS700_BTREE_AU_MOVE_GET_PARENT:
+ *baue = up;
+ break;
+
+ case LFDS700_BTREE_AU_MOVE_MOVE_UP_TREE:
+ while( finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ load_finished_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ while( load_finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ up = (*baue)->up;
+ if( up != NULL )
+ up_left = (*baue)->up->left;
+
+ if( up == NULL or (up != NULL and up_left != NULL) )
+ break;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( up == (*baue)->up and up_left == (*baue)->up->left )
+ load_finished_flag = LFDS700_MISC_FLAG_RAISED;
+ }
+
+ if( *baue != NULL and up != NULL and *baue == up_left )
+ *baue = up;
+ else
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ }
+
+ *baue = up;
+
+ /*
+
+ while( *baue != NULL and (*baue)->up != NULL and *baue == (*baue)->up->left )
+ *baue = (*baue)->up;
+
+ *baue = (*baue)->up;
+
+ */
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_btree_au_internal_inorder_walk_from_smallest_get_next_largest_element( struct lfds700_btree_au_element **baue )
+{
+ enum lfds700_btree_au_move
+ action = LFDS700_BTREE_AU_MOVE_INVALID;
+
+ enum lfds700_misc_flag
+ finished_flag = LFDS700_MISC_FLAG_LOWERED,
+ load_finished_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ struct lfds700_btree_au_element
+ *left = NULL,
+ *right = NULL,
+ *up = NULL,
+ *up_left = NULL,
+ *up_right = NULL;
+
+ LFDS700_PAL_ASSERT( baue != NULL );
+
+ /* TRD : from any given element, the next largest element is;
+ 1. if we have a right, it's the smallest element on the left branch of our right child
+ 2. if we don't have a right, and we're on the left of our parent, then it's our parent
+ 3. if we don't have a right, and we're on the right of our parent or we have no parent,
+ iterate up the tree until we find the first child who is on the left of its parent; then it's the parent
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ while( load_finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ left = (*baue)->left;
+ right = (*baue)->right;
+ up = (*baue)->up;
+ if( up != NULL )
+ {
+ up_left = (*baue)->up->left;
+ up_right = (*baue)->up->right;
+ }
+
+ if( left != NULL and right != NULL and (up == NULL or (up != NULL and up_left != NULL and up_right != NULL)) )
+ break;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( left == (*baue)->left and right == (*baue)->right and (up == NULL or (up != NULL and up == (*baue)->up and up_left == (*baue)->up->left and up_right == (*baue)->up->right)) )
+ load_finished_flag = LFDS700_MISC_FLAG_RAISED;
+ }
+
+ if( right != NULL )
+ action = LFDS700_BTREE_AU_MOVE_SMALLEST_FROM_RIGHT_CHILD;
+
+ if( right == NULL and up != NULL and up_left == *baue )
+ action = LFDS700_BTREE_AU_MOVE_GET_PARENT;
+
+ if( (right == NULL and up == NULL) or (up != NULL and up_right == *baue and right == NULL) )
+ action = LFDS700_BTREE_AU_MOVE_MOVE_UP_TREE;
+
+ switch( action )
+ {
+ case LFDS700_BTREE_AU_MOVE_INVALID:
+ case LFDS700_BTREE_AU_MOVE_LARGEST_FROM_LEFT_CHILD:
+ // TRD : remove compiler warning
+ break;
+
+ case LFDS700_BTREE_AU_MOVE_SMALLEST_FROM_RIGHT_CHILD:
+ *baue = right;
+ if( *baue != NULL )
+ {
+ LFDS700_MISC_BARRIER_LOAD;
+ while( (*baue)->left != NULL )
+ {
+ *baue = (*baue)->left;
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+ }
+ break;
+
+ case LFDS700_BTREE_AU_MOVE_GET_PARENT:
+ *baue = up;
+ break;
+
+ case LFDS700_BTREE_AU_MOVE_MOVE_UP_TREE:
+ while( finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ load_finished_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ while( load_finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ up = (*baue)->up;
+ if( up != NULL )
+ up_right = (*baue)->up->right;
+
+ if( up == NULL or (up != NULL and up_right != NULL) )
+ break;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( up == (*baue)->up and up_right == (*baue)->up->right )
+ load_finished_flag = LFDS700_MISC_FLAG_RAISED;
+ }
+
+ if( *baue != NULL and up != NULL and *baue == up_right )
+ *baue = up;
+ else
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ }
+
+ *baue = up;
+
+ /*
+
+ while( *baue != NULL and (*baue)->up != NULL and *baue == (*baue)->up->right )
+ *baue = (*baue)->up;
+
+ *baue = (*baue)->up;
+
+ */
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+int lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position( struct lfds700_btree_au_state *baus, struct lfds700_btree_au_element **baue, enum lfds700_btree_au_absolute_position absolute_position, enum lfds700_btree_au_relative_position relative_position )
+{
+ int
+ rv;
+
+ LFDS700_PAL_ASSERT( baus != NULL );
+ LFDS700_PAL_ASSERT( baue != NULL );
+ // TRD: absolute_position can be any value in its range
+ // TRD: relative_position can be any value in its range
+
+ if( *baue == NULL )
+ rv = lfds700_btree_au_get_by_absolute_position( baus, baue, absolute_position );
+ else
+ rv = lfds700_btree_au_get_by_relative_position( baue, relative_position );
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_init.c
new file mode 100644
index 0000000000..7dd0efd6c0
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_init.c
@@ -0,0 +1,32 @@
+/***** includes *****/
+#include "lfds700_btree_addonly_unbalanced_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_btree_au_init_valid_on_current_logical_core( struct lfds700_btree_au_state *baus,
+ int (*key_compare_function)(void const *new_key, void const *existing_key),
+ enum lfds700_btree_au_existing_key existing_key,
+ void *user_state )
+{
+ LFDS700_PAL_ASSERT( baus != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &baus->root % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &baus->key_compare_function % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( key_compare_function != NULL );
+ // TRD : existing_key can be any value in its range
+ // TRD : user_state can be NULL
+
+ baus->root = NULL;
+ baus->key_compare_function = key_compare_function;
+ baus->existing_key = existing_key;
+ baus->user_state = user_state;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_insert.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_insert.c
new file mode 100644
index 0000000000..8808177a4c
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_insert.c
@@ -0,0 +1,156 @@
+/***** includes *****/
+#include "lfds700_btree_addonly_unbalanced_internal.h"
+
+
+
+
+
+/****************************************************************************/
+enum lfds700_btree_au_insert_result lfds700_btree_au_insert( struct lfds700_btree_au_state *baus,
+ struct lfds700_btree_au_element *baue,
+ struct lfds700_btree_au_element **existing_baue,
+ struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result = 0;
+
+ int
+ compare_result = 0;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_btree_au_element
+ *volatile compare = NULL,
+ *volatile baue_next = NULL,
+ *volatile baue_parent = NULL,
+ *volatile baue_temp;
+
+ LFDS700_PAL_ASSERT( baus != NULL );
+ LFDS700_PAL_ASSERT( baue != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &baue->left % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &baue->right % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &baue->up % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &baue->value % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &baue->key % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ // TRD : existing_baue can be NULL
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ /* TRD : we follow a normal search for the insert node and which side to insert
+
+ the difference is that insertion may fail because someone else inserts
+ there before we do
+
+ in this case, we resume searching for the insert node from the node
+ we were attempting to insert upon
+
+ (if we attempted to insert the root node and this failed, i.e. we thought
+ the tree was empty but then it wasn't, then we start searching from the
+ new root)
+ */
+
+ baue->up = baue->left = baue->right = NULL;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ baue_temp = baus->root;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ while( result == 0 )
+ {
+ // TRD : first we find where to insert
+ while( baue_temp != NULL )
+ {
+ compare_result = baus->key_compare_function( baue->key, baue_temp->key );
+
+ if( compare_result == 0 )
+ {
+ if( existing_baue != NULL )
+ *existing_baue = baue_temp;
+
+ switch( baus->existing_key )
+ {
+ case LFDS700_BTREE_AU_EXISTING_KEY_OVERWRITE:
+ LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( *baue_temp, baue->value );
+ return( LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS_OVERWRITE );
+ break;
+
+ case LFDS700_BTREE_AU_EXISTING_KEY_FAIL:
+ return( LFDS700_BTREE_AU_INSERT_RESULT_FAILURE_EXISTING_KEY );
+ break;
+ }
+ }
+
+ if( compare_result < 0 )
+ baue_next = baue_temp->left;
+
+ if( compare_result > 0 )
+ baue_next = baue_temp->right;
+
+ baue_parent = baue_temp;
+ baue_temp = baue_next;
+ if( baue_temp != NULL )
+ LFDS700_MISC_BARRIER_LOAD;
+ }
+
+ /* TRD : second, we actually insert
+
+ at this point baue_temp has come to NULL
+ and baue_parent is the element to insert at
+ and result of the last compare indicates
+ the direction of insertion
+
+ it may be that another tree has already inserted an element with
+ the same key as ourselves, or other elements which mean our position
+ is now wrong
+
+ in this case, it is either inserted in the position we're trying
+ to insert in now, in which case our insert will fail
+
+ or, similarly, other elements will have come in where we are,
+ and our insert will fail
+ */
+
+ if( baue_parent == NULL )
+ {
+ compare = NULL;
+ baue->up = baus->root;
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_CAS_WITH_BACKOFF( &baus->root, &compare, baue, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+
+ if( result == 0 )
+ baue_temp = baus->root;
+ }
+
+ if( baue_parent != NULL )
+ {
+ if( compare_result <= 0 )
+ {
+ compare = NULL;
+ baue->up = baue_parent;
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_CAS_WITH_BACKOFF( &baue_parent->left, &compare, baue, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+ }
+
+ if( compare_result > 0 )
+ {
+ compare = NULL;
+ baue->up = baue_parent;
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_CAS_WITH_BACKOFF( &baue_parent->right, &compare, baue, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+ }
+
+ // TRD : if the insert fails, resume searching at the insert node
+ if( result == 0 )
+ baue_temp = baue_parent;
+ }
+ }
+
+ // TRD : if we get to here, we added (not failed or overwrite on exist) a new element
+ if( existing_baue != NULL )
+ *existing_baue = NULL;
+
+ return( LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_internal.h
new file mode 100644
index 0000000000..54149bac99
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_internal.h
@@ -0,0 +1,23 @@
+/***** the library-wide header file *****/
+#include "../liblfds700_internal.h"
+
+/***** enums *****/
+enum lfds700_btree_au_move
+{
+ LFDS700_BTREE_AU_MOVE_INVALID,
+ LFDS700_BTREE_AU_MOVE_SMALLEST_FROM_RIGHT_CHILD,
+ LFDS700_BTREE_AU_MOVE_LARGEST_FROM_LEFT_CHILD,
+ LFDS700_BTREE_AU_MOVE_GET_PARENT,
+ LFDS700_BTREE_AU_MOVE_MOVE_UP_TREE
+};
+
+enum lfds700_btree_au_delete_action
+{
+ LFDS700_BTREE_AU_DELETE_SELF,
+ LFDS700_BTREE_AU_DELETE_SELF_REPLACE_WITH_LEFT_CHILD,
+ LFDS700_BTREE_AU_DELETE_SELF_REPLACE_WITH_RIGHT_CHILD,
+ LFDS700_BTREE_AU_DELETE_MOVE_LEFT
+};
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_query.c
new file mode 100644
index 0000000000..dce9587929
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_btree_addonly_unbalanced/lfds700_btree_addonly_unbalanced_query.c
@@ -0,0 +1,121 @@
+/***** includes *****/
+#include "lfds700_btree_addonly_unbalanced_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_btree_au_internal_validate( struct lfds700_btree_au_state *abs, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_btree_au_validity );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_btree_au_query( struct lfds700_btree_au_state *baus, enum lfds700_btree_au_query query_type, void *query_input, void *query_output )
+{
+ LFDS700_PAL_ASSERT( baus != NULL );
+ // TRD : query_type can be any value in its range
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ switch( query_type )
+ {
+ case LFDS700_BTREE_AU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT:
+ {
+ struct lfds700_btree_au_element
+ *baue = NULL;
+
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ *(lfds700_pal_uint_t *) query_output = 0;
+
+ while( lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position(baus, &baue, LFDS700_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
+ ( *(lfds700_pal_uint_t *) query_output )++;
+ }
+ break;
+
+ case LFDS700_BTREE_AU_QUERY_SINGLETHREADED_VALIDATE:
+ // TRD : query_input can be NULL
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_btree_au_internal_validate( baus, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_btree_au_internal_validate( struct lfds700_btree_au_state *baus, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_btree_au_validity )
+{
+ lfds700_pal_uint_t
+ number_elements_from_query_tree = 0,
+ number_elements_from_walk = 0;
+
+ struct lfds700_btree_au_element
+ *baue = NULL,
+ *baue_prev = NULL;
+
+ LFDS700_PAL_ASSERT( baus!= NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_btree_au_validity != NULL );
+
+ *lfds700_btree_au_validity = LFDS700_MISC_VALIDITY_VALID;
+
+ /* TRD : validation is performed by;
+
+ performing an in-order walk
+ we should see every element is larger than the preceeding element
+ we count elements as we go along (visited elements, that is)
+ and check our tally equals the expected count
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ while( lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position(baus, &baue, LFDS700_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
+ {
+ // TRD : baue_prev should always be smaller than or equal to baue
+ if( baue_prev != NULL )
+ if( baus->key_compare_function(baue_prev->key, baue->key) > 0 )
+ {
+ *lfds700_btree_au_validity = LFDS700_MISC_VALIDITY_INVALID_ORDER;
+ return;
+ }
+
+ baue_prev = baue;
+ number_elements_from_walk++;
+ }
+
+ if( *lfds700_btree_au_validity == LFDS700_MISC_VALIDITY_VALID )
+ {
+ lfds700_btree_au_query( (struct lfds700_btree_au_state *) baus, LFDS700_BTREE_AU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, &number_elements_from_query_tree );
+
+ if( number_elements_from_walk > number_elements_from_query_tree )
+ *lfds700_btree_au_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( number_elements_from_walk < number_elements_from_query_tree )
+ *lfds700_btree_au_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+ }
+
+ /* TRD : now check for expected number of elements
+ vi can be NULL, in which case we do not check
+ we know we don't have a loop from our earlier check
+ */
+
+ if( *lfds700_btree_au_validity == LFDS700_MISC_VALIDITY_VALID and vi != NULL )
+ {
+ lfds700_btree_au_query( (struct lfds700_btree_au_state *) baus, LFDS700_BTREE_AU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, &number_elements_from_query_tree );
+
+ if( number_elements_from_query_tree < vi->min_elements )
+ *lfds700_btree_au_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( number_elements_from_query_tree > vi->max_elements )
+ *lfds700_btree_au_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_cleanup.c
new file mode 100644
index 0000000000..f7a088a39a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_cleanup.c
@@ -0,0 +1,36 @@
+/***** includes *****/
+#include "lfds700_freelist_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_freelist_cleanup( struct lfds700_freelist_state *fs,
+ void (*element_cleanup_callback)(struct lfds700_freelist_state *fs, struct lfds700_freelist_element *fe) )
+{
+ struct lfds700_freelist_element
+ *fe,
+ *fe_temp;
+
+ LFDS700_PAL_ASSERT( fs != NULL );
+ // TRD : element_cleanup_callback can be NULL
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( element_cleanup_callback != NULL )
+ {
+ fe = fs->top[POINTER];
+
+ while( fe != NULL )
+ {
+ fe_temp = fe;
+ fe = fe->next;
+
+ element_cleanup_callback( fs, fe_temp );
+ }
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_init.c
new file mode 100644
index 0000000000..fcacd1b32f
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_init.c
@@ -0,0 +1,27 @@
+/***** includes *****/
+#include "lfds700_freelist_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_freelist_init_valid_on_current_logical_core( struct lfds700_freelist_state *fs, void *user_state )
+{
+ LFDS700_PAL_ASSERT( fs != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) fs->top % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &fs->user_state % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ // TRD : user_state can be NULL
+
+ fs->top[POINTER] = NULL;
+ fs->top[COUNTER] = 0;
+
+ fs->user_state = user_state;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_internal.h
new file mode 100644
index 0000000000..7a7d541804
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_internal.h
@@ -0,0 +1,5 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_pop.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_pop.c
new file mode 100644
index 0000000000..c0a3545d91
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_pop.c
@@ -0,0 +1,52 @@
+/***** includes *****/
+#include "lfds700_freelist_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_freelist_pop( struct lfds700_freelist_state *fs, struct lfds700_freelist_element **fe, struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_freelist_element LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_DOUBLE_POINTER)
+ *new_top[PAC_SIZE],
+ *volatile original_top[PAC_SIZE];
+
+ LFDS700_PAL_ASSERT( fs != NULL );
+ LFDS700_PAL_ASSERT( fe != NULL );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ LFDS700_PAL_BARRIER_PROCESSOR_LOAD;
+
+ original_top[COUNTER] = fs->top[COUNTER];
+ original_top[POINTER] = fs->top[POINTER];
+
+ do
+ {
+ if( original_top[POINTER] == NULL )
+ {
+ *fe = NULL;
+ return( 0 );
+ }
+
+ new_top[COUNTER] = original_top[COUNTER] + 1;
+ new_top[POINTER] = original_top[POINTER]->next;
+
+ LFDS700_PAL_ATOMIC_DWCAS_WITH_BACKOFF( &fs->top, original_top, new_top, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+
+ if( result != 1 )
+ LFDS700_PAL_BARRIER_PROCESSOR_LOAD;
+ }
+ while( result != 1 );
+
+ *fe = original_top[POINTER];
+
+ return( 1 );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_push.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_push.c
new file mode 100644
index 0000000000..67fe38dadb
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_push.c
@@ -0,0 +1,42 @@
+/***** includes *****/
+#include "lfds700_freelist_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_freelist_push( struct lfds700_freelist_state *fs, struct lfds700_freelist_element *fe, struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_freelist_element LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_DOUBLE_POINTER)
+ *new_top[PAC_SIZE],
+ *volatile original_top[PAC_SIZE];
+
+ LFDS700_PAL_ASSERT( fs != NULL );
+ LFDS700_PAL_ASSERT( fe != NULL );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ new_top[POINTER] = fe;
+
+ original_top[COUNTER] = fs->top[COUNTER];
+ original_top[POINTER] = fs->top[POINTER];
+
+ do
+ {
+ new_top[COUNTER] = original_top[COUNTER] + 1;
+ fe->next = original_top[POINTER];
+
+ LFDS700_PAL_BARRIER_PROCESSOR_STORE;
+ LFDS700_PAL_ATOMIC_DWCAS_WITH_BACKOFF( &fs->top, original_top, new_top, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+ }
+ while( result != 1 );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_query.c
new file mode 100644
index 0000000000..43b8bc263d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_freelist/lfds700_freelist_query.c
@@ -0,0 +1,123 @@
+/***** includes *****/
+#include "lfds700_freelist_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_freelist_internal_freelist_validate( struct lfds700_freelist_state *fs, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_freelist_validity );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_freelist_query( struct lfds700_freelist_state *fs, enum lfds700_freelist_query query_type, void *query_input, void *query_output )
+{
+ struct lfds700_freelist_element
+ *fe;
+
+ LFDS700_PAL_ASSERT( fs != NULL );
+ // TRD : query_type can be any value in its range
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ switch( query_type )
+ {
+ case LFDS700_FREELIST_QUERY_SINGLETHREADED_GET_COUNT:
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ *(lfds700_pal_uint_t *) query_output = 0;
+
+ fe = (struct lfds700_freelist_element *) fs->top[POINTER];
+
+ while( fe != NULL )
+ {
+ ( *(lfds700_pal_uint_t *) query_output )++;
+ fe = (struct lfds700_freelist_element *) fe->next;
+ }
+ break;
+
+ case LFDS700_FREELIST_QUERY_SINGLETHREADED_VALIDATE:
+ // TRD : query_input can be NULL
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_freelist_internal_freelist_validate( fs, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_freelist_internal_freelist_validate( struct lfds700_freelist_state *fs, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_freelist_validity )
+{
+ lfds700_pal_uint_t
+ number_elements = 0;
+
+ struct lfds700_freelist_element
+ *fe_slow,
+ *fe_fast;
+
+ LFDS700_PAL_ASSERT( fs != NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_freelist_validity != NULL );
+
+ *lfds700_freelist_validity = LFDS700_MISC_VALIDITY_VALID;
+
+ fe_slow = fe_fast = (struct lfds700_freelist_element *) fs->top[POINTER];
+
+ /* TRD : first, check for a loop
+ we have two pointers
+ both of which start at the top of the freelist
+ we enter a loop
+ and on each iteration
+ we advance one pointer by one element
+ and the other by two
+
+ we exit the loop when both pointers are NULL
+ (have reached the end of the freelist)
+
+ or
+
+ if we fast pointer 'sees' the slow pointer
+ which means we have a loop
+ */
+
+ if( fe_slow != NULL )
+ do
+ {
+ fe_slow = fe_slow->next;
+
+ if( fe_fast != NULL )
+ fe_fast = fe_fast->next;
+
+ if( fe_fast != NULL )
+ fe_fast = fe_fast->next;
+ }
+ while( fe_slow != NULL and fe_fast != fe_slow );
+
+ if( fe_fast != NULL and fe_slow != NULL and fe_fast == fe_slow )
+ *lfds700_freelist_validity = LFDS700_MISC_VALIDITY_INVALID_LOOP;
+
+ /* TRD : now check for expected number of elements
+ vi can be NULL, in which case we do not check
+ we know we don't have a loop from our earlier check
+ */
+
+ if( *lfds700_freelist_validity == LFDS700_MISC_VALIDITY_VALID and vi != NULL )
+ {
+ lfds700_freelist_query( fs, LFDS700_FREELIST_QUERY_SINGLETHREADED_GET_COUNT, NULL, (void *) &number_elements );
+
+ if( number_elements < vi->min_elements )
+ *lfds700_freelist_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( number_elements > vi->max_elements )
+ *lfds700_freelist_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.c
new file mode 100644
index 0000000000..af88b19179
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_cleanup.c
@@ -0,0 +1,61 @@
+/***** includes *****/
+#include "lfds700_hash_addonly_internal.h"
+
+/***** private prototypes*****/
+static void btree_au_element_cleanup_function( struct lfds700_btree_au_state *baus, struct lfds700_btree_au_element *baue );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_hash_a_cleanup( struct lfds700_hash_a_state *has,
+ void (*element_cleanup_callback)(struct lfds700_hash_a_state *has, struct lfds700_hash_a_element *hae) )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ LFDS700_PAL_ASSERT( has != NULL );
+ // TRD : element_cleanup_callback can be NULL
+
+ if( element_cleanup_callback == NULL )
+ return;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ has->element_cleanup_callback = element_cleanup_callback;
+
+ for( loop = 0 ; loop < has->array_size ; loop++ )
+ lfds700_btree_au_cleanup( has->baus_array+loop, btree_au_element_cleanup_function );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void btree_au_element_cleanup_function( struct lfds700_btree_au_state *baus, struct lfds700_btree_au_element *baue )
+{
+ struct lfds700_hash_a_state
+ *has;
+
+ struct lfds700_hash_a_element
+ *hae;
+
+ LFDS700_PAL_ASSERT( baus != NULL );
+ LFDS700_PAL_ASSERT( baue != NULL );
+
+ hae = (struct lfds700_hash_a_element *) LFDS700_BTREE_AU_GET_VALUE_FROM_ELEMENT( *baue );
+ has = (struct lfds700_hash_a_state *) LFDS700_BTREE_AU_GET_USER_STATE_FROM_STATE( *baus );
+
+ has->element_cleanup_callback( has, hae );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_get.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_get.c
new file mode 100644
index 0000000000..8d010664ab
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_get.c
@@ -0,0 +1,37 @@
+/***** includes *****/
+#include "lfds700_hash_addonly_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_hash_a_get_by_key( struct lfds700_hash_a_state *has,
+ void *key,
+ struct lfds700_hash_a_element **hae )
+{
+ int
+ rv;
+
+ lfds700_pal_uint_t
+ hash = 0;
+
+ struct lfds700_btree_au_element
+ *baue;
+
+ LFDS700_PAL_ASSERT( has != NULL );
+ // TRD : key can be NULL
+ LFDS700_PAL_ASSERT( hae != NULL );
+
+ has->key_hash_function( key, &hash );
+
+ rv = lfds700_btree_au_get_by_key( has->baus_array + (hash % has->array_size), key, &baue );
+
+ if( rv == 1 )
+ *hae = LFDS700_BTREE_AU_GET_VALUE_FROM_ELEMENT( *baue );
+ else
+ *hae = NULL;
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_init.c
new file mode 100644
index 0000000000..022024ce27
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_init.c
@@ -0,0 +1,54 @@
+/***** includes *****/
+#include "lfds700_hash_addonly_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_hash_a_init_valid_on_current_logical_core( struct lfds700_hash_a_state *has,
+ struct lfds700_btree_au_state *baus_array,
+ lfds700_pal_uint_t array_size,
+ int (*key_compare_function)(void const *new_key, void const *existing_key),
+ void (*key_hash_function)(void const *key, lfds700_pal_uint_t *hash),
+ enum lfds700_hash_a_existing_key existing_key,
+ void *user_state )
+{
+ enum lfds700_btree_au_existing_key
+ btree_au_existing_key = LFDS700_BTREE_AU_EXISTING_KEY_OVERWRITE; // TRD : for compiler warning
+
+ lfds700_pal_uint_t
+ loop;
+
+ LFDS700_PAL_ASSERT( has != NULL );
+ LFDS700_PAL_ASSERT( baus_array != NULL );
+ LFDS700_PAL_ASSERT( array_size > 0 );
+ LFDS700_PAL_ASSERT( key_compare_function != NULL );
+ LFDS700_PAL_ASSERT( key_hash_function != NULL );
+ // TRD : existing_key can be any value in its range
+ // TRD : user_state can be NULL
+
+ has->array_size = array_size;
+ has->key_compare_function = key_compare_function;
+ has->key_hash_function = key_hash_function;
+ has->existing_key = existing_key;
+ has->baus_array = baus_array;
+ has->user_state = user_state;
+
+ if( has->existing_key == LFDS700_HASH_A_EXISTING_KEY_OVERWRITE )
+ btree_au_existing_key = LFDS700_BTREE_AU_EXISTING_KEY_OVERWRITE;
+
+ if( has->existing_key == LFDS700_HASH_A_EXISTING_KEY_FAIL )
+ btree_au_existing_key = LFDS700_BTREE_AU_EXISTING_KEY_FAIL;
+
+ // TRD : since the addonly_hash atomic counts, if that flag is set, the btree_addonly_unbalanceds don't have to
+ for( loop = 0 ; loop < array_size ; loop++ )
+ lfds700_btree_au_init_valid_on_current_logical_core( has->baus_array+loop, key_compare_function, btree_au_existing_key, user_state );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_insert.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_insert.c
new file mode 100644
index 0000000000..25df3e7f93
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_insert.c
@@ -0,0 +1,62 @@
+/***** includes *****/
+#include "lfds700_hash_addonly_internal.h"
+
+
+
+
+
+/****************************************************************************/
+enum lfds700_hash_a_insert_result lfds700_hash_a_insert( struct lfds700_hash_a_state *has,
+ struct lfds700_hash_a_element *hae,
+ struct lfds700_hash_a_element **existing_hae,
+ struct lfds700_misc_prng_state *ps )
+{
+ enum lfds700_hash_a_insert_result
+ apr = LFDS700_HASH_A_PUT_RESULT_SUCCESS;
+
+ enum lfds700_btree_au_insert_result
+ alr;
+
+ lfds700_pal_uint_t
+ hash = 0;
+
+ struct lfds700_btree_au_element
+ *existing_baue;
+
+ LFDS700_PAL_ASSERT( has != NULL );
+ LFDS700_PAL_ASSERT( hae != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &hae->value % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ // TRD : existing_hae can be NULL
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ // TRD : alignment checks
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &hae->baue % LFDS700_PAL_ALIGN_SINGLE_POINTER == 0 );
+
+ has->key_hash_function( hae->key, &hash );
+
+ LFDS700_BTREE_AU_SET_KEY_IN_ELEMENT( hae->baue, hae->key );
+ LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( hae->baue, hae );
+
+ alr = lfds700_btree_au_insert( has->baus_array + (hash % has->array_size), &hae->baue, &existing_baue, ps );
+
+ switch( alr )
+ {
+ case LFDS700_BTREE_AU_INSERT_RESULT_FAILURE_EXISTING_KEY:
+ if( existing_hae != NULL )
+ *existing_hae = LFDS700_BTREE_AU_GET_VALUE_FROM_ELEMENT( *existing_baue );
+
+ apr = LFDS700_HASH_A_PUT_RESULT_FAILURE_EXISTING_KEY;
+ break;
+
+ case LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS_OVERWRITE:
+ apr = LFDS700_HASH_A_PUT_RESULT_SUCCESS_OVERWRITE;
+ break;
+
+ case LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS:
+ apr = LFDS700_HASH_A_PUT_RESULT_SUCCESS;
+ break;
+ }
+
+ return( apr );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_internal.h
new file mode 100644
index 0000000000..7a7d541804
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_internal.h
@@ -0,0 +1,5 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_iterate.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_iterate.c
new file mode 100644
index 0000000000..3e06be3f90
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_iterate.c
@@ -0,0 +1,58 @@
+/***** includes *****/
+#include "lfds700_hash_addonly_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_hash_a_iterate_init( struct lfds700_hash_a_state *has, struct lfds700_hash_a_iterate *hai )
+{
+ LFDS700_PAL_ASSERT( has != NULL );
+ LFDS700_PAL_ASSERT( hai != NULL );
+
+ hai->baus = has->baus_array;
+ hai->baus_end = has->baus_array + has->array_size;
+ hai->baue = NULL;
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+int lfds700_hash_a_iterate( struct lfds700_hash_a_iterate *hai, struct lfds700_hash_a_element **hae )
+{
+ enum lfds700_misc_flag
+ finished_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ int
+ rv = 0;
+
+ LFDS700_PAL_ASSERT( hai != NULL );
+ LFDS700_PAL_ASSERT( hae != NULL );
+
+ while( finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position( hai->baus, &hai->baue, LFDS700_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE );
+
+ if( hai->baue != NULL )
+ {
+ *hae = LFDS700_BTREE_AU_GET_VALUE_FROM_ELEMENT( *hai->baue );
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ rv = 1;
+ }
+
+ if( hai->baue == NULL )
+ if( ++hai->baus == hai->baus_end )
+ {
+ *hae = NULL;
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ }
+ }
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_query.c
new file mode 100644
index 0000000000..9d89a8838d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_hash_addonly/lfds700_hash_addonly_query.c
@@ -0,0 +1,112 @@
+/***** includes *****/
+#include "lfds700_hash_addonly_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_hash_a_internal_validate( struct lfds700_hash_a_state *has, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_hash_a_validity );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_hash_a_query( struct lfds700_hash_a_state *has, enum lfds700_hash_a_query query_type, void *query_input, void *query_output )
+{
+ LFDS700_PAL_ASSERT( has != NULL );
+ // TRD : query_type can be any value in its range
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ switch( query_type )
+ {
+ case LFDS700_HASH_A_QUERY_GET_POTENTIALLY_INACCURATE_COUNT:
+ {
+ struct lfds700_hash_a_iterate
+ ai;
+
+ struct lfds700_hash_a_element
+ *hae;
+
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ *(lfds700_pal_uint_t *) query_output = 0;
+
+ lfds700_hash_a_iterate_init( has, &ai );
+
+ while( lfds700_hash_a_iterate(&ai, &hae) )
+ ( *(lfds700_pal_uint_t *) query_output )++;
+ }
+ break;
+
+ case LFDS700_HASH_A_QUERY_SINGLETHREADED_VALIDATE:
+ // TRD: query_input can be any value in its range
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_hash_a_internal_validate( has, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_hash_a_internal_validate( struct lfds700_hash_a_state *has, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_hash_a_validity )
+{
+ lfds700_pal_uint_t
+ lfds700_hash_a_total_number_elements = 0,
+ lfds700_btree_au_total_number_elements = 0,
+ number_elements;
+
+ lfds700_pal_uint_t
+ loop;
+
+ LFDS700_PAL_ASSERT( has!= NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_hash_a_validity != NULL );
+
+ /* TRD : validate every btree_addonly_unbalanced in the addonly_hash
+ sum elements in each btree_addonly_unbalanced
+ check matches expected element counts (if vi is provided)
+ */
+
+ *lfds700_hash_a_validity = LFDS700_MISC_VALIDITY_VALID;
+
+ for( loop = 0 ; *lfds700_hash_a_validity == LFDS700_MISC_VALIDITY_VALID and loop < has->array_size ; loop++ )
+ lfds700_btree_au_query( has->baus_array+loop, LFDS700_BTREE_AU_QUERY_SINGLETHREADED_VALIDATE, NULL, (void *) lfds700_hash_a_validity );
+
+ if( *lfds700_hash_a_validity == LFDS700_MISC_VALIDITY_VALID )
+ {
+ for( loop = 0 ; loop < has->array_size ; loop++ )
+ {
+ lfds700_btree_au_query( has->baus_array+loop, LFDS700_BTREE_AU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void *) &number_elements );
+ lfds700_btree_au_total_number_elements += number_elements;
+ }
+
+ // TRD : first, check btree_addonly_unbalanced total vs the addonly_hash total
+ lfds700_hash_a_query( has, LFDS700_HASH_A_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, &lfds700_hash_a_total_number_elements );
+
+ // TRD : the btree_addonly_unbalanceds are assumed to speak the truth
+ if( lfds700_hash_a_total_number_elements < lfds700_btree_au_total_number_elements )
+ *lfds700_hash_a_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( lfds700_hash_a_total_number_elements > lfds700_btree_au_total_number_elements )
+ *lfds700_hash_a_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ // TRD : second, if we're still valid and vi is provided, check the btree_addonly_unbalanced total against vi
+ if( *lfds700_hash_a_validity == LFDS700_MISC_VALIDITY_VALID and vi != NULL )
+ {
+ if( lfds700_btree_au_total_number_elements < vi->min_elements )
+ *lfds700_hash_a_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( lfds700_btree_au_total_number_elements > vi->max_elements )
+ *lfds700_hash_a_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+ }
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_cleanup.c
new file mode 100644
index 0000000000..580fa9b3ac
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_cleanup.c
@@ -0,0 +1,37 @@
+/***** includes *****/
+#include "lfds700_list_addonly_ordered_singlylinked_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_aos_cleanup( struct lfds700_list_aos_state *laoss,
+ void (*element_cleanup_callback)(struct lfds700_list_aos_state *laoss, struct lfds700_list_aos_element *laose) )
+{
+ struct lfds700_list_aos_element
+ *laose,
+ *temp;
+
+ LFDS700_PAL_ASSERT( laoss != NULL );
+ // TRD : element_cleanup_callback can be NULL
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( element_cleanup_callback == NULL )
+ return;
+
+ laose = LFDS700_LIST_AOS_GET_START( *laoss );
+
+ while( laose != NULL )
+ {
+ temp = laose;
+
+ laose = LFDS700_LIST_AOS_GET_NEXT( *laose );
+
+ element_cleanup_callback( laoss, temp );
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_get.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_get.c
new file mode 100644
index 0000000000..9d4cab5e53
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_get.c
@@ -0,0 +1,29 @@
+/***** includes *****/
+#include "lfds700_list_addonly_ordered_singlylinked_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_list_aos_get_by_key( struct lfds700_list_aos_state *laoss,
+ void *key,
+ struct lfds700_list_aos_element **laose )
+{
+ int
+ cr = !0,
+ rv = 1;
+
+ LFDS700_PAL_ASSERT( laoss != NULL );
+ LFDS700_PAL_ASSERT( key != NULL );
+ LFDS700_PAL_ASSERT( laose != NULL );
+
+ while( cr != 0 and LFDS700_LIST_AOS_GET_START_AND_THEN_NEXT(*laoss, *laose) )
+ cr = laoss->key_compare_function( key, (*laose)->key );
+
+ if( *laose == NULL )
+ rv = 0;
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_init.c
new file mode 100644
index 0000000000..4c92835ce5
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_init.c
@@ -0,0 +1,37 @@
+/***** includes *****/
+#include "lfds700_list_addonly_ordered_singlylinked_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_aos_init_valid_on_current_logical_core( struct lfds700_list_aos_state *laoss,
+ int (*key_compare_function)(void const *new_key, void const *existing_key),
+ enum lfds700_list_aos_existing_key existing_key,
+ void *user_state )
+{
+ LFDS700_PAL_ASSERT( laoss != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &laoss->start % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &laoss->dummy_element % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &laoss->key_compare_function % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( key_compare_function != NULL );
+ // TRD : existing_key can be any value in its range
+ // TRD : user_state can be NULL
+
+ // TRD : dummy start element - makes code easier when you can always use ->next
+ laoss->start = &laoss->dummy_element;
+
+ laoss->start->next = NULL;
+ laoss->start->value = NULL;
+ laoss->key_compare_function = key_compare_function;
+ laoss->existing_key = existing_key;
+ laoss->user_state = user_state;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_insert.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_insert.c
new file mode 100644
index 0000000000..9beead4e1d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_insert.c
@@ -0,0 +1,134 @@
+/***** includes *****/
+#include "lfds700_list_addonly_ordered_singlylinked_internal.h"
+
+
+
+
+
+/****************************************************************************/
+enum lfds700_list_aos_insert_result lfds700_list_aos_insert( struct lfds700_list_aos_state *laoss,
+ struct lfds700_list_aos_element *laose,
+ struct lfds700_list_aos_element **existing_laose,
+ struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result;
+
+ enum lfds700_misc_flag
+ finished_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ int
+ compare_result = 0;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_list_aos_element
+ *volatile laose_temp = NULL,
+ *volatile laose_trailing;
+
+ LFDS700_PAL_ASSERT( laoss != NULL );
+ LFDS700_PAL_ASSERT( laose != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &laose->next % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &laose->value % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &laose->key % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ // TRD : existing_laose can be NULL
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ /* TRD : imagine a list, sorted small to large
+
+ we arrive at an element
+ we obtain its next pointer
+ we check we are greater than the current element and smaller than the next element
+ this means we have found the correct location to insert
+ we try to CAS ourselves in; in the meantime,
+ someone else has *aready* swapped in an element which is smaller than we are
+
+ e.g.
+
+ the list is { 1, 10 } and we are the value 5
+
+ we arrive at 1; we check the next element and see it is 10
+ so we are larger than the current element and smaller than the next
+ we are in the correct location to insert and we go to insert...
+
+ in the meantime, someone else with the value 3 comes along
+ he too finds this is the correct location and inserts before we do
+ the list is now { 1, 3, 10 } and we are trying to insert now after
+ 1 and before 3!
+
+ our insert CAS fails, because the next pointer of 1 has changed aready;
+ but we see we are in the wrong location - we need to move forward an
+ element
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ /* TRD : we need to begin with the leading dummy element
+ as the element to be inserted
+ may be smaller than all elements in the list
+ */
+
+ laose_trailing = laoss->start;
+ laose_temp = laoss->start->next;
+
+ while( finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ if( laose_temp == NULL )
+ compare_result = -1;
+
+ if( laose_temp != NULL )
+ {
+ LFDS700_MISC_BARRIER_LOAD;
+ compare_result = laoss->key_compare_function( laose->key, laose_temp->key );
+ }
+
+ if( compare_result == 0 )
+ {
+ if( existing_laose != NULL )
+ *existing_laose = laose_temp;
+
+ switch( laoss->existing_key )
+ {
+ case LFDS700_LIST_AOS_EXISTING_KEY_OVERWRITE:
+ LFDS700_LIST_AOS_SET_VALUE_IN_ELEMENT( *laose_temp, laose->value );
+ return( LFDS700_LIST_AOS_INSERT_RESULT_SUCCESS_OVERWRITE );
+ break;
+
+ case LFDS700_LIST_AOS_EXISTING_KEY_FAIL:
+ return( LFDS700_LIST_AOS_INSERT_RESULT_FAILURE_EXISTING_KEY );
+ break;
+ }
+
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ }
+
+ if( compare_result < 0 )
+ {
+ laose->next = laose_temp;
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_CAS_WITH_BACKOFF( &laose_trailing->next, &laose->next, laose, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+
+ if( result == 1 )
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ else
+ // TRD : if we fail to link, someone else has linked and so we need to redetermine our position is correct
+ laose_temp = laose_trailing->next;
+ }
+
+ if( compare_result > 0 )
+ {
+ // TRD : move trailing along by one element
+ laose_trailing = laose_trailing->next;
+
+ /* TRD : set temp as the element after trailing
+ if the new element we're linking is larger than all elements in the list,
+ laose_temp will now go to NULL and we'll link at the end
+ */
+ laose_temp = laose_trailing->next;
+ }
+ }
+
+ return( LFDS700_LIST_AOS_INSERT_RESULT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_internal.h
new file mode 100644
index 0000000000..7a7d541804
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_internal.h
@@ -0,0 +1,5 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_query.c
new file mode 100644
index 0000000000..a1d990ab79
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_ordered_singlylinked/lfds700_list_addonly_ordered_singlylinked_query.c
@@ -0,0 +1,121 @@
+/***** includes *****/
+#include "lfds700_list_addonly_ordered_singlylinked_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_list_aos_internal_validate( struct lfds700_list_aos_state *laoss, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_list_aos_validity );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_aos_query( struct lfds700_list_aos_state *laoss, enum lfds700_list_aos_query query_type, void *query_input, void *query_output )
+{
+ LFDS700_PAL_ASSERT( laoss != NULL );
+ // TRD : query_type can be any value in its range
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ switch( query_type )
+ {
+ case LFDS700_LIST_AOS_QUERY_GET_POTENTIALLY_INACCURATE_COUNT:
+ {
+ struct lfds700_list_aos_element
+ *laose = NULL;
+
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ *(lfds700_pal_uint_t *) query_output = 0;
+
+ while( LFDS700_LIST_AOS_GET_START_AND_THEN_NEXT(*laoss, laose) )
+ ( *(lfds700_pal_uint_t *) query_output )++;
+ }
+ break;
+
+ case LFDS700_LIST_AOS_QUERY_SINGLETHREADED_VALIDATE:
+ // TRD : query_input can be NULL
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_list_aos_internal_validate( laoss, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_list_aos_internal_validate( struct lfds700_list_aos_state *laoss, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_list_aos_validity )
+{
+ lfds700_pal_uint_t
+ number_elements = 0;
+
+ struct lfds700_list_aos_element
+ *laose_fast,
+ *laose_slow;
+
+ LFDS700_PAL_ASSERT( laoss!= NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_list_aos_validity != NULL );
+
+ *lfds700_list_aos_validity = LFDS700_MISC_VALIDITY_VALID;
+
+ laose_slow = laose_fast = laoss->start->next;
+
+ /* TRD : first, check for a loop
+ we have two pointers
+ both of which start at the start of the list
+ we enter a loop
+ and on each iteration
+ we advance one pointer by one element
+ and the other by two
+
+ we exit the loop when both pointers are NULL
+ (have reached the end of the queue)
+
+ or
+
+ if we fast pointer 'sees' the slow pointer
+ which means we have a loop
+ */
+
+ if( laose_slow != NULL )
+ do
+ {
+ laose_slow = laose_slow->next;
+
+ if( laose_fast != NULL )
+ laose_fast = laose_fast->next;
+
+ if( laose_fast != NULL )
+ laose_fast = laose_fast->next;
+ }
+ while( laose_slow != NULL and laose_fast != laose_slow );
+
+ if( laose_fast != NULL and laose_slow != NULL and laose_fast == laose_slow )
+ *lfds700_list_aos_validity = LFDS700_MISC_VALIDITY_INVALID_LOOP;
+
+ /* TRD : now check for expected number of elements
+ vi can be NULL, in which case we do not check
+ we know we don't have a loop from our earlier check
+ */
+
+ if( *lfds700_list_aos_validity == LFDS700_MISC_VALIDITY_VALID and vi != NULL )
+ {
+ lfds700_list_aos_query( laoss, LFDS700_LIST_AOS_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, &number_elements );
+
+ if( number_elements < vi->min_elements )
+ *lfds700_list_aos_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( number_elements > vi->max_elements )
+ *lfds700_list_aos_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_cleanup.c
new file mode 100644
index 0000000000..ef19ce1f86
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_cleanup.c
@@ -0,0 +1,37 @@
+/***** includes *****/
+#include "lfds700_list_addonly_singlylinked_unordered_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_asu_cleanup( struct lfds700_list_asu_state *lasus,
+ void (*element_cleanup_callback)(struct lfds700_list_asu_state *lasus, struct lfds700_list_asu_element *lasue) )
+{
+ struct lfds700_list_asu_element
+ *lasue,
+ *temp;
+
+ LFDS700_PAL_ASSERT( lasus != NULL );
+ // TRD : element_cleanup_callback can be NULL
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( element_cleanup_callback == NULL )
+ return;
+
+ lasue = LFDS700_LIST_ASU_GET_START( *lasus );
+
+ while( lasue != NULL )
+ {
+ temp = lasue;
+
+ lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
+
+ element_cleanup_callback( lasus, temp );
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_get.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_get.c
new file mode 100644
index 0000000000..ae99ebfca4
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_get.c
@@ -0,0 +1,29 @@
+/***** includes *****/
+#include "lfds700_list_addonly_singlylinked_unordered_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_list_asu_get_by_key( struct lfds700_list_asu_state *lasus,
+ void *key,
+ struct lfds700_list_asu_element **lasue )
+{
+ int
+ cr = !0,
+ rv = 1;
+
+ LFDS700_PAL_ASSERT( lasus != NULL );
+ LFDS700_PAL_ASSERT( key != NULL );
+ LFDS700_PAL_ASSERT( lasue != NULL );
+
+ while( cr != 0 and LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*lasus, *lasue) )
+ cr = lasus->key_compare_function( key, (*lasue)->key );
+
+ if( *lasue == NULL )
+ rv = 0;
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_init.c
new file mode 100644
index 0000000000..78b0d8eae6
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_init.c
@@ -0,0 +1,35 @@
+/***** includes *****/
+#include "lfds700_list_addonly_singlylinked_unordered_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_asu_init_valid_on_current_logical_core( struct lfds700_list_asu_state *lasus,
+ int (*key_compare_function)(void const *new_key, void const *existing_key),
+ void *user_state )
+{
+ LFDS700_PAL_ASSERT( lasus != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasus->end % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasus->start % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasus->dummy_element % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasus->key_compare_function % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ // TRD : key_compare_function can be NULL
+ // TRD : user_state can be NULL
+
+ // TRD : dummy start element - makes code easier when you can always use ->next
+ lasus->start = lasus->end = &lasus->dummy_element;
+
+ lasus->start->next = NULL;
+ lasus->start->value = NULL;
+ lasus->key_compare_function = key_compare_function;
+ lasus->user_state = user_state;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_insert.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_insert.c
new file mode 100644
index 0000000000..ce2ee825aa
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_insert.c
@@ -0,0 +1,193 @@
+/***** includes *****/
+#include "lfds700_list_addonly_singlylinked_unordered_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_asu_insert_at_position( struct lfds700_list_asu_state *lasus,
+ struct lfds700_list_asu_element *lasue,
+ struct lfds700_list_asu_element *lasue_predecessor,
+ enum lfds700_list_asu_position position,
+ struct lfds700_misc_prng_state *ps )
+{
+ LFDS700_PAL_ASSERT( lasus != NULL );
+ LFDS700_PAL_ASSERT( lasue != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->next % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->value % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->key % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ // TRD : lasue_predecessor asserted in the switch
+ // TRD : position can be any value in its range
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ switch( position )
+ {
+ case LFDS700_LIST_ASU_POSITION_START:
+ lfds700_list_asu_insert_at_start( lasus, lasue, ps );
+ break;
+
+ case LFDS700_LIST_ASU_POSITION_END:
+ lfds700_list_asu_insert_at_end( lasus, lasue, ps );
+ break;
+
+ case LFDS700_LIST_ASU_POSITION_AFTER:
+ lfds700_list_asu_insert_after_element( lasus, lasue, lasue_predecessor, ps );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_asu_insert_at_start( struct lfds700_list_asu_state *lasus,
+ struct lfds700_list_asu_element *lasue,
+ struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ LFDS700_PAL_ASSERT( lasus != NULL );
+ LFDS700_PAL_ASSERT( lasue != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->next % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->value % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->key % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lasue->next = lasus->start->next;
+
+ do
+ {
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_CAS_WITH_BACKOFF( &lasus->start->next, &lasue->next, lasue, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+ }
+ while( result != 1 );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_asu_insert_at_end( struct lfds700_list_asu_state *lasus,
+ struct lfds700_list_asu_element *lasue,
+ struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result;
+
+ enum lfds700_misc_flag
+ finished_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_list_asu_element LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_SINGLE_POINTER)
+ *compare;
+
+ struct lfds700_list_asu_element
+ *volatile lasue_next,
+ *volatile lasue_end;
+
+ LFDS700_PAL_ASSERT( lasus != NULL );
+ LFDS700_PAL_ASSERT( lasue != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->next % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->value % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->key % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ /* TRD : begin by assuming end is correctly pointing to the final element
+ try to link (comparing for next being NULL)
+ if we fail, move down list till we find last element
+ and retry
+ when successful, update end to ourselves
+
+ note there's a leading dummy element
+ so lasus->end always points to an element
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lasue->next = NULL;
+ lasue_end = lasus->end;
+
+ while( finished_flag == LFDS700_MISC_FLAG_LOWERED )
+ {
+ compare = NULL;
+
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_CAS_WITH_BACKOFF( &lasue_end->next, &compare, lasue, LFDS700_MISC_CAS_STRENGTH_STRONG, result, backoff_iteration, ps );
+
+ if( result == 1 )
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ else
+ {
+ lasue_end = compare;
+ lasue_next = LFDS700_LIST_ASU_GET_NEXT( *lasue_end );
+
+ while( lasue_next != NULL )
+ {
+ lasue_end = lasue_next;
+ lasue_next = LFDS700_LIST_ASU_GET_NEXT( *lasue_end );
+ }
+ }
+ }
+
+ lasus->end = lasue;
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+void lfds700_list_asu_insert_after_element( struct lfds700_list_asu_state *lasus,
+ struct lfds700_list_asu_element *lasue,
+ struct lfds700_list_asu_element *lasue_predecessor,
+ struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ LFDS700_PAL_ASSERT( lasus != NULL );
+ LFDS700_PAL_ASSERT( lasue != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->next % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->value % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &lasue->key % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( lasue_predecessor != NULL );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lasue->next = lasue_predecessor->next;
+
+ do
+ {
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_CAS_WITH_BACKOFF( &lasue_predecessor->next, &lasue->next, lasue, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+ }
+ while( result != 1 );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_internal.h
new file mode 100644
index 0000000000..7a7d541804
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_internal.h
@@ -0,0 +1,5 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_query.c
new file mode 100644
index 0000000000..0adf5a8032
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_list_addonly_singlylinked_unordered/lfds700_list_addonly_singlylinked_unordered_query.c
@@ -0,0 +1,121 @@
+/***** includes *****/
+#include "lfds700_list_addonly_singlylinked_unordered_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_list_asu_internal_validate( struct lfds700_list_asu_state *lasus, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_list_asu_validity );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_list_asu_query( struct lfds700_list_asu_state *lasus, enum lfds700_list_asu_query query_type, void *query_input, void *query_output )
+{
+ LFDS700_PAL_ASSERT( lasus != NULL );
+ // TRD : query_type can be any value in its range
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ switch( query_type )
+ {
+ case LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT:
+ {
+ struct lfds700_list_asu_element
+ *lasue = NULL;
+
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ *(lfds700_pal_uint_t *) query_output = 0;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*lasus, lasue) )
+ ( *(lfds700_pal_uint_t *) query_output )++;
+ }
+ break;
+
+ case LFDS700_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE:
+ // TRD : query_input can be NULL
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_list_asu_internal_validate( lasus, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_list_asu_internal_validate( struct lfds700_list_asu_state *lasus, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_list_asu_validity )
+{
+ lfds700_pal_uint_t
+ number_elements = 0;
+
+ struct lfds700_list_asu_element
+ *lasue_fast,
+ *lasue_slow;
+
+ LFDS700_PAL_ASSERT( lasus!= NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_list_asu_validity != NULL );
+
+ *lfds700_list_asu_validity = LFDS700_MISC_VALIDITY_VALID;
+
+ lasue_slow = lasue_fast = lasus->start->next;
+
+ /* TRD : first, check for a loop
+ we have two pointers
+ both of which start at the start of the list
+ we enter a loop
+ and on each iteration
+ we advance one pointer by one element
+ and the other by two
+
+ we exit the loop when both pointers are NULL
+ (have reached the end of the queue)
+
+ or
+
+ if we fast pointer 'sees' the slow pointer
+ which means we have a loop
+ */
+
+ if( lasue_slow != NULL )
+ do
+ {
+ lasue_slow = lasue_slow->next;
+
+ if( lasue_fast != NULL )
+ lasue_fast = lasue_fast->next;
+
+ if( lasue_fast != NULL )
+ lasue_fast = lasue_fast->next;
+ }
+ while( lasue_slow != NULL and lasue_fast != lasue_slow );
+
+ if( lasue_fast != NULL and lasue_slow != NULL and lasue_fast == lasue_slow )
+ *lfds700_list_asu_validity = LFDS700_MISC_VALIDITY_INVALID_LOOP;
+
+ /* TRD : now check for expected number of elements
+ vi can be NULL, in which case we do not check
+ we know we don't have a loop from our earlier check
+ */
+
+ if( *lfds700_list_asu_validity == LFDS700_MISC_VALIDITY_VALID and vi != NULL )
+ {
+ lfds700_list_asu_query( lasus, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, &number_elements );
+
+ if( number_elements < vi->min_elements )
+ *lfds700_list_asu_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( number_elements > vi->max_elements )
+ *lfds700_list_asu_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_cleanup.c
new file mode 100644
index 0000000000..d93c95db0f
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_cleanup.c
@@ -0,0 +1,15 @@
+/***** includes *****/
+#include "lfds700_misc_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_misc_library_cleanup( void )
+{
+ // TRD : we do nuuuuuuthin'
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_globals.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_globals.c
new file mode 100644
index 0000000000..af2826675a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_globals.c
@@ -0,0 +1,11 @@
+/***** includes *****/
+#include "lfds700_misc_internal.h"
+
+
+
+
+
+/****************************************************************************/
+struct lfds700_misc_globals
+ lfds700_misc_globals;
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_init.c
new file mode 100644
index 0000000000..32685077bf
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_init.c
@@ -0,0 +1,53 @@
+/***** includes *****/
+#include "lfds700_misc_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_misc_library_init_valid_on_current_logical_core()
+{
+ /* TRD : the PRNG arrangement is that each thread has its own state, for a maximum-speed PRNG, where output
+ quality is second consideration to performance
+
+ on 64-bit platforms this is xorshift64*, on 32-bit platforms, an unadorned xorshift32
+
+ the seed for each thread however comes from a single, global, maximum-quality PRNG, where quality of
+ output is the primary consideration
+
+ for this, I'm using a xorshift1024*
+
+ since the generation from this global PRNG state is not thread safe, but is still quick in
+ thread start-up terms, I run a little spin-lock around it
+
+ regarding the seed for this high quality PRNG; it is customary to use time(), but this has a number of
+ drawbacks;
+
+ 1. liblfds would depend on time() (currently it does not depend on a hosted implementation of standard library)
+ 2. the output from time may only be 32 bit, and even when it isn't, the top 32 bits are currently all zero...
+ 3. many threads can begin in the same second; I'd need to add in their thread number,
+ which means I'd need to *get* their thread number...
+
+ as such, I've decided to use a *fixed* 64-bit seed for the high-quality PRNG; this seed is run
+ through the MurmerHash3 avalanche phase to generate successive 64-bit values, which populate
+ the 1024 state of xorshift1024*
+
+ if you have access to a high-frequency clock (often 64-bit), you can use this for the seed
+ (don't use it for the per-thread PRNG, unless you know the clock can be read without a context switch)
+
+ murmurhash3 code from here; http://xorshift.di.unimi.it/murmurhash3.c
+ */
+
+ lfds700_misc_prng_internal_big_slow_high_quality_init( LFDS700_MISC_PRNG_SEED );
+
+ lfds700_misc_globals.exponential_backoff_timeslot_length_in_loop_iterations_for_cas = EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_INCS_FOR_CAS;
+ lfds700_misc_globals.exponential_backoff_timeslot_length_in_loop_iterations_for_dwcas = EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_INCS_FOR_DWCAS;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_internal.h
new file mode 100644
index 0000000000..9ed927efc9
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_internal.h
@@ -0,0 +1,10 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** defines *****/
+#define EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_INCS_FOR_CAS 8
+#define EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_INCS_FOR_DWCAS 16
+
+/***** private prototypes *****/
+void lfds700_misc_prng_internal_big_slow_high_quality_init( int long long unsigned seed );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_prng.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_prng.c
new file mode 100644
index 0000000000..84ae25fe71
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_prng.c
@@ -0,0 +1,144 @@
+/***** includes *****/
+#include "lfds700_misc_internal.h"
+
+/***** defines *****/
+#define LFDS700_PRNG_STATE_SIZE 16
+
+/***** struct *****/
+struct lfds700_misc_prng_big_slow_high_quality_state
+{
+ lfds700_pal_atom_t LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ xorshift1024star_spinlock;
+
+ // TRD : must be a 32 bit signed int
+ int
+ xorshift1024star_index;
+
+ int long long unsigned
+ xorshift1024star_state[LFDS700_PRNG_STATE_SIZE];
+};
+
+/***** locals *****/
+struct lfds700_misc_prng_big_slow_high_quality_state
+ pbshqs;
+
+/***** private prototypes *****/
+static void lfds700_misc_prng_internal_hash_murmurhash3( int long long unsigned *murmurhash3_state );
+static void lfds700_misc_prng_internal_big_slow_high_quality_generate( struct lfds700_misc_prng_big_slow_high_quality_state *ps, lfds700_pal_uint_t *random_value );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_misc_prng_init( struct lfds700_misc_prng_state *ps )
+{
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ /* TRD : we use the big, slow, high quality PRNG to generate the initial value
+ for the small, fast, low qulity PRNG, which is used in exponential backoff
+
+ we need the load barrier to catch any changes to the backoff periods
+ */
+
+ lfds700_misc_prng_internal_big_slow_high_quality_generate( &pbshqs, &ps->prng_state );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ ps->local_copy_of_global_exponential_backoff_timeslot_length_in_loop_iterations_for_cas = lfds700_misc_globals.exponential_backoff_timeslot_length_in_loop_iterations_for_cas;
+ ps->local_copy_of_global_exponential_backoff_timeslot_length_in_loop_iterations_for_dwcas = lfds700_misc_globals.exponential_backoff_timeslot_length_in_loop_iterations_for_dwcas;
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void lfds700_misc_prng_internal_big_slow_high_quality_init( int long long unsigned seed )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ LFDS700_PAL_ASSERT( seed != 0 ); // TRD : a 0 seed causes all zeros in the entropy state, so is forbidden
+
+ pbshqs.xorshift1024star_spinlock = LFDS700_MISC_FLAG_LOWERED;
+
+ for( loop = 0 ; loop < LFDS700_PRNG_STATE_SIZE ; loop++ )
+ {
+ lfds700_misc_prng_internal_hash_murmurhash3( &seed );
+ pbshqs.xorshift1024star_state[loop] = seed;
+ }
+
+ pbshqs.xorshift1024star_index = 0;
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_misc_prng_internal_hash_murmurhash3( int long long unsigned *murmurhash3_state )
+{
+ LFDS700_PAL_ASSERT( murmurhash3_state != NULL );
+
+ *murmurhash3_state ^= *murmurhash3_state >> 33;
+ *murmurhash3_state *= 0xff51afd7ed558ccdULL;
+ *murmurhash3_state ^= *murmurhash3_state >> 33;
+ *murmurhash3_state *= 0xc4ceb9fe1a85ec53ULL;
+ *murmurhash3_state ^= *murmurhash3_state >> 33;
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_misc_prng_internal_big_slow_high_quality_generate( struct lfds700_misc_prng_big_slow_high_quality_state *ps, lfds700_pal_uint_t *random_value )
+{
+ char unsigned
+ result;
+
+ int long long unsigned
+ xs_temp_one,
+ xs_temp_two;
+
+ lfds700_pal_atom_t
+ compare = LFDS700_MISC_FLAG_LOWERED,
+ exchange = LFDS700_MISC_FLAG_LOWERED;
+
+ LFDS700_PAL_ASSERT( ps != NULL );
+ LFDS700_PAL_ASSERT( random_value != NULL );
+
+ // TRD : this is single-threaded code, on a per-state basis
+ do
+ {
+ compare = LFDS700_MISC_FLAG_LOWERED;
+ LFDS700_PAL_ATOMIC_CAS( &ps->xorshift1024star_spinlock, &compare, (lfds700_pal_atom_t) LFDS700_MISC_FLAG_RAISED, LFDS700_MISC_CAS_STRENGTH_STRONG, result );
+ }
+ while( result == 0 );
+
+ // TRD : xorshift1024* code from here; http://xorshift.di.unimi.it/xorshift1024star.c
+
+ xs_temp_one = ps->xorshift1024star_state[ ps->xorshift1024star_index ];
+ ps->xorshift1024star_index = ( ps->xorshift1024star_index + 1 ) & 15;
+ xs_temp_two = ps->xorshift1024star_state[ ps->xorshift1024star_index ];
+
+ xs_temp_two ^= xs_temp_two << 31;
+ xs_temp_two ^= xs_temp_two >> 11;
+ xs_temp_one ^= xs_temp_one >> 30;
+
+ ps->xorshift1024star_state[ ps->xorshift1024star_index ] = xs_temp_one ^ xs_temp_two;
+
+ *random_value = (lfds700_pal_uint_t) ( ps->xorshift1024star_state[ ps->xorshift1024star_index ] * 1181783497276652981LL );
+
+ LFDS700_PAL_ATOMIC_EXCHANGE( &ps->xorshift1024star_spinlock, &exchange );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_query.c
new file mode 100644
index 0000000000..fd3595d86a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_misc/lfds700_misc_query.c
@@ -0,0 +1,48 @@
+/***** includes *****/
+#include "lfds700_misc_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_misc_query( enum lfds700_misc_query query_type, void *query_input, void *query_output )
+{
+ // TRD : query type can be any value in its range
+ // TRD : query_input can be NULL in some cases
+ // TRD : query_outputput can be NULL in some cases
+
+ switch( query_type )
+ {
+ case LFDS700_MISC_QUERY_GET_EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_LOOP_ITERATIONS_FOR_CAS:
+ *(lfds700_pal_atom_t *) query_output = lfds700_misc_globals.exponential_backoff_timeslot_length_in_loop_iterations_for_cas;
+ break;
+
+ case LFDS700_MISC_QUERY_SET_EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_LOOP_ITERATIONS_FOR_CAS:
+ LFDS700_PAL_ATOMIC_EXCHANGE( &lfds700_misc_globals.exponential_backoff_timeslot_length_in_loop_iterations_for_cas, (lfds700_pal_atom_t *) query_input );
+ break;
+
+ case LFDS700_MISC_QUERY_GET_EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_LOOP_ITERATIONS_FOR_DWCAS:
+ *(lfds700_pal_atom_t *) query_output = lfds700_misc_globals.exponential_backoff_timeslot_length_in_loop_iterations_for_dwcas;
+ break;
+
+ case LFDS700_MISC_QUERY_SET_EXPONENTIAL_BACKOFF_TIMESLOT_LENGTH_IN_LOOP_ITERATIONS_FOR_DWCAS:
+ LFDS700_PAL_ATOMIC_EXCHANGE( &lfds700_misc_globals.exponential_backoff_timeslot_length_in_loop_iterations_for_dwcas, (lfds700_pal_atom_t *) query_input );
+ break;
+
+ case LFDS700_MISC_QUERY_GET_BUILD_AND_VERSION_STRING:
+ {
+ char static const
+ * const build_and_version_string = "liblfds " LFDS700_MISC_VERSION_STRING " (" BUILD_TYPE_STRING ", " LFDS700_PAL_OS_STRING ", " MODE_TYPE_STRING ", " LFDS700_PAL_PROCESSOR_STRING ", " LFDS700_PAL_COMPILER_STRING ")";
+
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ *(char const **) query_output = build_and_version_string;
+ }
+ break;
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_cleanup.c
new file mode 100644
index 0000000000..f2da905dbe
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_cleanup.c
@@ -0,0 +1,48 @@
+/***** includes *****/
+#include "lfds700_queue_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_queue_cleanup( struct lfds700_queue_state *qs,
+ void (*element_cleanup_callback)(struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag) )
+{
+ struct lfds700_queue_element
+ *qe;
+
+ void
+ *value;
+
+ LFDS700_PAL_ASSERT( qs != NULL );
+ // TRD : element_cleanup_callback can be NULL
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( element_cleanup_callback != NULL )
+ {
+ while( qs->dequeue[POINTER] != qs->enqueue[POINTER] )
+ {
+ // TRD : trailing dummy element, so the first real value is in the next element
+ value = qs->dequeue[POINTER]->next[POINTER]->value;
+
+ // TRD : user is given back *an* element, but not the one his user data was in
+ qe = qs->dequeue[POINTER];
+
+ // TRD : remove the element from queue
+ qs->dequeue[POINTER] = qs->dequeue[POINTER]->next[POINTER];
+
+ // TRD : write value into the qe we're going to give the user
+ qe->value = value;
+
+ element_cleanup_callback( qs, qe, LFDS700_MISC_FLAG_LOWERED );
+ }
+
+ // TRD : and now the final element
+ element_cleanup_callback( qs, (struct lfds700_queue_element *) qs->dequeue[POINTER], LFDS700_MISC_FLAG_RAISED );
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_dequeue.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_dequeue.c
new file mode 100644
index 0000000000..853c585039
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_dequeue.c
@@ -0,0 +1,109 @@
+/***** includes *****/
+#include "lfds700_queue_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_queue_dequeue( struct lfds700_queue_state *qs,
+ struct lfds700_queue_element **qe,
+ struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result = 0,
+ unwanted_result;
+
+ enum lfds700_queue_queue_state
+ state = LFDS700_QUEUE_QUEUE_STATE_UNKNOWN;
+
+ int
+ rv = 1,
+ finished_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_queue_element LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_DOUBLE_POINTER)
+ *dequeue[PAC_SIZE],
+ *enqueue[PAC_SIZE],
+ *next[PAC_SIZE];
+
+ void
+ *key = NULL,
+ *value = NULL;
+
+ LFDS700_PAL_ASSERT( qs != NULL );
+ LFDS700_PAL_ASSERT( qe != NULL );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ do
+ {
+ dequeue[COUNTER] = qs->dequeue[COUNTER];
+ dequeue[POINTER] = qs->dequeue[POINTER];
+
+ enqueue[COUNTER] = qs->enqueue[COUNTER];
+ enqueue[POINTER] = qs->enqueue[POINTER];
+
+ next[COUNTER] = qs->dequeue[POINTER]->next[COUNTER];
+ next[POINTER] = qs->dequeue[POINTER]->next[POINTER];
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( dequeue[COUNTER] == qs->dequeue[COUNTER] and dequeue[POINTER] == qs->dequeue[POINTER] )
+ {
+ if( enqueue[POINTER] == dequeue[POINTER] and next[POINTER] == NULL )
+ state = LFDS700_QUEUE_QUEUE_STATE_EMPTY;
+
+ if( enqueue[POINTER] == dequeue[POINTER] and next[POINTER] != NULL )
+ state = LFDS700_QUEUE_QUEUE_STATE_ENQUEUE_OUT_OF_PLACE;
+
+ if( enqueue[POINTER] != dequeue[POINTER] )
+ state = LFDS700_QUEUE_QUEUE_STATE_ATTEMPT_DEQUEUE;
+
+ switch( state )
+ {
+ case LFDS700_QUEUE_QUEUE_STATE_UNKNOWN:
+ // TRD : eliminates compiler warning
+ break;
+
+ case LFDS700_QUEUE_QUEUE_STATE_EMPTY:
+ rv = 0;
+ *qe = NULL;
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ break;
+
+ case LFDS700_QUEUE_QUEUE_STATE_ENQUEUE_OUT_OF_PLACE:
+ next[COUNTER] = enqueue[COUNTER] + 1;
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_DWCAS( qs->enqueue, enqueue, next, LFDS700_MISC_CAS_STRENGTH_WEAK, unwanted_result );
+ break;
+
+ case LFDS700_QUEUE_QUEUE_STATE_ATTEMPT_DEQUEUE:
+ key = next[POINTER]->key;
+ value = next[POINTER]->value;
+
+ next[COUNTER] = dequeue[COUNTER] + 1;
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_DWCAS_WITH_BACKOFF( qs->dequeue, dequeue, next, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+
+ if( result == 1 )
+ finished_flag = LFDS700_MISC_FLAG_RAISED;
+ break;
+ }
+ }
+ }
+ while( finished_flag == LFDS700_MISC_FLAG_LOWERED );
+
+ if( result == 1 )
+ {
+ *qe = dequeue[POINTER];
+ (*qe)->key = key;
+ (*qe)->value = value;
+ }
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_enqueue.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_enqueue.c
new file mode 100644
index 0000000000..07df84d851
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_enqueue.c
@@ -0,0 +1,74 @@
+/***** includes *****/
+#include "lfds700_queue_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_queue_enqueue( struct lfds700_queue_state *qs,
+ struct lfds700_queue_element *qe,
+ struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result = 0,
+ unwanted_result;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_queue_element LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_DOUBLE_POINTER)
+ *volatile enqueue[PAC_SIZE],
+ *new_enqueue[PAC_SIZE],
+ *volatile next[PAC_SIZE];
+
+ LFDS700_PAL_ASSERT( qs != NULL );
+ LFDS700_PAL_ASSERT( qe != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) qe->next % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &qe->key % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ qe->next[COUNTER] = (struct lfds700_queue_element *) LFDS700_MISC_PRNG_GENERATE( ps );
+ qe->next[POINTER] = NULL;
+
+ new_enqueue[POINTER] = qe;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ do
+ {
+ enqueue[COUNTER] = qs->enqueue[COUNTER];
+ enqueue[POINTER] = qs->enqueue[POINTER];
+
+ next[COUNTER] = qs->enqueue[POINTER]->next[COUNTER];
+ next[POINTER] = qs->enqueue[POINTER]->next[POINTER];
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( qs->enqueue[COUNTER] == enqueue[COUNTER] and qs->enqueue[POINTER] == enqueue[POINTER] )
+ {
+ if( next[POINTER] == NULL )
+ {
+ new_enqueue[COUNTER] = next[COUNTER] + 1;
+ LFDS700_MISC_BARRIER_STORE;
+ LFDS700_PAL_ATOMIC_DWCAS_WITH_BACKOFF( enqueue[POINTER]->next, next, new_enqueue, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+ }
+ else
+ {
+ next[COUNTER] = enqueue[COUNTER] + 1;
+ LFDS700_MISC_BARRIER_STORE;
+ // TRD : strictly, this is a weak CAS, but we do an extra iteration of the main loop on a fake failure, so we set it to be strong
+ LFDS700_PAL_ATOMIC_DWCAS( qs->enqueue, enqueue, next, LFDS700_MISC_CAS_STRENGTH_STRONG, unwanted_result );
+ }
+ }
+ }
+ while( result != 1 );
+
+ new_enqueue[COUNTER] = enqueue[COUNTER] + 1;
+ LFDS700_MISC_BARRIER_STORE;
+ // TRD : move enqueue along; only a weak CAS as the dequeue will solve this if its out of place
+ LFDS700_PAL_ATOMIC_DWCAS( qs->enqueue, enqueue, new_enqueue, LFDS700_MISC_CAS_STRENGTH_WEAK, unwanted_result );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_init.c
new file mode 100644
index 0000000000..15f4e64d8d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_init.c
@@ -0,0 +1,43 @@
+/***** includes *****/
+#include "lfds700_queue_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_queue_init_valid_on_current_logical_core( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe_dummy, struct lfds700_misc_prng_state *ps, void *user_state )
+{
+ LFDS700_PAL_ASSERT( qs != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &qs->enqueue % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &qs->dequeue % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &qs->user_state % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( qe_dummy != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) qe_dummy->next % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &qe_dummy->key % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( ps != NULL );
+ // TRD : user_state can be UNLL
+
+ /* TRD : qe_dummy is a dummy element, needed for init
+ the qs->enqueue and qs->dequeue counters do not need to be initialized
+ but it does no harm to do so, and stops a valgrind complaint
+ */
+
+ qs->enqueue[POINTER] = qe_dummy;
+ qs->enqueue[COUNTER] = (struct lfds700_queue_element *) 0;
+ qs->dequeue[POINTER] = qe_dummy;
+ qs->dequeue[COUNTER] = (struct lfds700_queue_element *) 0;
+
+ qe_dummy->next[POINTER] = NULL;
+ qe_dummy->next[COUNTER] = (struct lfds700_queue_element *) LFDS700_MISC_PRNG_GENERATE( ps );
+ qe_dummy->value = NULL;
+
+ qs->user_state = user_state;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_internal.h
new file mode 100644
index 0000000000..81c9b69f48
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_internal.h
@@ -0,0 +1,14 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** enums *****/
+enum lfds700_queue_queue_state
+{
+ LFDS700_QUEUE_QUEUE_STATE_UNKNOWN,
+ LFDS700_QUEUE_QUEUE_STATE_EMPTY,
+ LFDS700_QUEUE_QUEUE_STATE_ENQUEUE_OUT_OF_PLACE,
+ LFDS700_QUEUE_QUEUE_STATE_ATTEMPT_DEQUEUE
+};
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_query.c
new file mode 100644
index 0000000000..15b4307ff2
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue/lfds700_queue_query.c
@@ -0,0 +1,126 @@
+/***** includes *****/
+#include "lfds700_queue_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_queue_internal_validate( struct lfds700_queue_state *qs, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_queue_validity );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_queue_query( struct lfds700_queue_state *qs, enum lfds700_queue_query query_type, void *query_input, void *query_output )
+{
+ struct lfds700_queue_element
+ *qe;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ LFDS700_PAL_ASSERT( qs != NULL );
+ // TRD : query_type can be any value in its range
+
+ switch( query_type )
+ {
+ case LFDS700_QUEUE_QUERY_SINGLETHREADED_GET_COUNT:
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ *(lfds700_pal_uint_t *) query_output = 0;
+
+ qe = (struct lfds700_queue_element *) qs->dequeue[POINTER];
+
+ while( qe != NULL )
+ {
+ ( *(lfds700_pal_uint_t *) query_output )++;
+ qe = (struct lfds700_queue_element *) qe->next[POINTER];
+ }
+
+ // TRD : remember there is a dummy element in the queue
+ ( *(lfds700_pal_uint_t *) query_output )--;
+ break;
+
+ case LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE:
+ // TRD : query_input can be NULL
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_queue_internal_validate( qs, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_queue_internal_validate( struct lfds700_queue_state *qs, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_queue_validity )
+{
+ lfds700_pal_uint_t
+ number_elements = 0;
+
+ struct lfds700_queue_element
+ *qe_fast,
+ *qe_slow;
+
+ LFDS700_PAL_ASSERT( qs != NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_queue_validity != NULL );
+
+ *lfds700_queue_validity = LFDS700_MISC_VALIDITY_VALID;
+
+ qe_slow = qe_fast = (struct lfds700_queue_element *) qs->dequeue[POINTER];
+
+ /* TRD : first, check for a loop
+ we have two pointers
+ both of which start at the dequeue end of the queue
+ we enter a loop
+ and on each iteration
+ we advance one pointer by one element
+ and the other by two
+
+ we exit the loop when both pointers are NULL
+ (have reached the end of the queue)
+
+ or
+
+ if we fast pointer 'sees' the slow pointer
+ which means we have a loop
+ */
+
+ if( qe_slow != NULL )
+ do
+ {
+ qe_slow = qe_slow->next[POINTER];
+
+ if( qe_fast != NULL )
+ qe_fast = qe_fast->next[POINTER];
+
+ if( qe_fast != NULL )
+ qe_fast = qe_fast->next[POINTER];
+ }
+ while( qe_slow != NULL and qe_fast != qe_slow );
+
+ if( qe_fast != NULL and qe_slow != NULL and qe_fast == qe_slow )
+ *lfds700_queue_validity = LFDS700_MISC_VALIDITY_INVALID_LOOP;
+
+ /* TRD : now check for expected number of elements
+ vi can be NULL, in which case we do not check
+ we know we don't have a loop from our earlier check
+ */
+
+ if( *lfds700_queue_validity == LFDS700_MISC_VALIDITY_VALID and vi != NULL )
+ {
+ lfds700_queue_query( qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_GET_COUNT, NULL, (void *) &number_elements );
+
+ if( number_elements < vi->min_elements )
+ *lfds700_queue_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( number_elements > vi->max_elements )
+ *lfds700_queue_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c
new file mode 100644
index 0000000000..2b157bd973
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c
@@ -0,0 +1,30 @@
+/***** includes *****/
+#include "lfds700_queue_bounded_singleconsumer_singleproducer_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_queue_bss_cleanup( struct lfds700_queue_bss_state *qbsss,
+ void (*element_cleanup_callback)(struct lfds700_queue_bss_state *qbsss, void *key, void *value) )
+{
+ int long long unsigned
+ loop;
+
+ struct lfds700_queue_bss_element
+ *qbsse;
+
+ LFDS700_PAL_ASSERT( qbsss != NULL );
+ // TRD : element_cleanup_callback can be NULL
+
+ if( element_cleanup_callback != NULL )
+ for( loop = qbsss->read_index ; loop < qbsss->read_index + qbsss->number_elements ; loop++ )
+ {
+ qbsse = qbsss->element_array + (loop % qbsss->number_elements);
+ element_cleanup_callback( qbsss, qbsse->key, qbsse->value );
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c
new file mode 100644
index 0000000000..28f735f610
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c
@@ -0,0 +1,42 @@
+/***** includes *****/
+#include "lfds700_queue_bounded_singleconsumer_singleproducer_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_queue_bss_dequeue( struct lfds700_queue_bss_state *qbsss, void **key, void **value )
+{
+ int
+ rv = 0;
+
+ struct lfds700_queue_bss_element
+ *qbsse;
+
+ LFDS700_PAL_ASSERT( qbsss != NULL );
+ // TRD : key can be NULL
+ // TRD : value can be NULL
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( qbsss->read_index != qbsss->write_index )
+ {
+ qbsse = qbsss->element_array + qbsss->read_index;
+
+ if( key != NULL )
+ *key = qbsse->key;
+
+ if( value != NULL )
+ *value = qbsse->value;
+
+ qbsss->read_index = (qbsss->read_index + 1) & qbsss->mask;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ rv = 1;
+ }
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c
new file mode 100644
index 0000000000..c74091a23e
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c
@@ -0,0 +1,39 @@
+/***** includes *****/
+#include "lfds700_queue_bounded_singleconsumer_singleproducer_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_queue_bss_enqueue( struct lfds700_queue_bss_state *qbsss, void *key, void *value )
+{
+ int
+ rv = 0;
+
+ struct lfds700_queue_bss_element
+ *qbsse;
+
+ LFDS700_PAL_ASSERT( qbsss != NULL );
+ // TRD : key can be NULL
+ // TRD : value can be NULL
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( ( (qbsss->write_index+1) & qbsss->mask ) != qbsss->read_index )
+ {
+ qbsse = qbsss->element_array + qbsss->write_index;
+
+ qbsse->key = key;
+ qbsse->value = value;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ qbsss->write_index = (qbsss->write_index + 1) & qbsss->mask;
+
+ rv = 1;
+ }
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_init.c
new file mode 100644
index 0000000000..9127fef443
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_init.c
@@ -0,0 +1,63 @@
+/***** includes *****/
+#include "lfds700_queue_bounded_singleconsumer_singleproducer_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_queue_bss_init_valid_on_current_logical_core( struct lfds700_queue_bss_state *qbsss,
+ struct lfds700_queue_bss_element *element_array,
+ lfds700_pal_uint_t number_elements,
+ void *user_state )
+{
+ LFDS700_PAL_ASSERT( qbsss != NULL );
+ LFDS700_PAL_ASSERT( element_array != NULL );
+ LFDS700_PAL_ASSERT( number_elements >= 2 );
+ LFDS700_PAL_ASSERT( ( number_elements & (number_elements-1) ) == 0 ); // TRD : number_elements must be a positive integer power of 2
+ // TRD : user_state can be NULL
+
+ /* TRD : the use of mask and the restriction on a power of two
+ upon the number of elements bears some remark
+
+ in this queue, there are a fixed number of elements
+ we have a read index and a write index
+ when we write, and thre is space to write, we increment the write index
+ (if no space to write, we just return)
+ when we read, and there are elements to be read, we after reading increment the read index
+ (if no elements to read, we just return)
+ the problem is - how do we handle wrap around?
+ e.g. when I write, but my write index is now equal to the number of elements
+ the usual solution is to modulus the write index by the nunmber of elements
+ problem is modulus is slow
+ there is a better way
+ first, we restrict the number of elements to be a power of two
+ so imagine we have a 64-bit system and we set the number of elements to be 2^64
+ this gives us a bit pattern of 1000 0000 0000 0000 (...etc, lots of zeros)
+ now (just roll with this for a bit) subtract one from this
+ this gives us a mask (on a two's compliment machine)
+ 0111 1111 1111 1111 (...etc, lots of ones)
+ so what we do now, when we increment an index (think of the write index as the example)
+ we bitwise and it with the mask
+ now think about thwt happens
+ all the numbers up to 2^64 will be unchanged - their MSB is never set, and we and with all the other bits
+ but when we finally hit 2^64 and need to roll over... bingo!
+ we drop MSB (which we finally have) and have the value 0!
+ this is exactly what we want
+ bitwise and is much faster than modulus
+ */
+
+ qbsss->number_elements = number_elements;
+ qbsss->mask = qbsss->number_elements - 1;
+ qbsss->read_index = 0;
+ qbsss->write_index = 0;
+ qbsss->element_array = element_array;
+ qbsss->user_state = user_state;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_internal.h
new file mode 100644
index 0000000000..7a7d541804
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_internal.h
@@ -0,0 +1,5 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_query.c
new file mode 100644
index 0000000000..aabcae23f3
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_queue_bounded_singleconsumer_singleproducer/lfds700_queue_bounded_singleconsumer_singleproducer_query.c
@@ -0,0 +1,70 @@
+/***** includes *****/
+#include "lfds700_queue_bounded_singleconsumer_singleproducer_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_queue_bss_internal_validate( struct lfds700_queue_bss_state *qbsss, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_validity );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_queue_bss_query( struct lfds700_queue_bss_state *qbsss, enum lfds700_queue_bss_query query_type, void *query_input, void *query_output )
+{
+ LFDS700_PAL_ASSERT( qbsss != NULL );
+ // TRD : query_type can be any value in its range
+
+ switch( query_type )
+ {
+ case LFDS700_QUEUE_BSS_QUERY_GET_POTENTIALLY_INACCURATE_COUNT:
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ *(lfds700_pal_uint_t *) query_output = +( qbsss->write_index - qbsss->read_index );
+ if( qbsss->read_index > qbsss->write_index )
+ *(lfds700_pal_uint_t *) query_output = qbsss->number_elements - *(lfds700_pal_uint_t *) query_output;
+ break;
+
+ case LFDS700_QUEUE_BSS_QUERY_VALIDATE:
+ // TRD : query_input can be NULL
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_queue_bss_internal_validate( qbsss, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_queue_bss_internal_validate( struct lfds700_queue_bss_state *qbsss, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_validity )
+{
+ LFDS700_PAL_ASSERT( qbsss != NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_validity != NULL );
+
+ *lfds700_validity = LFDS700_MISC_VALIDITY_VALID;
+
+ if( vi != NULL )
+ {
+ lfds700_pal_uint_t
+ number_elements;
+
+ lfds700_queue_bss_query( qbsss, LFDS700_QUEUE_BSS_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void *) &number_elements );
+
+ if( number_elements < vi->min_elements )
+ *lfds700_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( number_elements > vi->max_elements )
+ *lfds700_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c
new file mode 100644
index 0000000000..447c93041e
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_cleanup.c
@@ -0,0 +1,86 @@
+/***** includes *****/
+#include "lfds700_ringbuffer_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_ringbuffer_internal_queue_element_cleanup_callback( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag );
+static void lfds700_ringbuffer_internal_freelist_element_cleanup_callback( struct lfds700_freelist_state *fs, struct lfds700_freelist_element *fe );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_ringbuffer_cleanup( struct lfds700_ringbuffer_state *rs,
+ void (*element_cleanup_callback)(struct lfds700_ringbuffer_state *rs, void *key, void *value, enum lfds700_misc_flag unread_flag) )
+{
+ LFDS700_PAL_ASSERT( rs != NULL );
+ // TRD : element_cleanup_callback can be NULL
+
+ if( element_cleanup_callback != NULL )
+ {
+ rs->element_cleanup_callback = element_cleanup_callback;
+ lfds700_queue_cleanup( &rs->qs, lfds700_ringbuffer_internal_queue_element_cleanup_callback );
+ lfds700_freelist_cleanup( &rs->fs, lfds700_ringbuffer_internal_freelist_element_cleanup_callback );
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void lfds700_ringbuffer_internal_queue_element_cleanup_callback( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag )
+{
+ struct lfds700_ringbuffer_element
+ *re;
+
+ struct lfds700_ringbuffer_state
+ *rs;
+
+ LFDS700_PAL_ASSERT( qs != NULL );
+ LFDS700_PAL_ASSERT( qe != NULL );
+ // TRD : dummy_element can be any value in its range
+
+ rs = (struct lfds700_ringbuffer_state *) LFDS700_QUEUE_GET_USER_STATE_FROM_STATE( *qs );
+ re = (struct lfds700_ringbuffer_element *) LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+
+ if( dummy_element_flag == LFDS700_MISC_FLAG_LOWERED )
+ rs->element_cleanup_callback( rs, re->key, re->value, LFDS700_MISC_FLAG_RAISED );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void lfds700_ringbuffer_internal_freelist_element_cleanup_callback( struct lfds700_freelist_state *fs, struct lfds700_freelist_element *fe )
+{
+ struct lfds700_ringbuffer_element
+ *re;
+
+ struct lfds700_ringbuffer_state
+ *rs;
+
+ LFDS700_PAL_ASSERT( fs != NULL );
+ LFDS700_PAL_ASSERT( fe != NULL );
+
+ rs = (struct lfds700_ringbuffer_state *) LFDS700_FREELIST_GET_USER_STATE_FROM_STATE( *fs );
+ re = (struct lfds700_ringbuffer_element *) LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
+
+ rs->element_cleanup_callback( rs, re->key, re->value, LFDS700_MISC_FLAG_LOWERED );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_init.c
new file mode 100644
index 0000000000..a6cd1e3616
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_init.c
@@ -0,0 +1,51 @@
+/***** includes *****/
+#include "lfds700_ringbuffer_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_ringbuffer_init_valid_on_current_logical_core( struct lfds700_ringbuffer_state *rs,
+ struct lfds700_ringbuffer_element *re_array_inc_dummy,
+ lfds700_pal_uint_t number_elements,
+ struct lfds700_misc_prng_state *ps,
+ void *user_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ LFDS700_PAL_ASSERT( rs != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &rs->fs % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &rs->qs % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( re_array_inc_dummy != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &re_array_inc_dummy[0].fe % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &re_array_inc_dummy[0].qe % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( number_elements >= 2 );
+ LFDS700_PAL_ASSERT( ps != NULL );
+ // TRD : user_state can be NULL
+
+ rs->user_state = user_state;
+
+ re_array_inc_dummy[0].qe_use = &re_array_inc_dummy[0].qe;
+
+ lfds700_freelist_init_valid_on_current_logical_core( &rs->fs, rs );
+ lfds700_queue_init_valid_on_current_logical_core( &rs->qs, &re_array_inc_dummy[0].qe, ps, rs );
+
+ for( loop = 1 ; loop < number_elements ; loop++ )
+ {
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &re_array_inc_dummy[loop].fe % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &re_array_inc_dummy[loop].qe % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+
+ re_array_inc_dummy[loop].qe_use = &re_array_inc_dummy[loop].qe;
+ LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( re_array_inc_dummy[loop].fe, &re_array_inc_dummy[loop] );
+ lfds700_freelist_push( &rs->fs, &re_array_inc_dummy[loop].fe, ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_internal.h
new file mode 100644
index 0000000000..7a7d541804
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_internal.h
@@ -0,0 +1,5 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_query.c
new file mode 100644
index 0000000000..58b7b3a9cb
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_query.c
@@ -0,0 +1,72 @@
+/***** includes *****/
+#include "lfds700_ringbuffer_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_ringbuffer_internal_validate( struct lfds700_ringbuffer_state *rs, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_queue_validity, enum lfds700_misc_validity *lfds700_freelist_validity );
+
+
+
+/****************************************************************************/
+void lfds700_ringbuffer_query( struct lfds700_ringbuffer_state *rs, enum lfds700_ringbuffer_query query_type, void *query_input, void *query_output )
+{
+ LFDS700_PAL_ASSERT( rs != NULL );
+ // TRD : query_type can be any value in its range
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ switch( query_type )
+ {
+ case LFDS700_RINGBUFFER_QUERY_SINGLETHREADED_GET_COUNT:
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_queue_query( &rs->qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_GET_COUNT, NULL, query_output );
+ break;
+
+ case LFDS700_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE:
+ // TRD : query_input can be NULL
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_ringbuffer_internal_validate( rs, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output, ((enum lfds700_misc_validity *) query_output)+1 );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_ringbuffer_internal_validate( struct lfds700_ringbuffer_state *rs, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_queue_validity, enum lfds700_misc_validity *lfds700_freelist_validity )
+{
+ LFDS700_PAL_ASSERT( rs != NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_queue_validity != NULL );
+ LFDS700_PAL_ASSERT( lfds700_freelist_validity != NULL );
+
+ if( vi == NULL )
+ {
+ lfds700_queue_query( &rs->qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE, NULL, lfds700_queue_validity );
+ lfds700_freelist_query( &rs->fs, LFDS700_FREELIST_QUERY_SINGLETHREADED_VALIDATE, NULL, lfds700_freelist_validity );
+ }
+
+ if( vi != NULL )
+ {
+ struct lfds700_misc_validation_info
+ freelist_vi,
+ queue_vi;
+
+ queue_vi.min_elements = 0;
+ freelist_vi.min_elements = 0;
+ queue_vi.max_elements = vi->max_elements;
+ freelist_vi.max_elements = vi->max_elements;
+
+ lfds700_queue_query( &rs->qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE, &queue_vi, lfds700_queue_validity );
+ lfds700_freelist_query( &rs->fs, LFDS700_FREELIST_QUERY_SINGLETHREADED_VALIDATE, &freelist_vi, lfds700_freelist_validity );
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_read.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_read.c
new file mode 100644
index 0000000000..42dbe189e2
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_read.c
@@ -0,0 +1,44 @@
+/***** includes *****/
+#include "lfds700_ringbuffer_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_ringbuffer_read( struct lfds700_ringbuffer_state *rs,
+ void **key,
+ void **value,
+ struct lfds700_misc_prng_state *ps )
+{
+ int
+ rv;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct lfds700_ringbuffer_element
+ *re;
+
+ LFDS700_PAL_ASSERT( rs != NULL );
+ // TRD : key can be NULL
+ // TRD : value can be NULL
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ rv = lfds700_queue_dequeue( &rs->qs, &qe, ps );
+
+ if( rv == 1 )
+ {
+ re = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+ re->qe_use = (struct lfds700_queue_element *) qe;
+ if( key != NULL )
+ *key = re->key;
+ if( value != NULL )
+ *value = re->value;
+ LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( re->fe, re );
+ lfds700_freelist_push( &rs->fs, &re->fe, ps );
+ }
+
+ return( rv );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_write.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_write.c
new file mode 100644
index 0000000000..a16a8686c1
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_ringbuffer/lfds700_ringbuffer_write.c
@@ -0,0 +1,78 @@
+/***** includes *****/
+#include "lfds700_ringbuffer_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_ringbuffer_write( struct lfds700_ringbuffer_state *rs,
+ void *key,
+ void *value,
+ enum lfds700_misc_flag *overwrite_occurred_flag,
+ void **overwritten_key,
+ void **overwritten_value,
+ struct lfds700_misc_prng_state *ps )
+{
+ int
+ rv = 0;
+
+ struct lfds700_freelist_element
+ *fe;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct lfds700_ringbuffer_element
+ *re = NULL;
+
+ LFDS700_PAL_ASSERT( rs != NULL );
+ // TRD : key can be NULL
+ // TRD : value can be NULL
+ // TRD : overwrite_occurred_flag can be NULL
+ // TRD : overwritten_key can be NULL
+ // TRD : overwritten_value can be NULL
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ if( overwrite_occurred_flag != NULL )
+ *overwrite_occurred_flag = LFDS700_MISC_FLAG_LOWERED;
+
+ do
+ {
+ rv = lfds700_freelist_pop( &rs->fs, &fe, ps );
+
+ if( rv == 1 )
+ re = LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
+
+ if( rv == 0 )
+ {
+ // TRD : the queue can return empty as well - remember, we're lock-free; anything could have happened since the previous instruction
+ rv = lfds700_queue_dequeue( &rs->qs, &qe, ps );
+
+ if( rv == 1 )
+ {
+ re = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+ re->qe_use = (struct lfds700_queue_element *) qe;
+
+ if( overwrite_occurred_flag != NULL )
+ *overwrite_occurred_flag = LFDS700_MISC_FLAG_RAISED;
+
+ if( overwritten_key != NULL )
+ *overwritten_key = re->key;
+
+ if( overwritten_value != NULL )
+ *overwritten_value = re->value;
+ }
+ }
+ }
+ while( rv == 0 );
+
+ re->key = key;
+ re->value = value;
+
+ LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( *re->qe_use, re );
+ lfds700_queue_enqueue( &rs->qs, re->qe_use, ps );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_cleanup.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_cleanup.c
new file mode 100644
index 0000000000..efcebf3543
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_cleanup.c
@@ -0,0 +1,36 @@
+/***** includes *****/
+#include "lfds700_stack_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_stack_cleanup( struct lfds700_stack_state *ss,
+ void (*element_cleanup_callback)(struct lfds700_stack_state *ss, struct lfds700_stack_element *se) )
+{
+ struct lfds700_stack_element
+ *se,
+ *se_temp;
+
+ LFDS700_PAL_ASSERT( ss != NULL );
+ // TRD : element_cleanup_callback can be NULL
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( element_cleanup_callback != NULL )
+ {
+ se = ss->top[POINTER];
+
+ while( se != NULL )
+ {
+ se_temp = se;
+ se = se->next;
+
+ element_cleanup_callback( ss, se_temp );
+ }
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_init.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_init.c
new file mode 100644
index 0000000000..745017c029
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_init.c
@@ -0,0 +1,27 @@
+/***** includes *****/
+#include "lfds700_stack_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_stack_init_valid_on_current_logical_core( struct lfds700_stack_state *ss, void *user_state )
+{
+ LFDS700_PAL_ASSERT( ss != NULL );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) ss->top % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ LFDS700_PAL_ASSERT( (lfds700_pal_uint_t) &ss->user_state % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES == 0 );
+ // TRD : user_state can be NULL
+
+ ss->top[POINTER] = NULL;
+ ss->top[COUNTER] = 0;
+
+ ss->user_state = user_state;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_internal.h
new file mode 100644
index 0000000000..7a7d541804
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_internal.h
@@ -0,0 +1,5 @@
+/***** the library wide include file *****/
+#include "../liblfds700_internal.h"
+
+/***** private prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_pop.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_pop.c
new file mode 100644
index 0000000000..3cae2e563e
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_pop.c
@@ -0,0 +1,52 @@
+/***** includes *****/
+#include "lfds700_stack_internal.h"
+
+
+
+
+
+/****************************************************************************/
+int lfds700_stack_pop( struct lfds700_stack_state *ss, struct lfds700_stack_element **se, struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_stack_element LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_DOUBLE_POINTER)
+ *new_top[PAC_SIZE],
+ *volatile original_top[PAC_SIZE];
+
+ LFDS700_PAL_ASSERT( ss != NULL );
+ LFDS700_PAL_ASSERT( se != NULL );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ LFDS700_PAL_BARRIER_PROCESSOR_LOAD;
+
+ original_top[COUNTER] = ss->top[COUNTER];
+ original_top[POINTER] = ss->top[POINTER];
+
+ do
+ {
+ if( original_top[POINTER] == NULL )
+ {
+ *se = NULL;
+ return( 0 );
+ }
+
+ new_top[COUNTER] = original_top[COUNTER] + 1;
+ new_top[POINTER] = original_top[POINTER]->next;
+
+ LFDS700_PAL_ATOMIC_DWCAS_WITH_BACKOFF( &ss->top, original_top, new_top, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+
+ if( result != 1 )
+ LFDS700_PAL_BARRIER_PROCESSOR_LOAD;
+ }
+ while( result != 1 );
+
+ *se = original_top[POINTER];
+
+ return( 1 );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_push.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_push.c
new file mode 100644
index 0000000000..ff84c5ed55
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_push.c
@@ -0,0 +1,42 @@
+/***** includes *****/
+#include "lfds700_stack_internal.h"
+
+
+
+
+
+/****************************************************************************/
+void lfds700_stack_push( struct lfds700_stack_state *ss, struct lfds700_stack_element *se, struct lfds700_misc_prng_state *ps )
+{
+ char unsigned
+ result;
+
+ lfds700_pal_uint_t
+ backoff_iteration = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE;
+
+ struct lfds700_stack_element LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_DOUBLE_POINTER)
+ *new_top[PAC_SIZE],
+ *volatile original_top[PAC_SIZE];
+
+ LFDS700_PAL_ASSERT( ss != NULL );
+ LFDS700_PAL_ASSERT( se != NULL );
+ LFDS700_PAL_ASSERT( ps != NULL );
+
+ new_top[POINTER] = se;
+
+ original_top[COUNTER] = ss->top[COUNTER];
+ original_top[POINTER] = ss->top[POINTER];
+
+ do
+ {
+ new_top[COUNTER] = original_top[COUNTER] + 1;
+ se->next = original_top[POINTER];
+
+ LFDS700_PAL_BARRIER_PROCESSOR_STORE;
+ LFDS700_PAL_ATOMIC_DWCAS_WITH_BACKOFF( &ss->top, original_top, new_top, LFDS700_MISC_CAS_STRENGTH_WEAK, result, backoff_iteration, ps );
+ }
+ while( result != 1 );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_query.c b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_query.c
new file mode 100644
index 0000000000..b9abdf9f2d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/lfds700_stack/lfds700_stack_query.c
@@ -0,0 +1,123 @@
+/***** includes *****/
+#include "lfds700_stack_internal.h"
+
+/***** private prototypes *****/
+static void lfds700_stack_internal_stack_validate( struct lfds700_stack_state *ss, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_stack_validity );
+
+
+
+
+
+/****************************************************************************/
+void lfds700_stack_query( struct lfds700_stack_state *ss, enum lfds700_stack_query query_type, void *query_input, void *query_output )
+{
+ struct lfds700_stack_element
+ *se;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ LFDS700_PAL_ASSERT( ss != NULL );
+ // TRD : query_type can be any value in its range
+
+ switch( query_type )
+ {
+ case LFDS700_STACK_QUERY_SINGLETHREADED_GET_COUNT:
+ LFDS700_PAL_ASSERT( query_input == NULL );
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ *(lfds700_pal_uint_t *) query_output = 0;
+
+ se = (struct lfds700_stack_element *) ss->top[POINTER];
+
+ while( se != NULL )
+ {
+ ( *(lfds700_pal_uint_t *) query_output )++;
+ se = (struct lfds700_stack_element *) se->next;
+ }
+ break;
+
+ case LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE:
+ // TRD : query_input can be NULL
+ LFDS700_PAL_ASSERT( query_output != NULL );
+
+ lfds700_stack_internal_stack_validate( ss, (struct lfds700_misc_validation_info *) query_input, (enum lfds700_misc_validity *) query_output );
+ break;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static void lfds700_stack_internal_stack_validate( struct lfds700_stack_state *ss, struct lfds700_misc_validation_info *vi, enum lfds700_misc_validity *lfds700_stack_validity )
+{
+ lfds700_pal_uint_t
+ number_elements = 0;
+
+ struct lfds700_stack_element
+ *se_fast,
+ *se_slow;
+
+ LFDS700_PAL_ASSERT( ss != NULL );
+ // TRD : vi can be NULL
+ LFDS700_PAL_ASSERT( lfds700_stack_validity != NULL );
+
+ *lfds700_stack_validity = LFDS700_MISC_VALIDITY_VALID;
+
+ se_slow = se_fast = (struct lfds700_stack_element *) ss->top[POINTER];
+
+ /* TRD : first, check for a loop
+ we have two pointers
+ both of which start at the top of the stack
+ we enter a loop
+ and on each iteration
+ we advance one pointer by one element
+ and the other by two
+
+ we exit the loop when both pointers are NULL
+ (have reached the end of the stack)
+
+ or
+
+ if we fast pointer 'sees' the slow pointer
+ which means we have a loop
+ */
+
+ if( se_slow != NULL )
+ do
+ {
+ se_slow = se_slow->next;
+
+ if( se_fast != NULL )
+ se_fast = se_fast->next;
+
+ if( se_fast != NULL )
+ se_fast = se_fast->next;
+ }
+ while( se_slow != NULL and se_fast != se_slow );
+
+ if( se_fast != NULL and se_slow != NULL and se_fast == se_slow )
+ *lfds700_stack_validity = LFDS700_MISC_VALIDITY_INVALID_LOOP;
+
+ /* TRD : now check for expected number of elements
+ vi can be NULL, in which case we do not check
+ we know we don't have a loop from our earlier check
+ */
+
+ if( *lfds700_stack_validity == LFDS700_MISC_VALIDITY_VALID and vi != NULL )
+ {
+ lfds700_stack_query( ss, LFDS700_STACK_QUERY_SINGLETHREADED_GET_COUNT, NULL, (void *) &number_elements );
+
+ if( number_elements < vi->min_elements )
+ *lfds700_stack_validity = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( number_elements > vi->max_elements )
+ *lfds700_stack_validity = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/liblfds700_internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/liblfds700_internal.h
new file mode 100644
index 0000000000..fdd8c363eb
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/liblfds700/src/liblfds700_internal.h
@@ -0,0 +1,93 @@
+/***** public prototypes *****/
+#include "../inc/liblfds700.h"
+
+/***** defines *****/
+#define and &&
+#define or ||
+
+#define NO_FLAGS 0x0
+
+#define LFDS700_ABSTRACTION_BACKOFF_LIMIT (0x1 << 10)
+
+#if( defined _KERNEL_MODE )
+ #define MODE_TYPE_STRING "kernel-mode"
+#endif
+
+#if( !defined _KERNEL_MODE )
+ #define MODE_TYPE_STRING "user-mode"
+#endif
+
+#if( defined NDEBUG && !defined COVERAGE && !defined TSAN )
+ #define BUILD_TYPE_STRING "release"
+#endif
+
+#if( !defined NDEBUG && !defined COVERAGE && !defined TSAN )
+ #define BUILD_TYPE_STRING "debug"
+#endif
+
+#if( !defined NDEBUG && defined COVERAGE && !defined TSAN )
+ #define BUILD_TYPE_STRING "coverage"
+#endif
+
+#if( !defined NDEBUG && !defined COVERAGE && defined TSAN )
+ #define BUILD_TYPE_STRING "threadsanitizer"
+#endif
+
+// TRD : lfds700_pal_atom_t volatile *destination, lfds700_pal_atom_t *compare, lfds700_pal_atom_t new_destination, enum lfds700_misc_cas_strength cas_strength, char unsigned result, lfds700_pal_uint_t *backoff_iteration
+#define LFDS700_PAL_ATOMIC_CAS_WITH_BACKOFF( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result, backoff_iteration, ps ) \
+{ \
+ LFDS700_PAL_ATOMIC_CAS( pointer_to_destination, pointer_to_compare, new_destination, cas_strength, result ); \
+ \
+ if( result == 0 ) \
+ { \
+ lfds700_pal_uint_t \
+ endloop; \
+ \
+ lfds700_pal_uint_t volatile \
+ loop; \
+ \
+ if( (backoff_iteration) == LFDS700_ABSTRACTION_BACKOFF_LIMIT ) \
+ (backoff_iteration) = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE; \
+ \
+ if( (backoff_iteration) == LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE ) \
+ (backoff_iteration) = 1; \
+ else \
+ { \
+ endloop = ( LFDS700_MISC_PRNG_GENERATE(ps) % (backoff_iteration) ) * ps->local_copy_of_global_exponential_backoff_timeslot_length_in_loop_iterations_for_cas; \
+ for( loop = 0 ; loop < endloop ; loop++ ); \
+ } \
+ \
+ (backoff_iteration) <<= 1; \
+ } \
+}
+
+// TRD : lfds700_pal_atom_t volatile (*destination)[2], lfds700_pal_atom_t (*compare)[2], lfds700_pal_atom_t (*new_destination)[2], enum lfds700_misc_cas_strength cas_strength, char unsigned result, lfds700_pal_uint_t *backoff_iteration
+#define LFDS700_PAL_ATOMIC_DWCAS_WITH_BACKOFF( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result, backoff_iteration, ps ) \
+{ \
+ LFDS700_PAL_ATOMIC_DWCAS( pointer_to_destination, pointer_to_compare, pointer_to_new_destination, cas_strength, result ); \
+ \
+ if( result == 0 ) \
+ { \
+ lfds700_pal_uint_t \
+ endloop; \
+ \
+ lfds700_pal_uint_t volatile \
+ loop; \
+ \
+ if( (backoff_iteration) == LFDS700_ABSTRACTION_BACKOFF_LIMIT ) \
+ (backoff_iteration) = LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE; \
+ \
+ if( (backoff_iteration) == LFDS700_MISC_ABSTRACTION_BACKOFF_INITIAL_VALUE ) \
+ (backoff_iteration) = 1; \
+ else \
+ { \
+ endloop = ( LFDS700_MISC_PRNG_GENERATE(ps) % (backoff_iteration) ) * ps->local_copy_of_global_exponential_backoff_timeslot_length_in_loop_iterations_for_dwcas; \
+ for( loop = 0 ; loop < endloop ; loop++ ); \
+ } \
+ \
+ (backoff_iteration) <<= 1; \
+ } \
+}
+
+/***** library-wide prototypes *****/
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/build/gcc_and_gnumake/Makefile b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/gcc_and_gnumake/Makefile
new file mode 100644
index 0000000000..489e5b19e5
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/gcc_and_gnumake/Makefile
@@ -0,0 +1,129 @@
+##### paths #####
+BINDIR := ../../bin
+OBJDIR := ../../obj
+SRCDIR := ../../src
+LIBINCDIRS := ../../../liblfds700/inc/
+LIBBINDIRS := ../../../liblfds700/bin/
+
+##### misc #####
+QUIETLY := 1>nul 2>nul
+
+##### sources, objects and libraries #####
+BINNAME := test
+BINARY := $(BINDIR)/$(BINNAME)
+SRCDIRS := .
+SOURCES := main.c misc.c \
+ test_lfds700_btree_addonly_unbalanced.c test_lfds700_btree_addonly_unbalanced_alignment.c test_lfds700_btree_addonly_unbalanced_random_adds_fail.c test_lfds700_btree_addonly_unbalanced_random_adds_fail_and_overwrite.c test_lfds700_btree_addonly_unbalanced_random_adds_overwrite.c \
+ test_lfds700_freelist.c test_lfds700_freelist_alignment.c test_lfds700_freelist_popping.c test_lfds700_freelist_popping_and_pushing.c test_lfds700_freelist_pushing.c test_lfds700_freelist_rapid_popping_and_pushing.c \
+ test_lfds700_hash_addonly.c test_lfds700_hash_addonly_alignment.c test_lfds700_hash_addonly_iterate.c test_lfds700_hash_addonly_random_adds_fail.c test_lfds700_hash_addonly_random_adds_fail_and_overwrite.c test_lfds700_hash_addonly_random_adds_overwrite.c \
+ test_lfds700_list_addonly_ordered_singlylinked.c test_lfds700_list_addonly_ordered_singlylinked_alignment.c test_lfds700_list_addonly_ordered_singlylinked_new_ordered.c test_lfds700_list_addonly_ordered_singlylinked_new_ordered_with_cursor.c \
+ test_lfds700_list_addonly_singlylinked_unordered.c test_lfds700_list_addonly_singlylinked_unordered_alignment.c test_lfds700_list_addonly_singlylinked_unordered_new_after.c test_lfds700_list_addonly_singlylinked_unordered_new_end.c test_lfds700_list_addonly_singlylinked_unordered_new_start.c \
+ test_lfds700_porting_abstraction_layer_atomic.c test_lfds700_porting_abstraction_layer_atomic_cas.c test_lfds700_porting_abstraction_layer_atomic_dcas.c test_lfds700_porting_abstraction_layer_atomic_exchange.c \
+ test_lfds700_queue.c test_lfds700_queue_alignment.c test_lfds700_queue_dequeuing.c test_lfds700_queue_enqueuing.c test_lfds700_queue_enqueuing_and_dequeuing.c test_lfds700_queue_enqueuing_and_dequeuing_with_free.c test_lfds700_queue_enqueuing_with_malloc_and_dequeuing_with_free.c test_lfds700_queue_rapid_enqueuing_and_dequeuing.c \
+ test_lfds700_queue_bounded_singleconsumer_singleproducer.c test_lfds700_queue_bounded_singleconsumer_singleproducer_dequeuing.c test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing.c test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing_and_dequeuing.c \
+ test_lfds700_ringbuffer.c test_lfds700_ringbuffer_reading.c test_lfds700_ringbuffer_reading_and_writing.c test_lfds700_ringbuffer_writing.c \
+ test_lfds700_stack.c test_lfds700_stack_alignment.c test_lfds700_stack_popping.c test_lfds700_stack_popping_and_pushing.c test_lfds700_stack_pushing.c test_lfds700_stack_rapid_popping_and_pushing.c \
+ test_porting_abstraction_layer_get_logical_core_ids.c test_porting_abstraction_layer_thread_start.c test_porting_abstraction_layer_thread_wait.c \
+ util_cmdline.c util_memory_helpers.c util_thread_starter.c
+OBJECTS := $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SOURCES)))
+SYSLIBS := -lm -lpthread -lrt
+USRLIBS := -llfds700
+
+##### default paths #####
+CPATH += $(LIBINCDIRS)
+LIBRARY_PATH += $(LIBBINDIRS)
+export CPATH
+export LIBRARY_PATH
+
+##### tools #####
+MAKE := make
+MFLAGS :=
+
+DG := gcc
+DGFLAGS := -MM -std=gnu89
+
+CC := gcc
+CFBASE := -c -pthread -std=gnu89 -Wall -Wno-unknown-pragmas
+CFCOV := -O0 -ggdb -DCOVERAGE -fprofile-arcs -ftest-coverage
+CFDBG := -O0 -ggdb -D_DEBUG
+CFPROF := -O0 -ggdb -DPROF -pg
+CFREL := -O2 -DNDEBUG -finline-functions -Wno-strict-aliasing
+CFTSAN := -O0 -ggdb -DTSAN -fsanitize=thread -fPIE
+
+LD := gcc
+LFBASE := -pthread -std=gnu89 -Wall -Werror
+LFCOV := -O0 -fprofile-arcs -ftest-coverage
+LFDBG := -O0 -ggdb
+LFPROF := -O0 -pg
+LFREL := -O2 -s -finline-functions
+LFTSAN := -O0 -fsanitize=thread -pie
+
+PROF := gprof
+PFBASE := -b -p -Q $(BINARY) gmon.out
+
+##### variants and libnuma check #####
+CFLAGS += $(CFBASE)
+LFLAGS += $(LFBASE)
+
+ifeq ($(MAKECMDGOALS),)
+ CFLAGS += $(CFDBG)
+ LFLAGS += $(LFDBG)
+endif
+
+ifeq ($(MAKECMDGOALS),cov)
+ CFLAGS += $(CFCOV)
+ LFLAGS += $(LFCOV)
+ SYSLIBS += -lgcov
+endif
+
+ifeq ($(MAKECMDGOALS),dbg)
+ CFLAGS += $(CFDBG)
+ LFLAGS += $(LFDBG)
+endif
+
+ifeq ($(MAKECMDGOALS),prof)
+ CFLAGS += $(CFPROF)
+ LFLAGS += $(LFPROF)
+endif
+
+ifeq ($(MAKECMDGOALS),rel)
+ CFLAGS += $(CFREL)
+ LFLAGS += $(LFREL)
+endif
+
+ifeq ($(MAKECMDGOALS),tsan)
+ CFLAGS += $(CFTSAN)
+ LFLAGS += $(LFTSAN)
+endif
+
+##### search paths #####
+vpath %.c $(patsubst %,$(SRCDIR)/%:,$(SRCDIRS))
+
+##### implicit rules #####
+$(OBJDIR)/%.o : %.c
+ $(DG) $(DGFLAGS) $< >$(OBJDIR)/$*.d
+ $(CC) $(CFLAGS) -o $@ $<
+
+##### explicit rules #####
+$(BINARY) : $(OBJECTS)
+ $(LD) -o $(BINARY) $(LFLAGS) $(OBJECTS) $(USRLIBS) $(SYSLIBS)
+ chmod +x $(BINARY)
+
+##### phony #####
+.PHONY : clean cov dbg prof rel tsan
+
+clean :
+ @rm -f $(BINDIR)/$(BINNAME) $(OBJDIR)/*.o $(OBJDIR)/*.d $(OBJDIR)/*.gcno
+
+cov : $(BINARY)
+dbg : $(BINARY)
+prof : $(BINARY)
+rel : $(BINARY)
+tsan : $(BINARY)
+
+genprof :
+ @$(PROF) $(PFBASE)
+
+##### dependencies #####
+-include $(DEPENDS)
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/build/sdk_for_windows_7_and_gnumake/makefile b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/sdk_for_windows_7_and_gnumake/makefile
new file mode 100644
index 0000000000..c54d16635b
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/sdk_for_windows_7_and_gnumake/makefile
@@ -0,0 +1,106 @@
+##### paths #####
+BINDIR := ..\..\bin
+OBJDIR := ..\..\obj
+SRCDIR := ..\..\src
+
+##### misc #####
+QUIETLY := 1>nul 2>nul
+NULL :=
+SPACE := $(NULL) # TRD : necessary trailing space after the close bracket
+
+##### sources, objects and libraries #####
+BINNAME := test
+BINARY := $(BINDIR)\$(BINNAME).exe
+SRCDIRS := .
+SOURCES := main.c misc.c \
+ test_lfds700_btree_addonly_unbalanced.c test_lfds700_btree_addonly_unbalanced_alignment.c test_lfds700_btree_addonly_unbalanced_random_adds_fail.c test_lfds700_btree_addonly_unbalanced_random_adds_fail_and_overwrite.c test_lfds700_btree_addonly_unbalanced_random_adds_overwrite.c \
+ test_lfds700_freelist.c test_lfds700_freelist_alignment.c test_lfds700_freelist_popping.c test_lfds700_freelist_popping_and_pushing.c test_lfds700_freelist_pushing.c test_lfds700_freelist_rapid_popping_and_pushing.c \
+ test_lfds700_hash_addonly.c test_lfds700_hash_addonly_alignment.c test_lfds700_hash_addonly_iterate.c test_lfds700_hash_addonly_random_adds_fail.c test_lfds700_hash_addonly_random_adds_fail_and_overwrite.c test_lfds700_hash_addonly_random_adds_overwrite.c \
+ test_lfds700_list_addonly_ordered_singlylinked.c test_lfds700_list_addonly_ordered_singlylinked_alignment.c test_lfds700_list_addonly_ordered_singlylinked_new_ordered.c test_lfds700_list_addonly_ordered_singlylinked_new_ordered_with_cursor.c \
+ test_lfds700_list_addonly_singlylinked_unordered.c test_lfds700_list_addonly_singlylinked_unordered_alignment.c test_lfds700_list_addonly_singlylinked_unordered_new_after.c test_lfds700_list_addonly_singlylinked_unordered_new_end.c test_lfds700_list_addonly_singlylinked_unordered_new_start.c \
+ test_lfds700_porting_abstraction_layer_atomic.c test_lfds700_porting_abstraction_layer_atomic_cas.c test_lfds700_porting_abstraction_layer_atomic_dcas.c test_lfds700_porting_abstraction_layer_atomic_exchange.c \
+ test_lfds700_queue.c test_lfds700_queue_alignment.c test_lfds700_queue_dequeuing.c test_lfds700_queue_enqueuing.c test_lfds700_queue_enqueuing_and_dequeuing.c test_lfds700_queue_enqueuing_and_dequeuing_with_free.c test_lfds700_queue_enqueuing_with_malloc_and_dequeuing_with_free.c test_lfds700_queue_rapid_enqueuing_and_dequeuing.c \
+ test_lfds700_queue_bounded_singleconsumer_singleproducer.c test_lfds700_queue_bounded_singleconsumer_singleproducer_dequeuing.c test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing.c test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing_and_dequeuing.c \
+ test_lfds700_ringbuffer.c test_lfds700_ringbuffer_reading.c test_lfds700_ringbuffer_reading_and_writing.c test_lfds700_ringbuffer_writing.c \
+ test_lfds700_stack.c test_lfds700_stack_alignment.c test_lfds700_stack_popping.c test_lfds700_stack_popping_and_pushing.c test_lfds700_stack_pushing.c test_lfds700_stack_rapid_popping_and_pushing.c \
+ test_porting_abstraction_layer_get_logical_core_ids.c test_porting_abstraction_layer_thread_start.c test_porting_abstraction_layer_thread_wait.c \
+ util_cmdline.c util_memory_helpers.c util_thread_starter.c
+OBJECTS := $(patsubst %.c,$(OBJDIR)/%.obj,$(notdir $(SOURCES)))
+RESFILE := $(patsubst %.rc,$(OBJDIR)/%.res,$(notdir $(RCFILE)))
+SYSLIBS := kernel32.lib
+EXTLIBS :=
+USRLIBS := ../../../liblfds700/bin/liblfds700.lib
+
+##### default paths fix up #####
+INCLUDE += ;../../../../liblfds700/inc/
+LIB += ;../../../../liblfds700/bin/
+
+##### tools #####
+MAKE := make
+MFLAGS :=
+
+CC := cl
+CFBASE := /c /D_CRT_SECURE_NO_WARNINGS /DWIN32_LEAN_AND_MEAN /DUNICODE /D_UNICODE /DUNICODE "/Fd$(BINDIR)\$(BINNAME).pdb" /nologo /W4 /WX
+CFREL := /DNDEBUG /Ox
+CFDBG := /D_DEBUG /Od /Gm /Zi
+
+LD := link
+LFBASE := /nologo /subsystem:console /nodefaultlib /nxcompat /wx
+LFREL := /incremental:no
+LFDBG := /debug "/pdb:$(BINDIR)\$(BINNAME).pdb"
+
+##### variants #####
+CFLAGS := $(CFBASE) $(CFDBG) /MTd
+LFLAGS := $(LFBASE) $(LFDBG)
+CLIB := libcmtd.lib
+
+ifeq ($(MAKECMDGOALS),librel)
+ CFLAGS := $(CFBASE) $(CFREL) /MT
+ LFLAGS := $(LFBASE) $(LFREL)
+ CLIB := libcmt.lib
+endif
+
+ifeq ($(MAKECMDGOALS),libdbg)
+ CFLAGS := $(CFBASE) $(CFDBG) /MTd
+ LFLAGS := $(LFBASE) $(LFDBG)
+ CLIB := libcmtd.lib
+endif
+
+ifeq ($(MAKECMDGOALS),dllrel)
+ CFLAGS := $(CFBASE) $(CFREL) /MD
+ LFLAGS := $(LFBASE) $(LFREL)
+ CLIB := msvcrt.lib
+endif
+
+ifeq ($(MAKECMDGOALS),dlldbg)
+ CFLAGS := $(CFBASE) $(CFDBG) /MDd
+ LFLAGS := $(LFBASE) $(LFDBG)
+ CLIB := msvcrtd.lib
+endif
+
+##### search paths #####
+vpath %.c $(patsubst %,$(SRCDIR)/%;,$(SRCDIRS))
+
+##### implicit rules #####
+$(OBJDIR)/%.obj : %.c
+ $(CC) $(CFLAGS) "/Fo$@" $<
+
+##### explicit rules #####
+$(BINARY) : $(OBJECTS) $(USRLIBS)
+ $(LD) $(LFLAGS) $(CLIB) $(SYSLIBS) $(EXTLIBS) $(USRLIBS) $(OBJECTS) /out:$(BINARY)
+
+##### phony #####
+.PHONY : clean librel libdbg dllrel dlldbg
+
+clean :
+ @erase /Q $(OBJDIR)\*.obj $(OBJDIR)\*.res $(BINDIR)\$(BINNAME).* $(QUIETLY)
+
+dlldbg : $(BINARY)
+dllrel : $(BINARY)
+
+libdbg : $(BINARY)
+librel : $(BINARY)
+
+##### notes #####
+# TRD : we fix up the default paths because cl and link require an extra argument per additional path, which is ugly as hell
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.sln b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.sln
new file mode 100644
index 0000000000..cc8727482f
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.sln
@@ -0,0 +1,67 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "test", "test.vcxproj", "{A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}"
+ ProjectSection(ProjectDependencies) = postProject
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0} = {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}
+ EndProjectSection
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "liblfds700", "..\..\..\liblfds700\build\visual_studio_professional_2012\liblfds700.vcxproj", "{1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug DLL|Win32 = Debug DLL|Win32
+ Debug DLL|x64 = Debug DLL|x64
+ Debug LIB|Win32 = Debug LIB|Win32
+ Debug LIB|x64 = Debug LIB|x64
+ Release DLL|Win32 = Release DLL|Win32
+ Release DLL|x64 = Release DLL|x64
+ Release LIB|Win32 = Release LIB|Win32
+ Release LIB|x64 = Release LIB|x64
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug DLL|Win32.Deploy.0 = Debug DLL|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug DLL|x64.ActiveCfg = Debug DLL|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug DLL|x64.Build.0 = Debug DLL|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug DLL|x64.Deploy.0 = Debug DLL|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug LIB|Win32.ActiveCfg = Debug LIB|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug LIB|Win32.Build.0 = Debug LIB|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug LIB|Win32.Deploy.0 = Debug LIB|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug LIB|x64.ActiveCfg = Debug LIB|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug LIB|x64.Build.0 = Debug LIB|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Debug LIB|x64.Deploy.0 = Debug LIB|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release DLL|Win32.Build.0 = Release DLL|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release DLL|Win32.Deploy.0 = Release DLL|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release DLL|x64.ActiveCfg = Release DLL|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release DLL|x64.Build.0 = Release DLL|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release DLL|x64.Deploy.0 = Release DLL|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release LIB|Win32.ActiveCfg = Release LIB|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release LIB|Win32.Build.0 = Release LIB|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release LIB|Win32.Deploy.0 = Release LIB|Win32
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release LIB|x64.ActiveCfg = Release LIB|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release LIB|x64.Build.0 = Release LIB|x64
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}.Release LIB|x64.Deploy.0 = Release LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|Win32.Build.0 = Debug DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.ActiveCfg = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug DLL|x64.Build.0 = Debug DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.ActiveCfg = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|Win32.Build.0 = Debug LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.ActiveCfg = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Debug LIB|x64.Build.0 = Debug LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.ActiveCfg = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|Win32.Build.0 = Release DLL|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.ActiveCfg = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release DLL|x64.Build.0 = Release DLL|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.ActiveCfg = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|Win32.Build.0 = Release LIB|Win32
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.ActiveCfg = Release LIB|x64
+ {1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}.Release LIB|x64.Build.0 = Release LIB|x64
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj
new file mode 100644
index 0000000000..3fbf8d78ee
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj
@@ -0,0 +1,554 @@
+
+
+
+
+ Debug DLL
+ Win32
+
+
+ Debug DLL
+ x64
+
+
+ Debug LIB
+ Win32
+
+
+ Debug LIB
+ x64
+
+
+ Release DLL
+ Win32
+
+
+ Release DLL
+ x64
+
+
+ Release LIB
+ Win32
+
+
+ Release LIB
+ x64
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {1e5d7d09-94f2-455d-ae5e-6c7f4c96bce0}
+
+
+
+ {A6BA3A68-A1D4-4C07-A0D5-7EAE73272A43}
+ Win32Proj
+
+
+
+ Application
+ true
+ v110
+
+
+ Application
+ true
+ v110
+
+
+ Application
+ true
+ v110
+
+
+ Application
+ true
+ v110
+
+
+ Application
+ false
+ v110
+
+
+ Application
+ false
+ v110
+
+
+ Application
+ false
+ v110
+
+
+ Application
+ false
+ v110
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ false
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ false
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ false
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ false
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ false
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ false
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ false
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+ false
+ $(ProjectDir)..\..\bin\$(Platform) $(Configuration)\
+ $(ProjectDir)..\..\obj\$(Platform) $(Configuration)\
+
+
+
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ true
+ false
+ false
+ false
+ false
+ NoExtensions
+ false
+ false
+ false
+ true
+ CompileAsC
+ None
+ ..\liblfds700\inc;%(AdditionalIncludeDirectories)
+ true
+
+
+ MachineX86
+ true
+ Console
+ true
+
+
+
+
+ kernel32.lib;%(AdditionalDependencies)
+
+
+
+
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ true
+ false
+ false
+ false
+ false
+ NoExtensions
+ false
+ false
+ false
+ true
+ CompileAsC
+ None
+ ..\liblfds700\inc;%(AdditionalIncludeDirectories)
+ true
+
+
+ MachineX86
+ true
+ Console
+ true
+
+
+
+
+ kernel32.lib;%(AdditionalDependencies)
+
+
+
+
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ true
+ false
+ false
+ false
+ false
+ NotSet
+ false
+ false
+ false
+ true
+ CompileAsC
+ None
+ true
+ false
+
+
+ true
+ Console
+ true
+
+
+ kernel32.lib;%(AdditionalDependencies)
+
+
+
+
+ WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ MultiThreadedDebug
+ Level4
+ ProgramDatabase
+ Disabled
+ false
+ false
+ true
+ true
+ true
+ true
+ true
+ false
+ false
+ false
+ false
+ NotSet
+ false
+ false
+ false
+ true
+ CompileAsC
+ None
+ true
+ false
+
+
+ true
+ Console
+ true
+
+
+ kernel32.lib;%(AdditionalDependencies)
+
+
+ true
+
+
+
+
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ false
+ false
+ CompileAsC
+ true
+
+
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ None
+
+
+ MachineX86
+ false
+ Console
+ true
+ true
+ true
+ true
+ NoErrorReport
+ kernel32.lib;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
+
+
+
+
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ false
+ false
+ CompileAsC
+ true
+
+
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ None
+
+
+ MachineX86
+ false
+ Console
+ true
+ true
+ true
+ true
+ NoErrorReport
+ kernel32.lib;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
+
+
+
+
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ false
+ false
+ CompileAsC
+ true
+
+
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ None
+
+
+ false
+ Console
+ true
+ true
+ true
+ true
+ NoErrorReport
+ kernel32.lib;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
+
+
+
+
+ WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
+ MultiThreaded
+ Level4
+ None
+ false
+ false
+ false
+ false
+ CompileAsC
+ true
+
+
+ true
+ AnySuitable
+ true
+ Speed
+ true
+ true
+ true
+ true
+ false
+ true
+ true
+ false
+ false
+ false
+ None
+
+
+ false
+ Console
+ true
+ true
+ true
+ true
+ NoErrorReport
+ kernel32.lib;%(AdditionalDependencies)
+ UseLinkTimeCodeGeneration
+
+
+
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj.filters b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj.filters
new file mode 100644
index 0000000000..69da4b9836
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj.filters
@@ -0,0 +1,216 @@
+
+
+
+
+ {4FC737F1-C7A5-4376-A066-2A32D752A2FF}
+ cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx
+
+
+ {93995380-89BD-4b04-88EB-625FBE52EBFB}
+ h;hpp;hxx;hm;inl;inc;xsd
+
+
+ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01}
+ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav
+
+
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+ Header Files
+
+
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+ Source Files
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj.user b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj.user
new file mode 100644
index 0000000000..7cbb3216ad
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/build/visual_studio_professional_2012/test.vcxproj.user
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/internal.h b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/internal.h
new file mode 100644
index 0000000000..14bf02c74c
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/internal.h
@@ -0,0 +1,157 @@
+/***** includes *****/
+#define _GNU_SOURCE
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "../../liblfds700/inc/liblfds700.h"
+#include "test_porting_abstraction_layer_operating_system.h"
+
+/***** defines *****/
+#define and &&
+#define or ||
+
+#define NO_FLAGS 0x0
+
+#define BITS_PER_BYTE 8
+
+#define TEST_DURATION_IN_SECONDS 5
+#define TIME_LOOP_COUNT 10000
+#define REDUCED_TIME_LOOP_COUNT 1000
+#define NUMBER_OF_NANOSECONDS_IN_ONE_SECOND 1000000000LLU
+#define ONE_MEGABYTE_IN_BYTES (1024 * 1024)
+#define DEFAULT_TEST_MEMORY_IN_MEGABYTES 512U
+#define TEST_PAL_DEFAULT_NUMA_NODE_ID 0
+#define LFDS700_TEST_VERSION_STRING "7.0.0"
+#define LFDS700_TEST_VERSION_INTEGER 700
+
+#if( defined _KERNEL_MODE )
+ #define MODE_TYPE_STRING "kernel-mode"
+#endif
+
+#if( !defined _KERNEL_MODE )
+ #define MODE_TYPE_STRING "user-mode"
+#endif
+
+#if( defined NDEBUG && !defined COVERAGE && !defined TSAN )
+ #define BUILD_TYPE_STRING "release"
+#endif
+
+#if( !defined NDEBUG && !defined COVERAGE && !defined TSAN )
+ #define BUILD_TYPE_STRING "debug"
+#endif
+
+#if( !defined NDEBUG && defined COVERAGE && !defined TSAN )
+ #define BUILD_TYPE_STRING "coverage"
+#endif
+
+#if( !defined NDEBUG && !defined COVERAGE && defined TSAN )
+ #define BUILD_TYPE_STRING "threadsanitizer"
+#endif
+
+/***** enums *****/
+enum flag
+{
+ LOWERED,
+ RAISED
+};
+
+/***** structs *****/
+struct test_pal_logical_processor
+{
+ lfds700_pal_uint_t
+ logical_processor_number,
+ windows_logical_processor_group_number;
+
+ struct lfds700_list_asu_element
+ lasue;
+};
+
+/***** prototypes *****/
+int main( int argc, char **argv );
+
+void internal_display_test_name( char *format_string, ... );
+void internal_display_test_result( lfds700_pal_uint_t number_name_dvs_pairs, ... );
+void internal_display_data_structure_validity( enum lfds700_misc_validity dvs );
+void internal_show_version( void );
+void internal_logical_core_id_element_cleanup_callback( struct lfds700_list_asu_state *lasus, struct lfds700_list_asu_element *lasue );
+
+int test_pal_thread_start( test_pal_thread_state_t *thread_state, struct test_pal_logical_processor *lp, test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state), void *thread_user_state );
+void test_pal_thread_wait( test_pal_thread_state_t thread_state );
+void test_pal_get_logical_core_ids( struct lfds700_list_asu_state *lasus );
+
+void test_lfds700_pal_atomic( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_pal_atomic_cas( struct lfds700_list_asu_state *list_of_logical_processors );
+ void test_lfds700_pal_atomic_dwcas( struct lfds700_list_asu_state *list_of_logical_processors );
+ void test_lfds700_pal_atomic_exchange( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+
+void test_lfds700_hash_a( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_hash_a_alignment( void );
+ void test_lfds700_hash_a_fail_and_overwrite_on_existing_key( void );
+ void test_lfds700_hash_a_random_adds_fail_on_existing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_hash_a_random_adds_overwrite_on_existing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_hash_a_iterate( void );
+
+void test_lfds700_list_aos( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_list_aos_alignment( void );
+ void test_lfds700_list_aos_new_ordered( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_list_aos_new_ordered_with_cursor( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+
+void test_lfds700_list_asu( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_list_asu_alignment( void );
+ void test_lfds700_list_asu_new_start( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_list_asu_new_end( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_list_asu_new_after( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+
+void test_lfds700_btree_au( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_btree_au_alignment( void );
+ void test_lfds700_btree_au_fail_and_overwrite_on_existing_key( void );
+ void test_lfds700_btree_au_random_adds_fail_on_existing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_btree_au_random_adds_overwrite_on_existing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+
+void test_lfds700_freelist( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_freelist_alignment( void );
+ void test_lfds700_freelist_popping( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_freelist_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_freelist_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_freelist_rapid_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors );
+ void test_lfds700_freelist_pushing_array( void );
+
+void test_lfds700_queue( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_queue_alignment( void );
+ void test_lfds700_queue_enqueuing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_queue_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_queue_enqueuing_and_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors );
+ void test_lfds700_queue_rapid_enqueuing_and_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_queue_enqueuing_and_dequeuing_with_free( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_queue_enqueuing_with_malloc_and_dequeuing_with_free( struct lfds700_list_asu_state *list_of_logical_processors );
+
+void test_lfds700_queue_bss( struct lfds700_list_asu_state *list_of_logical_processors );
+ void test_lfds700_queue_bss_enqueuing( void );
+ void test_lfds700_queue_bss_dequeuing( void );
+ void test_lfds700_queue_bss_enqueuing_and_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors );
+
+void test_lfds700_ringbuffer( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_ringbuffer_reading( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_ringbuffer_reading_and_writing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_ringbuffer_writing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+
+void test_lfds700_stack( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_stack_alignment( void );
+ void test_lfds700_stack_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_stack_popping( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_stack_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes );
+ void test_lfds700_stack_rapid_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors );
+ void test_lfds700_stack_pushing_array( void );
+
+/***** late includes *****/
+#include "util_cmdline.h"
+#include "util_memory_helpers.h"
+#include "util_thread_starter.h"
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/main.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/main.c
new file mode 100644
index 0000000000..fa6afc8747
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/main.c
@@ -0,0 +1,135 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+int main( int argc, char **argv )
+{
+ enum flag
+ run_flag = LOWERED,
+ show_error_flag = LOWERED,
+ show_help_flag = LOWERED,
+ show_version_flag = LOWERED;
+
+ int
+ rv;
+
+ lfds700_pal_uint_t
+ loop,
+ iterations = 1,
+ memory_in_megabytes = DEFAULT_TEST_MEMORY_IN_MEGABYTES;
+
+ struct lfds700_list_asu_state
+ list_of_logical_processors;
+
+ struct util_cmdline_state
+ cs;
+
+ union util_cmdline_arg_data
+ *arg_data;
+
+ assert( argc >= 1 );
+ assert( argv != NULL );
+
+ lfds700_misc_library_init_valid_on_current_logical_core();
+
+ util_cmdline_init( &cs );
+
+ util_cmdline_add_arg( &cs, 'h', LIBCOMMON_CMDLINE_ARG_TYPE_FLAG );
+ util_cmdline_add_arg( &cs, 'i', LIBCOMMON_CMDLINE_ARG_TYPE_INTEGER );
+ util_cmdline_add_arg( &cs, 'm', LIBCOMMON_CMDLINE_ARG_TYPE_INTEGER );
+ util_cmdline_add_arg( &cs, 'r', LIBCOMMON_CMDLINE_ARG_TYPE_FLAG );
+ util_cmdline_add_arg( &cs, 'v', LIBCOMMON_CMDLINE_ARG_TYPE_FLAG );
+
+ rv = util_cmdline_process_args( &cs, argc, argv );
+
+ if( rv == 0 )
+ show_error_flag = RAISED;
+
+ if( rv == 1 )
+ {
+ util_cmdline_get_arg_data( &cs, 'h', &arg_data );
+ if( arg_data != NULL )
+ show_help_flag = RAISED;
+
+ util_cmdline_get_arg_data( &cs, 'i', &arg_data );
+ if( arg_data != NULL )
+ iterations = (lfds700_pal_uint_t) arg_data->integer.integer;
+
+ util_cmdline_get_arg_data( &cs, 'm', &arg_data );
+ if( arg_data != NULL )
+ memory_in_megabytes = (lfds700_pal_uint_t) arg_data->integer.integer;
+
+ util_cmdline_get_arg_data( &cs, 'r', &arg_data );
+ if( arg_data != NULL )
+ run_flag = RAISED;
+
+ util_cmdline_get_arg_data( &cs, 'v', &arg_data );
+ if( arg_data != NULL )
+ show_version_flag = RAISED;
+ }
+
+ util_cmdline_cleanup( &cs );
+
+ if( argc == 1 or (run_flag == LOWERED and show_version_flag == LOWERED) )
+ show_help_flag = RAISED;
+
+ if( show_error_flag == RAISED )
+ {
+ printf( "\nInvalid arguments. Sorry - it's a simple parser, so no clues.\n"
+ "-h or run with no args to see the help text.\n" );
+
+ return( EXIT_SUCCESS );
+ }
+
+ if( show_help_flag == RAISED )
+ {
+ printf( "test -h -i [n] -m [n] -r -v\n"
+ " -h : help\n"
+ " -i [n] : number of iterations (default : 1)\n"
+ " -m [n] : memory for tests, in mb (default : %u)\n"
+ " -r : run (causes test to run; present so no args gives help)\n"
+ " -v : version\n", DEFAULT_TEST_MEMORY_IN_MEGABYTES );
+
+ return( EXIT_SUCCESS );
+ }
+
+ if( show_version_flag == RAISED )
+ {
+ internal_show_version();
+ return( EXIT_SUCCESS );
+ }
+
+ if( run_flag == RAISED )
+ {
+ test_pal_get_logical_core_ids( &list_of_logical_processors );
+
+ for( loop = 0 ; loop < (lfds700_pal_uint_t) iterations ; loop++ )
+ {
+ printf( "\n"
+ "Test Iteration %02llu\n"
+ "=================\n", (int long long unsigned) (loop+1) );
+
+ test_lfds700_pal_atomic( &list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_btree_au( &list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_freelist( &list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_hash_a( &list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_list_aos( &list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_list_asu( &list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_queue( &list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_queue_bss( &list_of_logical_processors );
+ test_lfds700_ringbuffer( &list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_stack( &list_of_logical_processors, memory_in_megabytes );
+ }
+
+ lfds700_list_asu_cleanup( &list_of_logical_processors, internal_logical_core_id_element_cleanup_callback );
+ }
+
+ lfds700_misc_library_cleanup();
+
+ return( EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/misc.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/misc.c
new file mode 100644
index 0000000000..4fa794f68d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/misc.c
@@ -0,0 +1,191 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+void internal_display_test_name( char *format_string, ... )
+{
+ va_list
+ va;
+
+ assert( format_string != NULL );
+
+ va_start( va, format_string );
+
+ vprintf( format_string, va );
+
+ printf( "..." );
+
+ va_end( va );
+
+ fflush( stdout );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void internal_display_test_result( lfds700_pal_uint_t number_name_dvs_pairs, ... )
+{
+ char
+ *name;
+
+ enum flag
+ passed_flag = RAISED;
+
+ enum lfds700_misc_validity
+ dvs;
+
+ lfds700_pal_uint_t
+ loop;
+
+ va_list
+ va;
+
+ // 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++ )
+ {
+ name = va_arg( va, char * );
+ dvs = va_arg( va, enum lfds700_misc_validity );
+
+ if( dvs != LFDS700_MISC_VALIDITY_VALID )
+ {
+ passed_flag = LOWERED;
+ break;
+ }
+ }
+
+ va_end( va );
+
+ if( passed_flag == RAISED )
+ puts( "passed" );
+
+ if( passed_flag == LOWERED )
+ {
+ printf( "failed (" );
+
+ va_start( va, number_name_dvs_pairs );
+
+ for( loop = 0 ; loop < number_name_dvs_pairs ; loop++ )
+ {
+ name = va_arg( va, char * );
+ dvs = va_arg( va, enum lfds700_misc_validity );
+
+ printf( "%s ", name );
+ internal_display_data_structure_validity( dvs );
+
+ if( loop+1 < number_name_dvs_pairs )
+ printf( ", " );
+ }
+
+ va_end( va );
+
+ printf( ")\n" );
+
+ /* TRD : quick hack
+ the whole test programme needs rewriting
+ and for now I just want to make it so we
+ exit with failure upon any test failing
+ */
+
+ exit( EXIT_FAILURE );
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void internal_display_data_structure_validity( enum lfds700_misc_validity dvs )
+{
+ char
+ *string = NULL;
+
+ switch( dvs )
+ {
+ case LFDS700_MISC_VALIDITY_VALID:
+ string = "valid";
+ break;
+
+ case LFDS700_MISC_VALIDITY_INVALID_LOOP:
+ string = "invalid - loop detected";
+ break;
+
+ case LFDS700_MISC_VALIDITY_INVALID_ORDER:
+ string = "invalid - invalid order detected";
+ break;
+
+ case LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS:
+ string = "invalid - missing elements";
+ break;
+
+ case LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS:
+ string = "invalid - additional elements";
+ break;
+
+ case LFDS700_MISC_VALIDITY_INVALID_TEST_DATA:
+ string = "invalid - invalid test data";
+ break;
+ }
+
+ printf( "%s", string );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void internal_show_version()
+{
+ char const
+ *version_and_build_string;
+
+ printf( "test %s (%s, %s) (" __DATE__ " " __TIME__ ")\n", LFDS700_TEST_VERSION_STRING, BUILD_TYPE_STRING, MODE_TYPE_STRING );
+
+ lfds700_misc_query( LFDS700_MISC_QUERY_GET_BUILD_AND_VERSION_STRING, NULL, (void **) &version_and_build_string );
+
+ printf( "%s\n", version_and_build_string );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+void internal_logical_core_id_element_cleanup_callback( struct lfds700_list_asu_state *lasus, struct lfds700_list_asu_element *lasue )
+{
+ struct test_pal_logical_processor
+ *lp;
+
+ assert( lasus != NULL );
+ assert( lasue != NULL );
+
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+
+ util_aligned_free( lp );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced.c
new file mode 100644
index 0000000000..55b94ca5bb
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced.c
@@ -0,0 +1,32 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_btree_au( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_CAS and LFDS700_MISC_ATOMIC_SUPPORT_EXCHANGE )
+ {
+ printf( "\n"
+ "Binary Tree (add-only, unbalanced) Tests\n"
+ "========================================\n" );
+
+ test_lfds700_btree_au_alignment();
+ test_lfds700_btree_au_fail_and_overwrite_on_existing_key();
+ test_lfds700_btree_au_random_adds_fail_on_existing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_btree_au_random_adds_overwrite_on_existing( list_of_logical_processors, memory_in_megabytes );
+ }
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_alignment.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_alignment.c
new file mode 100644
index 0000000000..ecdaf29adb
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_alignment.c
@@ -0,0 +1,64 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_btree_au_alignment()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ /* TRD : these are compile time checks
+ but we do them here because this is a test programme
+ and it should indicate issues to users when it is *run*,
+ not when it is compiled, because a compile error normally
+ indicates a problem with the code itself and so is misleading
+ */
+
+ internal_display_test_name( "Alignment" );
+
+
+
+ // TRD : struct lfds700_btree_au_element
+ if( offsetof(struct lfds700_btree_au_element,up) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_btree_au_element,left) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_btree_au_element,right) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_btree_au_element,key) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_btree_au_element,value) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_btree_au_element,key) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : struct lfds700_btree_au_state
+ if( offsetof(struct lfds700_btree_au_state,root) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_btree_au_state,key_compare_function) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "btree_au", dvs );
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_fail.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_fail.c
new file mode 100644
index 0000000000..ae043a0669
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_fail.c
@@ -0,0 +1,319 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_btree_au_element
+ baue;
+
+ lfds700_pal_uint_t
+ key;
+};
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ insert_fail_count,
+ number_elements;
+
+ struct lfds700_btree_au_state
+ *baus;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static int key_compare_function( void const *new_value, void const *value_in_tree );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_adding( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_btree_au_random_adds_fail_on_existing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ actual_sum_insert_failure_count,
+ expected_sum_insert_failure_count,
+ index = 0,
+ *key_count_array,
+ loop,
+ number_elements,
+ number_logical_processors,
+ random_value,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_btree_au_element
+ *baue = NULL;
+
+ struct lfds700_btree_au_state
+ baus;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ void
+ *key;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a single btree_au
+ we generate 10k elements per thread (one per logical processor) in an array
+ we set a random number in each element, which is the key
+ random numbers are generated are from 0 to 5000, so we must have some duplicates
+ (we don't use value, so we always pass in a NULL for that when we insert)
+
+ each thread loops, adds those elements into the btree, and counts the total number of insert fails
+ (we don't count on a per value basis because of the performance hit - we'll be TLBing all the time)
+ this test has the btree_au set to fail on add, so duplicates should be eliminated
+
+ we then merge the per-thread arrays
+
+ we should find in the tree one of every value, and the sum of the counts of each value (beyond the
+ first value, which was inserted) in the merged arrays should equal the sum of the insert fails from
+ each thread
+
+ we check the count of unique values in the merged array and use that when calling the btree_au validation function
+
+ we in-order walk and check that what we have in the tree matches what we have in the merged array
+ and then check the fail counts
+ */
+
+ internal_display_test_name( "Random adds and walking (fail on existing key)" );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_btree_au_init_valid_on_current_logical_core( &baus, key_compare_function, LFDS700_BTREE_AU_EXISTING_KEY_FAIL, NULL );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->baus = &baus;
+ (ts+loop)->element_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+ (ts+loop)->number_elements = number_elements;
+ (ts+loop)->insert_fail_count = 0;
+
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ {
+ random_value = LFDS700_MISC_PRNG_GENERATE( &ps );
+ ((ts+loop)->element_array+subloop)->key = (lfds700_pal_uint_t) floor( (number_elements/2) * ((double) random_value / (double) LFDS700_MISC_PRNG_MAX) );
+ }
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_adding, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ /* TRD : now for validation
+ make an array equal to number_elements, set all to 0
+ iterate over every per-thread array, counting the number of each value into this array
+ so we can know how many elements ought to have failed to be inserted
+ as well as being able to work out the actual number of elements which should be present in the btree, for the btree validation call
+ */
+
+ key_count_array = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_elements );
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ *(key_count_array+loop) = 0;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ ( *(key_count_array+( (ts+loop)->element_array+subloop)->key) )++;
+
+ // TRD : first, btree validation function
+ vi.min_elements = number_elements;
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ if( *(key_count_array+loop) == 0 )
+ vi.min_elements--;
+
+ vi.max_elements = vi.min_elements;
+
+ lfds700_btree_au_query( &baus, LFDS700_BTREE_AU_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) &dvs );
+
+ /* TRD : now check the sum of per-thread insert failures
+ is what it should be, which is the sum of key_count_array,
+ but with every count minus one (for the single succesful insert)
+ and where elements of 0 are ignored (i.e. do not have -1 applied)
+ */
+
+ expected_sum_insert_failure_count = 0;
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ if( *(key_count_array+loop) != 0 )
+ expected_sum_insert_failure_count += *(key_count_array+loop) - 1;
+
+ actual_sum_insert_failure_count = 0;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ actual_sum_insert_failure_count += (ts+loop)->insert_fail_count;
+
+ if( expected_sum_insert_failure_count != actual_sum_insert_failure_count )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ /* TRD : now compared the combined array and an in-order walk of the tree
+ ignoring array elements with the value 0, we should find an exact match
+ */
+
+ if( dvs == LFDS700_MISC_VALIDITY_VALID )
+ {
+ // TRD : in-order walk over btree_au and check key_count_array matches
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position(&baus, &baue, LFDS700_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
+ {
+ key = LFDS700_BTREE_AU_GET_KEY_FROM_ELEMENT( *baue );
+
+ while( *(key_count_array+index) == 0 )
+ index++;
+
+ if( index++ != (lfds700_pal_uint_t) key )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ }
+ }
+
+ // TRD : cleanup
+ free( key_count_array );
+
+ lfds700_btree_au_cleanup( &baus, NULL );
+
+ // TRD : cleanup
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ util_aligned_free( (ts+loop)->element_array );
+
+ free( ts );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "btree_au", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int key_compare_function( void const *new_key, void const *key_in_tree )
+{
+ int
+ cr = 0;
+
+ // TRD : key_new can be any value in its range
+ // TRD : key_in_tree can be any value in its range
+
+ if( (lfds700_pal_uint_t) new_key < (lfds700_pal_uint_t) key_in_tree )
+ cr = -1;
+
+ if( (lfds700_pal_uint_t) new_key > (lfds700_pal_uint_t) key_in_tree )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_adding( void *util_thread_starter_thread_state )
+{
+ enum lfds700_btree_au_insert_result
+ alr;
+
+ lfds700_pal_uint_t
+ index = 0;
+
+ struct test_state
+ *ts;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( index < ts->number_elements )
+ {
+ LFDS700_BTREE_AU_SET_KEY_IN_ELEMENT( (ts->element_array+index)->baue, (ts->element_array+index)->key );
+ LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( (ts->element_array+index)->baue, 0 );
+ alr = lfds700_btree_au_insert( ts->baus, &(ts->element_array+index)->baue, NULL, &ps );
+
+ if( alr == LFDS700_BTREE_AU_INSERT_RESULT_FAILURE_EXISTING_KEY )
+ ts->insert_fail_count++;
+
+ index++;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_fail_and_overwrite.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_fail_and_overwrite.c
new file mode 100644
index 0000000000..4c638c8600
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_fail_and_overwrite.c
@@ -0,0 +1,140 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** private prototypes *****/
+static int key_compare_function( void const *new_value, void const *value_in_tree );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_btree_au_fail_and_overwrite_on_existing_key()
+{
+ enum lfds700_btree_au_insert_result
+ alr;
+
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ struct lfds700_btree_au_element
+ baue_one,
+ baue_two,
+ *existing_baue;
+
+ struct lfds700_btree_au_state
+ baus;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ void
+ *value;
+
+ /* TRD : the random_adds tests with fail and overwrite don't (can't, not in a performant manner)
+ test that the fail and/or overwrite of user data has *actually* happened - they use the
+ return value from the link function call, rather than empirically observing the final
+ state of the tree
+
+ as such, we now have a couple of single threaded tests where we check that the user data
+ value really is being modified (or not modified, as the case may be)
+ */
+
+ internal_display_test_name( "Fail and overwrite on existing key" );
+
+ lfds700_misc_prng_init( &ps );
+
+ /* TRD : so, we make a tree which is fail on existing
+ add one element, with a known user data
+ we then try to add the same key again, with a different user data
+ the call should fail, and then we get the element by its key
+ and check its user data is unchanged
+ (and confirm the failed link returned the correct existing_baue)
+ that's the first test done
+ */
+
+ lfds700_btree_au_init_valid_on_current_logical_core( &baus, key_compare_function, LFDS700_BTREE_AU_EXISTING_KEY_FAIL, NULL );
+
+ LFDS700_BTREE_AU_SET_KEY_IN_ELEMENT( baue_one, 0 );
+ LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( baue_one, 1 );
+ alr = lfds700_btree_au_insert( &baus, &baue_one, NULL, &ps );
+
+ if( alr != LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ LFDS700_BTREE_AU_SET_KEY_IN_ELEMENT( baue_two, 0 );
+ LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( baue_two, 2 );
+ alr = lfds700_btree_au_insert( &baus, &baue_two, &existing_baue, &ps );
+
+ if( alr != LFDS700_BTREE_AU_INSERT_RESULT_FAILURE_EXISTING_KEY )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( existing_baue != &baue_one )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ value = LFDS700_BTREE_AU_GET_VALUE_FROM_ELEMENT( *existing_baue );
+
+ if( (void *) (lfds700_pal_uint_t) value != (void *) (lfds700_pal_uint_t) 1 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ lfds700_btree_au_cleanup( &baus, NULL );
+
+ /* TRD : second test, make a tree which is overwrite on existing
+ add one element, with a known user data
+ we then try to add the same key again, with a different user data
+ the call should succeed, and then we get the element by its key
+ and check its user data is changed
+ (and confirm the failed link returned the correct existing_baue)
+ that's the secondtest done
+ */
+
+ lfds700_btree_au_init_valid_on_current_logical_core( &baus, key_compare_function, LFDS700_BTREE_AU_EXISTING_KEY_OVERWRITE, NULL );
+
+ LFDS700_BTREE_AU_SET_KEY_IN_ELEMENT( baue_one, 0 );
+ LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( baue_one, 1 );
+ alr = lfds700_btree_au_insert( &baus, &baue_one, NULL, &ps );
+
+ if( alr != LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ LFDS700_BTREE_AU_SET_KEY_IN_ELEMENT( baue_two, 0 );
+ LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( baue_two, 2 );
+ alr = lfds700_btree_au_insert( &baus, &baue_two, NULL, &ps );
+
+ if( alr != LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS_OVERWRITE )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ lfds700_btree_au_cleanup( &baus, NULL );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "btree_au", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int key_compare_function( void const *new_key, void const *key_in_tree )
+{
+ int
+ cr = 0;
+
+ // TRD : key_new can be any value in its range
+ // TRD : key_in_tree can be any value in its range
+
+ if( (lfds700_pal_uint_t) new_key < (lfds700_pal_uint_t) key_in_tree )
+ cr = -1;
+
+ if( (lfds700_pal_uint_t) new_key > (lfds700_pal_uint_t) key_in_tree )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_overwrite.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_overwrite.c
new file mode 100644
index 0000000000..c9b162128b
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_btree_addonly_unbalanced_random_adds_overwrite.c
@@ -0,0 +1,322 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_btree_au_element
+ baue;
+
+ lfds700_pal_uint_t
+ key;
+};
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ insert_existing_count,
+ number_elements;
+
+ struct lfds700_btree_au_state
+ *baus;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static int key_compare_function( void const *new_value, void const *value_in_tree );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_adding( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_btree_au_random_adds_overwrite_on_existing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ actual_sum_insert_existing_count,
+ expected_sum_insert_existing_count,
+ index = 0,
+ *key_count_array,
+ loop,
+ number_elements,
+ number_logical_processors,
+ random_value,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_btree_au_element
+ *baue = NULL;
+
+ struct lfds700_btree_au_state
+ baus;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ void
+ *key;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a single btree_au
+ we generate 10k elements per thread (one per logical processor) in an array
+ we set a random number in each element, which is the key
+ random numbers are generated are from 0 to 5000, so we must have some duplicates
+ (we don't use value, so we always pass in a NULL for that when we insert)
+
+ each thread loops, adds those elements into the btree, and counts the total number of insert fails
+ (we don't count on a per value basis because of the performance hit - we'll be TLBing all the time)
+ this test has the btree_au set to overwrite on add, so duplicates should be eliminated
+
+ we then merge the per-thread arrays
+
+ we should find in the tree one of every value, and the sum of the counts of each value (beyond the
+ first value, which was inserted) in the merged arrays should equal the sum of the existing_baues returned
+ from each thread when they inserted and found an existing element
+
+ we check the count of unique values in the merged array and use that when calling the btree_au validation function
+
+ we in-order walk and check that what we have in the tree matches what we have in the merged array
+ and then check the fail counts
+ */
+
+ internal_display_test_name( "Random adds and walking (overwrite on existing key)" );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_btree_au_init_valid_on_current_logical_core( &baus, key_compare_function, LFDS700_BTREE_AU_EXISTING_KEY_OVERWRITE, NULL );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->baus = &baus;
+ (ts+loop)->element_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+ (ts+loop)->number_elements = number_elements;
+ (ts+loop)->insert_existing_count = 0;
+
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ {
+ random_value = LFDS700_MISC_PRNG_GENERATE( &ps );
+ ((ts+loop)->element_array+subloop)->key = (lfds700_pal_uint_t) floor( (number_elements/2) * ((double) random_value / (double) LFDS700_MISC_PRNG_MAX) );
+ }
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_adding, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ /* TRD : now for validation
+ make an array equal to number_elements, set all to 0
+ iterate over every per-thread array, counting the number of each value into this array
+ so we can know how many elements ought to have failed to be inserted
+ as well as being able to work out the actual number of elements which should be present in the btree, for the btree validation call
+ */
+
+ key_count_array = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_elements );
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ *(key_count_array+loop) = 0;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ ( *(key_count_array+( (ts+loop)->element_array+subloop)->key) )++;
+
+ // TRD : first, btree validation function
+ vi.min_elements = number_elements;
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ if( *(key_count_array+loop) == 0 )
+ vi.min_elements--;
+
+ vi.max_elements = vi.min_elements;
+
+ lfds700_btree_au_query( &baus, LFDS700_BTREE_AU_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) &dvs );
+
+ /* TRD : now check the sum of per-thread insert failures
+ is what it should be, which is the sum of key_count_array,
+ but with every count minus one (for the single succesful insert)
+ and where elements of 0 are ignored (i.e. do not have -1 applied)
+ */
+
+ expected_sum_insert_existing_count = 0;
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ if( *(key_count_array+loop) != 0 )
+ expected_sum_insert_existing_count += *(key_count_array+loop) - 1;
+
+ actual_sum_insert_existing_count = 0;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ actual_sum_insert_existing_count += (ts+loop)->insert_existing_count;
+
+ if( expected_sum_insert_existing_count != actual_sum_insert_existing_count )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ /* TRD : now compared the combined array and an in-order walk of the tree
+ ignoring array elements with the value 0, we should find an exact match
+ */
+
+ if( dvs == LFDS700_MISC_VALIDITY_VALID )
+ {
+ // TRD : in-order walk over btree_au and check key_count_array matches
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_btree_au_get_by_absolute_position_and_then_by_relative_position(&baus, &baue, LFDS700_BTREE_AU_ABSOLUTE_POSITION_SMALLEST_IN_TREE, LFDS700_BTREE_AU_RELATIVE_POSITION_NEXT_LARGER_ELEMENT_IN_ENTIRE_TREE) )
+ {
+ key = LFDS700_BTREE_AU_GET_KEY_FROM_ELEMENT( *baue );
+
+ while( *(key_count_array+index) == 0 )
+ index++;
+
+ if( index++ != (lfds700_pal_uint_t) key )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ }
+ }
+
+ // TRD : cleanup
+ free( key_count_array );
+
+ lfds700_btree_au_cleanup( &baus, NULL );
+
+ // TRD : cleanup
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ util_aligned_free( (ts+loop)->element_array );
+
+ free( ts );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "btree_au", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int key_compare_function( void const *new_key, void const *key_in_tree )
+{
+ int
+ cr = 0;
+
+ // TRD : key_new can be any value in its range
+ // TRD : key_in_tree can be any value in its range
+
+ if( (lfds700_pal_uint_t) new_key < (lfds700_pal_uint_t) key_in_tree )
+ cr = -1;
+
+ if( (lfds700_pal_uint_t) new_key > (lfds700_pal_uint_t) key_in_tree )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_adding( void *util_thread_starter_thread_state )
+{
+ enum lfds700_btree_au_insert_result
+ alr;
+
+ lfds700_pal_uint_t
+ index = 0;
+
+ struct test_state
+ *ts;
+
+ struct lfds700_btree_au_element
+ *existing_baue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( index < ts->number_elements )
+ {
+ LFDS700_BTREE_AU_SET_KEY_IN_ELEMENT( (ts->element_array+index)->baue, (ts->element_array+index)->key );
+ LFDS700_BTREE_AU_SET_VALUE_IN_ELEMENT( (ts->element_array+index)->baue, 0 );
+ alr = lfds700_btree_au_insert( ts->baus, &(ts->element_array+index)->baue, &existing_baue, &ps );
+
+ if( alr == LFDS700_BTREE_AU_INSERT_RESULT_SUCCESS_OVERWRITE )
+ ts->insert_existing_count++;
+
+ index++;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist.c
new file mode 100644
index 0000000000..1968ae7167
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist.c
@@ -0,0 +1,33 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_freelist( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_DWCAS )
+ {
+ printf( "\n"
+ "Freelist Tests\n"
+ "==============\n" );
+
+ test_lfds700_freelist_alignment();
+ test_lfds700_freelist_popping( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_freelist_pushing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_freelist_popping_and_pushing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_freelist_rapid_popping_and_pushing( list_of_logical_processors );
+ }
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_alignment.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_alignment.c
new file mode 100644
index 0000000000..885ecbf8c4
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_alignment.c
@@ -0,0 +1,43 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_freelist_alignment()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ /* TRD : these are compile time checks
+ but we do them here because this is a test programme
+ and it should indicate issues to users when it is *run*,
+ not when it is compiled, because a compile error normally
+ indicates a problem with the code itself and so is misleading
+ */
+
+ internal_display_test_name( "Alignment" );
+
+
+
+ // TRD : struct lfds700_freelist_state
+ if( offsetof(struct lfds700_freelist_state,top) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_freelist_state,user_state) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "freelist", dvs );
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_popping.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_popping.c
new file mode 100644
index 0000000000..6dcbd0847a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_popping.c
@@ -0,0 +1,205 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ struct lfds700_freelist_state
+ *fs;
+};
+
+struct test_element
+{
+ struct lfds700_freelist_element
+ fe;
+
+ enum flag
+ popped_flag;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_freelist_popping( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_freelist_state
+ fs;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi = { 0, 0 };
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a freelist with 1,000,000 elements
+
+ the creation function runs in a single thread and creates
+ and pushes those elements onto the freelist
+
+ each element contains a void pointer to the container test element
+
+ we then run one thread per CPU
+ where each thread loops, popping as quickly as possible
+ each test element has a flag which indicates it has been popped
+
+ the threads run till the source freelist is empty
+
+ we then check the test elements
+ every element should have been popped
+
+ then tidy up
+
+ we have no extra code for CAS/GC as we're only popping
+ */
+
+ internal_display_test_name( "Popping" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_freelist_init_valid_on_current_logical_core( &fs, NULL );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct test_element);
+
+ te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ {
+ (te_array+loop)->popped_flag = LOWERED;
+ LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( (te_array+loop)->fe, te_array+loop );
+ lfds700_freelist_push( &fs, &(te_array+loop)->fe, &ps );
+ }
+
+ ts = util_aligned_malloc( sizeof(struct test_state) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ (ts+loop)->fs = &fs;
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_popping, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lfds700_freelist_query( &fs, LFDS700_FREELIST_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ // TRD : now we check each element has popped_flag set to RAISED
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ if( (te_array+loop)->popped_flag == LOWERED )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ // TRD : cleanup
+ lfds700_freelist_cleanup( &fs, NULL );
+ util_aligned_free( ts );
+ util_aligned_free( te_array );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "freelist", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state )
+{
+ struct lfds700_freelist_element
+ *fe;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_element
+ *te;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( lfds700_freelist_pop(ts->fs, &fe, &ps) )
+ {
+ te = LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
+ te->popped_flag = RAISED;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_popping_and_pushing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_popping_and_pushing.c
new file mode 100644
index 0000000000..8c411151d3
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_popping_and_pushing.c
@@ -0,0 +1,319 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element;
+
+struct test_state
+{
+ struct lfds700_freelist_state
+ fs_thread_local,
+ *fs;
+
+ lfds700_pal_uint_t
+ number_elements;
+
+ struct test_element
+ *fs_thread_local_te_array;
+};
+
+struct test_element
+{
+ struct lfds700_freelist_element
+ fe,
+ thread_local_fe;
+
+ lfds700_pal_uint_t
+ datum;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping_and_pushing_start_popping( void *util_thread_starter_thread_state );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping_and_pushing_start_pushing( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_freelist_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_freelist_state
+ fs;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we have two threads per CPU
+ the threads loop for ten seconds
+ the first thread pushes 10000 elements then pops 10000 elements
+ the second thread pops 10000 elements then pushes 10000 elements
+ all pushes and pops go onto the single main freelist
+ with a per-thread local freelist to store the pops
+
+ after time is up, all threads push what they have remaining onto
+ the main freelist
+
+ we then validate the main freelist
+ */
+
+ internal_display_test_name( "Popping and pushing (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors * 2 );
+
+ lfds700_freelist_init_valid_on_current_logical_core( &fs, NULL );
+
+ // TRD : we allocate half the total elements here, and half again later, which is why *2 above, but not here
+ te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ // TRD : initial elements in the main freelist so the popping threads can start immediately
+ for( loop = 0 ; loop < number_elements * number_logical_processors ; loop++ )
+ {
+ (te_array+loop)->datum = loop;
+ LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( (te_array+loop)->fe, te_array+loop );
+ lfds700_freelist_push( &fs, &(te_array+loop)->fe, &ps );
+ }
+
+ ts = util_aligned_malloc( sizeof(struct test_state) * number_logical_processors * 2, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ // TRD : first set of threads (poppers)
+ (ts+loop)->fs = &fs;
+ (ts+loop)->number_elements = number_elements;
+ lfds700_freelist_init_valid_on_current_logical_core( &(ts+loop)->fs_thread_local, NULL );
+
+ // TRD : second set of threads (pushers - who need elements in their per-thread freelists)
+ (ts+loop+number_logical_processors)->fs = &fs;
+ (ts+loop+number_logical_processors)->number_elements = number_elements;
+ lfds700_freelist_init_valid_on_current_logical_core( &(ts+loop+number_logical_processors)->fs_thread_local, NULL );
+
+ // TRD : fill the pushing thread freelists
+ (ts+loop+number_logical_processors)->fs_thread_local_te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ {
+ ((ts+loop+number_logical_processors)->fs_thread_local_te_array+subloop)->datum = loop;
+ LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( ((ts+loop+number_logical_processors)->fs_thread_local_te_array+subloop)->thread_local_fe, (ts+loop+number_logical_processors)->fs_thread_local_te_array+subloop );
+ lfds700_freelist_push( &(ts+loop+number_logical_processors)->fs_thread_local, &((ts+loop+number_logical_processors)->fs_thread_local_te_array+subloop)->thread_local_fe, &ps );
+ }
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors * 2 );
+
+ util_thread_starter_new( &tts, number_logical_processors * 2 );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_popping_and_pushing_start_popping, ts+loop );
+ util_thread_starter_start( tts, &thread_handles[loop+number_logical_processors], loop+number_logical_processors, lp, thread_popping_and_pushing_start_pushing, ts+loop+number_logical_processors );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors * 2 ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_elements * number_logical_processors * 2;
+
+ lfds700_freelist_query( &fs, LFDS700_FREELIST_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) &dvs );
+
+ lfds700_freelist_cleanup( &fs, NULL );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ lfds700_freelist_cleanup( &(ts+loop)->fs_thread_local, NULL );
+ lfds700_freelist_cleanup( &(ts+loop+number_logical_processors)->fs_thread_local, NULL );
+ util_aligned_free( (ts+loop+number_logical_processors)->fs_thread_local_te_array );
+ }
+
+ util_aligned_free( ts );
+
+ util_aligned_free( te_array );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "freelist", dvs );
+
+ return;
+}
+
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping_and_pushing_start_popping( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ count;
+
+ struct lfds700_freelist_element
+ *fe;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ struct test_state
+ *ts;
+
+ time_t
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ start_time = time( NULL );
+
+ while( time(NULL) < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ count = 0;
+
+ while( count < ts->number_elements )
+ if( lfds700_freelist_pop(ts->fs, &fe, &ps) )
+ {
+ // TRD : we do nothing with the test data, so there'ss no GET or SET here
+ lfds700_freelist_push( &ts->fs_thread_local, fe, &ps );
+ count++;
+ }
+
+ // TRD : return our local freelist to the main freelist
+ while( lfds700_freelist_pop(&ts->fs_thread_local, &fe, &ps) )
+ lfds700_freelist_push( ts->fs, fe, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping_and_pushing_start_pushing( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ count;
+
+ struct lfds700_freelist_element
+ *fe;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ start_time = time( NULL );
+
+ while( time(NULL) < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ // TRD : return our local freelist to the main freelist
+ while( lfds700_freelist_pop(&ts->fs_thread_local, &fe, &ps) )
+ lfds700_freelist_push( ts->fs, fe, &ps );
+
+ count = 0;
+
+ while( count < ts->number_elements )
+ if( lfds700_freelist_pop(ts->fs, &fe, &ps) )
+ {
+ lfds700_freelist_push( &ts->fs_thread_local, fe, &ps );
+ count++;
+ }
+ }
+
+ // TRD : now push whatever we have in our local freelist
+ while( lfds700_freelist_pop(&ts->fs_thread_local, &fe, &ps) )
+ lfds700_freelist_push( ts->fs, fe, &ps );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_pushing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_pushing.c
new file mode 100644
index 0000000000..0e756c5e2d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_pushing.c
@@ -0,0 +1,246 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements,
+ thread_number;
+
+ struct lfds700_freelist_state
+ *fs;
+
+ struct test_element
+ *te_array;
+};
+
+struct test_element
+{
+ struct lfds700_freelist_element
+ fe;
+
+ lfds700_pal_uint_t
+ datum,
+ thread_number;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_pushing( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_freelist_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors,
+ *per_thread_counters;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_freelist_element
+ *fe;
+
+ struct lfds700_freelist_state
+ fs;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te,
+ *first_te = NULL;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create an empty freelist
+
+ we then create one thread per CPU, where each thread
+ pushes 100,000 elements each as quickly as possible to the freelist
+
+ the data pushed is a counter and a thread ID
+
+ the threads exit when the freelist is full
+
+ we then validate the freelist;
+
+ checking that the counts increment on a per unique ID basis
+ and that the number of elements we pop equals 100,000 per thread
+ (since each element has an incrementing counter which is
+ unique on a per unique ID basis, we can know we didn't lose
+ any elements)
+ */
+
+ internal_display_test_name( "Pushing" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+
+ // TRD : the main freelist
+ lfds700_freelist_init_valid_on_current_logical_core( &fs, NULL );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->fs = &fs;
+ (ts+loop)->thread_number = loop;
+ (ts+loop)->number_elements = number_elements;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_pushing, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ *(per_thread_counters+loop) = number_elements - 1;
+
+ vi.min_elements = vi.max_elements = number_elements * number_logical_processors;
+
+ lfds700_freelist_query( &fs, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_freelist_pop(&fs, &fe, &ps) )
+ {
+ te = LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
+
+ if( first_te == NULL )
+ first_te = te;
+
+ if( te->thread_number >= number_logical_processors )
+ {
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ break;
+ }
+
+ if( te->datum > per_thread_counters[te->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( te->datum < per_thread_counters[te->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( te->datum == per_thread_counters[te->thread_number] )
+ per_thread_counters[te->thread_number]--;
+ }
+
+ // TRD : clean up
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ util_aligned_free( (ts+loop)->te_array );
+
+ free( per_thread_counters );
+
+ free( ts );
+
+ lfds700_freelist_cleanup( &fs, NULL );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "freelist", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_pushing( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ ts->te_array = util_aligned_malloc( sizeof(struct test_element) * ts->number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ (ts->te_array+loop)->thread_number = ts->thread_number;
+ (ts->te_array+loop)->datum = loop;
+ }
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( (ts->te_array+loop)->fe, ts->te_array+loop );
+ lfds700_freelist_push( ts->fs, &(ts->te_array+loop)->fe, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_rapid_popping_and_pushing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_rapid_popping_and_pushing.c
new file mode 100644
index 0000000000..15a0f9fd69
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_freelist_rapid_popping_and_pushing.c
@@ -0,0 +1,216 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ struct lfds700_freelist_state
+ *fs;
+};
+
+struct test_element
+{
+ struct lfds700_freelist_element
+ fe;
+
+ lfds700_pal_uint_t
+ datum;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_freelist_rapid_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_logical_processors;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_freelist_state
+ fs;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi = { 0, 0 };
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+
+ /* TRD : in these tests there is a fundamental antagonism between
+ how much checking/memory clean up that we do and the
+ likelyhood of collisions between threads in their lock-free
+ operations
+
+ the lock-free operations are very quick; if we do anything
+ much at all between operations, we greatly reduce the chance
+ of threads colliding
+
+ so we have some tests which do enough checking/clean up that
+ they can tell the freelist is valid and don't leak memory
+ and here, this test now is one of those which does minimal
+ checking - in fact, the nature of the test is that you can't
+ do any real checking - but goes very quickly
+
+ what we do is create a small freelist and then run one thread
+ per CPU, where each thread simply pushes and then immediately
+ pops
+
+ the test runs for ten seconds
+
+ after the test is done, the only check we do is to traverse
+ the freelist, checking for loops and ensuring the number of
+ elements is correct
+ */
+
+ internal_display_test_name( "Rapid popping and pushing (10 seconds)" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_freelist_init_valid_on_current_logical_core( &fs, NULL );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ (ts+loop)->fs = &fs;
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ // TRD : we need one element per thread
+ te_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( (te_array+loop)->fe, te_array+loop );
+ lfds700_freelist_push( &fs, &(te_array+loop)->fe, &ps );
+ }
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_rapid_popping_and_pushing, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_logical_processors;
+
+ lfds700_freelist_query( &fs, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ lfds700_freelist_cleanup( &fs, NULL );
+
+ util_aligned_free( te_array );
+
+ free( ts );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "freelist", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ time_loop = 0;
+
+ struct lfds700_freelist_element
+ *fe;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ lfds700_freelist_pop( ts->fs, &fe, &ps );
+ lfds700_freelist_push( ts->fs, fe, &ps );
+
+ if( time_loop++ == TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly.c
new file mode 100644
index 0000000000..eeb98727c5
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly.c
@@ -0,0 +1,33 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_hash_a( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_CAS )
+ {
+ printf( "\n"
+ "Hash (add-only) Tests\n"
+ "=====================\n" );
+
+ test_lfds700_hash_a_alignment();
+ test_lfds700_hash_a_fail_and_overwrite_on_existing_key();
+ test_lfds700_hash_a_random_adds_fail_on_existing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_hash_a_random_adds_overwrite_on_existing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_hash_a_iterate();
+ }
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_alignment.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_alignment.c
new file mode 100644
index 0000000000..2d0a0a5b8e
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_alignment.c
@@ -0,0 +1,40 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_hash_a_alignment()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ /* TRD : these are compile time checks
+ but we do them here because this is a test programme
+ and it should indicate issues to users when it is *run*,
+ not when it is compiled, because a compile error normally
+ indicates a problem with the code itself and so is misleading
+ */
+
+ internal_display_test_name( "Alignment" );
+
+
+
+ // TRD : struct lfds700_hash_a_element
+ if( offsetof(struct lfds700_hash_a_element,value) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "freelist", dvs );
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_iterate.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_iterate.c
new file mode 100644
index 0000000000..cf4899e31b
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_iterate.c
@@ -0,0 +1,224 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_btree_au_element
+ baue;
+
+ lfds700_pal_uint_t
+ datum;
+};
+
+struct test_state
+{
+ enum lfds700_misc_flag
+ error_flag;
+
+ struct lfds700_hash_a_state
+ *has;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static int key_compare_function( void const *new_key, void const *existing_key );
+static void key_hash_function( void const *key, lfds700_pal_uint_t *hash );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_hash_a_iterate( void )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ *counter_array,
+ loop;
+
+ struct lfds700_hash_a_element
+ *hae;
+
+ struct lfds700_hash_a_iterate
+ hai;
+
+ struct lfds700_hash_a_state
+ has;
+
+ struct lfds700_hash_a_element
+ *element_array;
+
+ struct lfds700_btree_au_state
+ *baus;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ void
+ *value;
+
+ /* TRD : single-threaded test
+ we create a single hash_a
+ we populate with 1000 elements
+ where key and value is the number of the element (e.g. 0 to 999)
+ we then allocate 1000 counters, init to 0
+ we then iterate
+ we increment each element as we see it in the iterate
+ if any are missing or seen more than once, problemo!
+
+ we do this once with a table of 10, to ensure each table has (or almost certainly has) something in
+ and then a second tiem with a table of 10000, to ensure some empty tables exist
+ */
+
+ internal_display_test_name( "Iterate" );
+
+ lfds700_misc_prng_init( &ps );
+
+ element_array = util_aligned_malloc( sizeof(struct lfds700_hash_a_element) * 1000, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ counter_array = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * 1000 );
+
+ // TRD : first time around
+ baus = util_aligned_malloc( sizeof(struct lfds700_btree_au_state) * 10, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_hash_a_init_valid_on_current_logical_core( &has, baus, 10, key_compare_function, key_hash_function, LFDS700_HASH_A_EXISTING_KEY_FAIL, NULL );
+
+ for( loop = 0 ; loop < 1000 ; loop++ )
+ {
+ LFDS700_HASH_A_SET_KEY_IN_ELEMENT( *(element_array+loop), loop );
+ LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( *(element_array+loop), loop );
+ lfds700_hash_a_insert( &has, element_array+loop, NULL, &ps );
+ }
+
+ for( loop = 0 ; loop < 1000 ; loop++ )
+ *(counter_array+loop) = 0;
+
+ lfds700_hash_a_iterate_init( &has, &hai );
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_hash_a_iterate(&hai, &hae) )
+ {
+ value = LFDS700_HASH_A_GET_VALUE_FROM_ELEMENT( *hae );
+ ( *(counter_array + (lfds700_pal_uint_t) value) )++;
+ }
+
+ if( dvs == LFDS700_MISC_VALIDITY_VALID )
+ for( loop = 0 ; loop < 1000 ; loop++ )
+ {
+ if( *(counter_array+loop) > 1 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( *(counter_array+loop) == 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+ }
+
+ lfds700_hash_a_cleanup( &has, NULL );
+
+ util_aligned_free( baus );
+
+ // TRD : second time around
+ if( dvs == LFDS700_MISC_VALIDITY_VALID )
+ {
+ baus = util_aligned_malloc( sizeof(struct lfds700_btree_au_state) * 10000, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_hash_a_init_valid_on_current_logical_core( &has, baus, 10000, key_compare_function, key_hash_function, LFDS700_HASH_A_EXISTING_KEY_FAIL, NULL );
+
+ for( loop = 0 ; loop < 1000 ; loop++ )
+ {
+ LFDS700_HASH_A_SET_KEY_IN_ELEMENT( *(element_array+loop), loop );
+ LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( *(element_array+loop), loop );
+ lfds700_hash_a_insert( &has, element_array+loop, NULL, &ps );
+ }
+
+ for( loop = 0 ; loop < 1000 ; loop++ )
+ *(counter_array+loop) = 0;
+
+ lfds700_hash_a_iterate_init( &has, &hai );
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_hash_a_iterate(&hai, &hae) )
+ {
+ value = LFDS700_HASH_A_GET_VALUE_FROM_ELEMENT( *hae );
+ ( *(counter_array + (lfds700_pal_uint_t) value ) )++;
+ }
+
+ if( dvs == LFDS700_MISC_VALIDITY_VALID )
+ for( loop = 0 ; loop < 1000 ; loop++ )
+ {
+ if( *(counter_array+loop) > 1 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( *(counter_array+loop) == 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+ }
+
+ lfds700_hash_a_cleanup( &has, NULL );
+
+ util_aligned_free( baus );
+ }
+
+ // TRD : cleanup
+ util_aligned_free( element_array );
+ free( counter_array );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "hash_a", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int key_compare_function( void const *new_key, void const *existing_key )
+{
+ int
+ cr = 0;
+
+ // TRD : new_key can be NULL (i.e. 0)
+ // TRD : existing_key can be NULL (i.e. 0)
+
+ if( (lfds700_pal_uint_t) new_key < (lfds700_pal_uint_t) existing_key )
+ cr = -1;
+
+ if( (lfds700_pal_uint_t) new_key > (lfds700_pal_uint_t) existing_key )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void key_hash_function( void const *key, lfds700_pal_uint_t *hash )
+{
+ // TRD : key can be NULL
+ assert( hash != NULL );
+
+ *hash = 0;
+
+ /* TRD : this function iterates over the user data
+ and we are using the void pointer AS user data
+ so here we need to pass in the addy of value
+ */
+
+ LFDS700_HASH_A_32BIT_HASH_FUNCTION( (void *) &key, sizeof(lfds700_pal_uint_t), *hash );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_fail.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_fail.c
new file mode 100644
index 0000000000..5d36e47a31
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_fail.c
@@ -0,0 +1,314 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_hash_a_element
+ hae;
+
+ lfds700_pal_uint_t
+ datum,
+ key;
+};
+
+struct test_state
+{
+ enum flag
+ error_flag;
+
+ lfds700_pal_uint_t
+ number_elements_per_thread;
+
+ struct lfds700_hash_a_state
+ *has;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_adding( void *util_thread_starter_thread_state );
+static int key_compare_function( void const *new_key, void const *existing_key );
+static void key_hash_function( void const *key, lfds700_pal_uint_t *hash );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_hash_a_random_adds_fail_on_existing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements_per_thread,
+ number_elements_total,
+ number_logical_processors,
+ offset,
+ temp,
+ value;
+
+ struct lfds700_hash_a_element
+ *hae;
+
+ struct lfds700_hash_a_state
+ has;
+
+ struct lfds700_list_asu_element
+ *lasue = NULL;
+
+ struct lfds700_btree_au_state
+ *baus;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *element_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a single hash_a
+ we generate 100k elements per thread (with one thread per logical processor) in an array
+ each element is unique
+ we randomly sort the elements
+ then each thread loops, adds those elements into the hash_a
+ we check that each datum inserts okay - failure will occur on non-unique data, i.e. two identical keys
+ we should have no failures
+ we then call the hash_a validation function
+ then using the hash_a get() we check all the elements we added are present
+ */
+
+ internal_display_test_name( "Random adds and get (fail on existing key)" );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ baus = util_aligned_malloc( sizeof(struct lfds700_btree_au_state) * 1000, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_hash_a_init_valid_on_current_logical_core( &has, baus, 1000, key_compare_function, key_hash_function, LFDS700_HASH_A_EXISTING_KEY_FAIL, NULL );
+
+ number_elements_per_thread = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+ number_elements_total = number_elements_per_thread * number_logical_processors;
+
+ // TRD : created an ordered list of unique numbers
+ element_array = util_aligned_malloc( sizeof(struct test_element) * number_elements_total, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ {
+ (element_array+loop)->key = loop;
+ // TRD : + number_elements just to make it different to the key
+ (element_array+loop)->datum = loop + number_elements_total;
+ }
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ {
+ offset = LFDS700_MISC_PRNG_GENERATE( &ps );
+ offset %= number_elements_total;
+ temp = (element_array + offset)->key;
+ (element_array + offset)->key = (element_array + loop)->key;
+ (element_array + loop)->key = temp;
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->has = &has;
+ (ts+loop)->element_array = element_array + number_elements_per_thread*loop;
+ (ts+loop)->error_flag = LOWERED;
+ (ts+loop)->number_elements_per_thread = number_elements_per_thread;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_adding, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ // TRD : now for validation
+ vi.min_elements = vi.max_elements = number_elements_total;
+ lfds700_hash_a_query( &has, LFDS700_HASH_A_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) &dvs );
+
+ /* TRD : now we attempt to lfds700_hash_a_get_by_key() for every element in number_array
+ any failure to find is an error
+ we also check we've obtained the correct element
+ */
+
+ for( loop = 0 ; dvs == LFDS700_MISC_VALIDITY_VALID and loop < number_elements_total ; loop++ )
+ if( 0 == lfds700_hash_a_get_by_key(&has, (void *) (ts->element_array+loop)->key, &hae) )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+ else
+ {
+ value = (lfds700_pal_uint_t) LFDS700_HASH_A_GET_VALUE_FROM_ELEMENT( *hae );
+ if( (ts->element_array+loop)->datum != value )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ }
+
+ // TRD : just check error_flags weren't raised
+ if( dvs == LFDS700_MISC_VALIDITY_VALID )
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ if( (ts+loop)->error_flag == RAISED )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ // TRD : cleanup
+ lfds700_hash_a_cleanup( &has, NULL );
+
+ util_aligned_free( baus );
+
+ free( ts );
+
+ util_aligned_free( element_array );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "hash_a", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_adding( void *util_thread_starter_thread_state )
+{
+ enum lfds700_hash_a_insert_result
+ apr;
+
+ lfds700_pal_uint_t
+ index = 0;
+
+ struct test_state
+ *ts;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( index < ts->number_elements_per_thread )
+ {
+ LFDS700_HASH_A_SET_KEY_IN_ELEMENT( (ts->element_array+index)->hae, (ts->element_array+index)->key );
+ LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( (ts->element_array+index)->hae, (ts->element_array+index)->datum );
+ apr = lfds700_hash_a_insert( ts->has, &(ts->element_array+index)->hae, NULL, &ps );
+
+ if( apr == LFDS700_HASH_A_PUT_RESULT_FAILURE_EXISTING_KEY )
+ ts->error_flag = RAISED;
+
+ index++;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int key_compare_function( void const *new_key, void const *existing_key )
+{
+ int
+ cr = 0;
+
+ // TRD : new_key can be NULL (i.e. 0)
+ // TRD : existing_key can be NULL (i.e. 0)
+
+ if( (lfds700_pal_uint_t) new_key < (lfds700_pal_uint_t) existing_key )
+ cr = -1;
+
+ if( (lfds700_pal_uint_t) new_key > (lfds700_pal_uint_t) existing_key )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void key_hash_function( void const *key, lfds700_pal_uint_t *hash )
+{
+ // TRD : key can be NULL
+ assert( hash != NULL );
+
+ *hash = 0;
+
+ /* TRD : this function iterates over the user data
+ and we are using the void pointer *as* key data
+ so here we need to pass in the addy of key
+ */
+
+ LFDS700_HASH_A_32BIT_HASH_FUNCTION( (void *) &key, sizeof(lfds700_pal_uint_t), *hash );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_fail_and_overwrite.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_fail_and_overwrite.c
new file mode 100644
index 0000000000..cc18900273
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_fail_and_overwrite.c
@@ -0,0 +1,137 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** private prototypes *****/
+static int key_compare_function( void const *new_value, void const *value_in_tree );
+static void key_hash_function( void const *key, lfds700_pal_uint_t *hash );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_hash_a_fail_and_overwrite_on_existing_key()
+{
+ enum lfds700_hash_a_insert_result
+ apr;
+
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ struct lfds700_hash_a_element
+ hae_one,
+ hae_two;
+
+ struct lfds700_hash_a_state
+ has;
+
+ struct lfds700_btree_au_state
+ *baus;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ internal_display_test_name( "Fail and overwrite on existing key" );
+
+ lfds700_misc_prng_init( &ps );
+
+ baus = util_aligned_malloc( sizeof(struct lfds700_btree_au_state) * 10, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ // TRD : fail on overwrite
+ lfds700_hash_a_init_valid_on_current_logical_core( &has, baus, 10, key_compare_function, key_hash_function, LFDS700_HASH_A_EXISTING_KEY_FAIL, NULL );
+
+ LFDS700_HASH_A_SET_KEY_IN_ELEMENT( hae_one, 1 );
+ LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( hae_one, 0 );
+ apr = lfds700_hash_a_insert( &has, &hae_one, NULL, &ps );
+
+ if( apr != LFDS700_HASH_A_PUT_RESULT_SUCCESS )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ LFDS700_HASH_A_SET_KEY_IN_ELEMENT( hae_two, 1 );
+ LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( hae_two, 1 );
+ apr = lfds700_hash_a_insert( &has, &hae_two, NULL, &ps );
+
+ if( apr != LFDS700_HASH_A_PUT_RESULT_FAILURE_EXISTING_KEY )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ lfds700_hash_a_cleanup( &has, NULL );
+
+ // TRD : success on overwrite
+ lfds700_hash_a_init_valid_on_current_logical_core( &has, baus, 10, key_compare_function, key_hash_function, LFDS700_HASH_A_EXISTING_KEY_OVERWRITE, NULL );
+
+ LFDS700_HASH_A_SET_KEY_IN_ELEMENT( hae_one, 1 );
+ LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( hae_one, 1 );
+ apr = lfds700_hash_a_insert( &has, &hae_one, NULL, &ps );
+
+ if( apr != LFDS700_HASH_A_PUT_RESULT_SUCCESS )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ LFDS700_HASH_A_SET_KEY_IN_ELEMENT( hae_two, 1 );
+ LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( hae_two, 1 );
+ apr = lfds700_hash_a_insert( &has, &hae_two, NULL, &ps );
+
+ if( apr != LFDS700_HASH_A_PUT_RESULT_SUCCESS_OVERWRITE )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ lfds700_hash_a_cleanup( &has, NULL );
+
+ util_aligned_free( baus );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "hash_a", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int key_compare_function( void const *new_key, void const *key_in_tree )
+{
+ int
+ cr = 0;
+
+ // TRD : key_new can be any value in its range
+ // TRD : key_in_tree can be any value in its range
+
+ if( (lfds700_pal_uint_t) new_key < (lfds700_pal_uint_t) key_in_tree )
+ cr = -1;
+
+ if( (lfds700_pal_uint_t) new_key > (lfds700_pal_uint_t) key_in_tree )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void key_hash_function( void const *key, lfds700_pal_uint_t *hash )
+{
+ // TRD : key can be NULL
+ assert( hash != NULL );
+
+ *hash = 0;
+
+ /* TRD : this function iterates over the user data
+ and we are using the void pointer *as* key data
+ so here we need to pass in the addy of key
+ */
+
+ LFDS700_HASH_A_32BIT_HASH_FUNCTION( (void *) &key, sizeof(lfds700_pal_uint_t), *hash );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_overwrite.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_overwrite.c
new file mode 100644
index 0000000000..29c5fae865
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_hash_addonly_random_adds_overwrite.c
@@ -0,0 +1,388 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_hash_a_element
+ hae;
+
+ lfds700_pal_uint_t
+ key;
+};
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements_per_thread,
+ overwrite_count;
+
+ struct lfds700_hash_a_state
+ *has;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_adding( void *util_thread_starter_thread_state );
+static int key_compare_function( void const *new_key, void const *existing_key );
+static void key_hash_function( void const *key, lfds700_pal_uint_t *hash );
+static int qsort_and_bsearch_key_compare_function( void const *e1, void const *e2 );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_hash_a_random_adds_overwrite_on_existing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ int
+ rv;
+
+ lfds700_pal_uint_t
+ actual_sum_overwrite_existing_count,
+ expected_sum_overwrite_existing_count,
+ *key_count_array,
+ loop,
+ number_elements_per_thread,
+ number_elements_total,
+ number_logical_processors,
+ random_value;
+
+ struct lfds700_hash_a_iterate
+ hai;
+
+ struct lfds700_hash_a_element
+ *hae;
+
+ struct lfds700_hash_a_state
+ has;
+
+ struct lfds700_list_asu_element
+ *lasue = NULL;
+
+ struct lfds700_btree_au_state
+ *baus;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *element_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ void
+ *key_pointer,
+ *key;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a single hash_a
+ we generate n elements per thread
+ each element contains a key value, which is set to a random value
+ (we don't use value, so it's just set to 0)
+ the threads then run, putting
+ the threads count their number of overwrite hits
+ once the threads are done, then we
+ count the number of each key
+ from this we figure out the min/max element for hash_a validation, so we call validation
+ we check the sum of overwrites for each thread is what it should be
+ then using the hash_a get() we check all the elements we expect are present
+ and then we iterate over the hash_a
+ checking we see each key once
+ */
+
+ internal_display_test_name( "Random adds, get and iterate (overwrite on existing key)" );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ baus = util_aligned_malloc( sizeof(struct lfds700_btree_au_state) * 1000, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_hash_a_init_valid_on_current_logical_core( &has, baus, 1000, key_compare_function, key_hash_function, LFDS700_HASH_A_EXISTING_KEY_OVERWRITE, NULL );
+
+ // TRD : we divide by 2 beccause we have to allocate a second array of this size later
+ number_elements_per_thread = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors ) / 2;
+ number_elements_total = number_elements_per_thread * number_logical_processors;
+
+ // TRD : created an ordered list of unique numbers
+ element_array = util_aligned_malloc( sizeof(struct test_element) * number_elements_total, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ {
+ random_value = LFDS700_MISC_PRNG_GENERATE( &ps );
+ (element_array+loop)->key = (lfds700_pal_uint_t) floor( (number_elements_total/2) * ((double) random_value / (double) LFDS700_MISC_PRNG_MAX) );
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->has = &has;
+ (ts+loop)->element_array = element_array + number_elements_per_thread*loop;
+ (ts+loop)->overwrite_count = 0;
+ (ts+loop)->number_elements_per_thread = number_elements_per_thread;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_adding, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ // TRD : now for validation
+ key_count_array = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_elements_total );
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ *(key_count_array+loop) = 0;
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ ( *(key_count_array + (element_array+loop)->key) )++;
+
+ vi.min_elements = number_elements_total;
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ if( *(key_count_array+loop) == 0 )
+ vi.min_elements--;
+
+ vi.max_elements = vi.min_elements;
+
+ lfds700_hash_a_query( &has, LFDS700_HASH_A_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) &dvs );
+
+ expected_sum_overwrite_existing_count = 0;
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ if( *(key_count_array+loop) != 0 )
+ expected_sum_overwrite_existing_count += *(key_count_array+loop) - 1;
+
+ actual_sum_overwrite_existing_count = 0;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ actual_sum_overwrite_existing_count += (ts+loop)->overwrite_count;
+
+ if( expected_sum_overwrite_existing_count != actual_sum_overwrite_existing_count )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ // TRD : now loop over the expected array and check we can get() every element
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ if( *(key_count_array+loop) > 0 )
+ {
+ rv = lfds700_hash_a_get_by_key( &has, (void *) loop, &hae );
+
+ if( rv != 1 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ }
+
+ /* TRD : now iterate, checking we find every element and no others
+ to do this in a timely manner, we need to qsort() the key values
+ and use bsearch() to check for items in the array
+ */
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ if( *(key_count_array+loop) != 0 )
+ *(key_count_array+loop) = loop;
+ else
+ *(key_count_array+loop) = 0;
+
+ qsort( key_count_array, number_elements_total, sizeof(lfds700_pal_uint_t), qsort_and_bsearch_key_compare_function );
+
+ lfds700_hash_a_iterate_init( &has, &hai );
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_hash_a_iterate(&hai, &hae) )
+ {
+ key = LFDS700_HASH_A_GET_KEY_FROM_ELEMENT( *hae );
+
+ key_pointer = bsearch( &key, key_count_array, number_elements_total, sizeof(lfds700_pal_uint_t), qsort_and_bsearch_key_compare_function );
+
+ if( key_pointer == NULL )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ }
+
+ // TRD : cleanup
+ lfds700_hash_a_cleanup( &has, NULL );
+
+ util_aligned_free( baus );
+
+ free( ts );
+
+ util_aligned_free( element_array );
+
+ free( key_count_array );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "hash_a", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_adding( void *util_thread_starter_thread_state )
+{
+ enum lfds700_hash_a_insert_result
+ apr;
+
+ lfds700_pal_uint_t
+ index = 0;
+
+ struct test_state
+ *ts;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( index < ts->number_elements_per_thread )
+ {
+ LFDS700_HASH_A_SET_KEY_IN_ELEMENT( (ts->element_array+index)->hae, (ts->element_array+index)->key );
+ LFDS700_HASH_A_SET_VALUE_IN_ELEMENT( (ts->element_array+index)->hae, 0 );
+ apr = lfds700_hash_a_insert( ts->has, &(ts->element_array+index)->hae, NULL, &ps );
+
+ if( apr == LFDS700_HASH_A_PUT_RESULT_SUCCESS_OVERWRITE )
+ ts->overwrite_count++;
+
+ index++;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int key_compare_function( void const *new_key, void const *existing_key )
+{
+ int
+ cr = 0;
+
+ // TRD : new_key can be NULL (i.e. 0)
+ // TRD : existing_key can be NULL (i.e. 0)
+
+ if( (lfds700_pal_uint_t) new_key < (lfds700_pal_uint_t) existing_key )
+ cr = -1;
+
+ if( (lfds700_pal_uint_t) new_key > (lfds700_pal_uint_t) existing_key )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void key_hash_function( void const *key, lfds700_pal_uint_t *hash )
+{
+ // TRD : key can be NULL
+ assert( hash != NULL );
+
+ *hash = 0;
+
+ /* TRD : this function iterates over the user data
+ and we are using the void pointer *as* key data
+ so here we need to pass in the addy of key
+ */
+
+ LFDS700_HASH_A_32BIT_HASH_FUNCTION( (void *) &key, sizeof(lfds700_pal_uint_t), *hash );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+static int qsort_and_bsearch_key_compare_function( void const *e1, void const *e2 )
+{
+ int
+ cr = 0;
+
+ lfds700_pal_uint_t
+ s1,
+ s2;
+
+ s1 = *(lfds700_pal_uint_t *) e1;
+ s2 = *(lfds700_pal_uint_t *) e2;
+
+ if( s1 > s2 )
+ cr = 1;
+
+ if( s1 < s2 )
+ cr = -1;
+
+ return( cr );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked.c
new file mode 100644
index 0000000000..5720aa2428
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked.c
@@ -0,0 +1,31 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_list_aos( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_CAS )
+ {
+ printf( "\n"
+ "List (add-only, ordered, singly-linked) Tests\n"
+ "=============================================\n" );
+
+ test_lfds700_list_aos_alignment();
+ test_lfds700_list_aos_new_ordered( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_list_aos_new_ordered_with_cursor( list_of_logical_processors, memory_in_megabytes );
+ }
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_alignment.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_alignment.c
new file mode 100644
index 0000000000..7726346366
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_alignment.c
@@ -0,0 +1,58 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_list_aos_alignment()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ /* TRD : these are compile time checks
+ but we do them here because this is a test programme
+ and it should indicate issues to users when it is *run*,
+ not when it is compiled, because a compile error normally
+ indicates a problem with the code itself and so is misleading
+ */
+
+ internal_display_test_name( "Alignment" );
+
+
+
+ // TRD : struct lfds700_list_aos_element
+ if( offsetof(struct lfds700_list_aos_element,next) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_aos_element,value) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_aos_element,key) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : struct lfds700_list_asu_state
+ if( offsetof(struct lfds700_list_aos_state,start) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_aos_state,dummy_element) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_aos_state,key_compare_function) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "list_aos", dvs );
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_new_ordered.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_new_ordered.c
new file mode 100644
index 0000000000..3a392b33bd
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_new_ordered.c
@@ -0,0 +1,278 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_list_aos_element
+ laose;
+
+ lfds700_pal_uint_t
+ element_number,
+ thread_number;
+};
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements_per_thread;
+
+ struct lfds700_list_aos_state
+ *laoss;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static int new_ordered_compare_function( void const *value_new, void const *value_in_list );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_ordered_thread( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_list_aos_new_ordered( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ expected_element_number,
+ number_elements_per_thread,
+ number_elements_total,
+ number_logical_processors,
+ offset,
+ temp;
+
+ struct lfds700_list_aos_element
+ *laose = NULL;
+
+ struct lfds700_list_asu_element
+ *lasue = NULL;
+
+ struct lfds700_list_aos_state
+ laoss;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct test_element
+ *element_array,
+ *element;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_state
+ *tts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : run one thread per logical processor
+ we have a single array of 10k elements per thread
+ this is set to be randomly ordered (but with contigious numbers from 0 to n)
+ we give 10k to each thread (a pointer into the array at the correct point)
+ which then loops through that array
+ calling lfds700_list_aos_insert_element_by_position( LFDS700_LIST_AOS_POSITION_ORDERED )
+ verification should show list is sorted
+ */
+
+ internal_display_test_name( "New ordered" );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_list_aos_init_valid_on_current_logical_core( &laoss, new_ordered_compare_function, LFDS700_LIST_AOS_INSERT_RESULT_FAILURE_EXISTING_KEY, NULL );
+
+ /* TRD : create randomly ordered number array with unique elements
+
+ unique isn't necessary - the list will sort anyway - but
+ it permits slightly better validation
+ */
+
+ number_elements_per_thread = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+
+ // TRD : or the test takes a looooooong time...
+ if( number_elements_per_thread > 10000 )
+ number_elements_per_thread = 10000;
+
+ number_elements_total = number_elements_per_thread * number_logical_processors;
+
+ element_array = util_aligned_malloc( sizeof(struct test_element) * number_elements_total, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ (element_array+loop)->element_number = loop;
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ {
+ offset = LFDS700_MISC_PRNG_GENERATE( &ps );
+ offset %= number_elements_total;
+ temp = (element_array + offset)->element_number;
+ (element_array + offset)->element_number = (element_array + loop)->element_number;
+ (element_array + loop)->element_number = temp;
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->laoss = &laoss;
+ (ts+loop)->element_array = element_array + (loop*number_elements_per_thread);
+ (ts+loop)->number_elements_per_thread = number_elements_per_thread;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, new_ordered_thread, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ free( ts );
+
+ /* TRD : validate the resultant list
+ iterate over the list
+ we expect to find the list is sorted,
+ which means that element_number will
+ increment from zero
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_elements_total;
+
+ lfds700_list_aos_query( &laoss, LFDS700_LIST_AOS_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ if( dvs == LFDS700_MISC_VALIDITY_VALID )
+ {
+ expected_element_number = 0;
+
+ // TRD : traverse the list and check combined_data_array matches
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and LFDS700_LIST_AOS_GET_START_AND_THEN_NEXT(laoss, laose) )
+ {
+ element = LFDS700_LIST_AOS_GET_VALUE_FROM_ELEMENT( *laose );
+
+ if( element->element_number != expected_element_number++ )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ }
+ }
+
+ lfds700_list_aos_cleanup( &laoss, NULL );
+
+ util_aligned_free( element_array );
+
+ internal_display_test_result( 1, "list_aos", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int new_ordered_compare_function( void const *value_new, void const *value_in_list )
+{
+ int
+ cr = 0;
+
+ struct test_element
+ *e1,
+ *e2;
+
+ // TRD : value_new can be any value in its range
+ // TRD : value_in_list can be any value in its range
+
+ e1 = (struct test_element *) value_new;
+ e2 = (struct test_element *) value_in_list;
+
+ if( e1->element_number < e2->element_number )
+ cr = -1;
+
+ if( e1->element_number > e2->element_number )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_ordered_thread( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ for( loop = 0 ; loop < ts->number_elements_per_thread ; loop++ )
+ {
+ LFDS700_LIST_AOS_SET_KEY_IN_ELEMENT( (ts->element_array+loop)->laose, ts->element_array+loop );
+ LFDS700_LIST_AOS_SET_VALUE_IN_ELEMENT( (ts->element_array+loop)->laose, ts->element_array+loop );
+ lfds700_list_aos_insert( ts->laoss, &(ts->element_array+loop)->laose, NULL, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_new_ordered_with_cursor.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_new_ordered_with_cursor.c
new file mode 100644
index 0000000000..42e0ebc7a5
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_ordered_singlylinked_new_ordered_with_cursor.c
@@ -0,0 +1,366 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_list_aos_element
+ laose;
+
+ lfds700_pal_uint_t
+ element_number,
+ thread_number;
+};
+
+struct test_state
+{
+ enum flag
+ error_flag;
+
+ lfds700_pal_uint_t
+ number_elements_per_thread;
+
+ struct lfds700_list_aos_state
+ *laoss;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static int new_ordered_with_cursor_compare_function( void const *value_new, void const *value_in_list );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_ordered_with_cursor_insert_thread( void *util_thread_starter_thread_state );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_ordered_with_cursor_cursor_thread( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_list_aos_new_ordered_with_cursor( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements_per_thread,
+ number_elements_total,
+ number_logical_processors,
+ offset,
+ temp;
+
+ struct lfds700_list_aos_state
+ laoss;
+
+ struct lfds700_list_asu_element
+ *lasue = NULL;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *element_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : run two threads per logical processor
+
+ the test runs for 10 seconds
+
+ the first thread loops over a pre-set list of random numbers
+ continually adding them using ordered insert
+
+ the second thread keeps iterating over the list, checking that
+ each element is larger than its predecessor
+ */
+
+ internal_display_test_name( "New ordered with cursor (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_list_aos_init_valid_on_current_logical_core( &laoss, new_ordered_with_cursor_compare_function, LFDS700_LIST_AOS_INSERT_RESULT_FAILURE_EXISTING_KEY, NULL );
+
+ /* TRD : create randomly ordered number array with unique elements
+
+ unique isn't necessary - the list will sort anyway - but
+ it permits slightly better validation
+ */
+
+ number_elements_per_thread = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+
+ // TRD : or the test takes a looooooong time...
+ if( number_elements_per_thread > 1000 )
+ number_elements_per_thread = 1000;
+
+ number_elements_total = number_elements_per_thread * number_logical_processors;
+
+ element_array = util_aligned_malloc( sizeof(struct test_element) * number_elements_total, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ (element_array+loop)->element_number = loop;
+
+ for( loop = 0 ; loop < number_elements_total ; loop++ )
+ {
+ offset = LFDS700_MISC_PRNG_GENERATE( &ps );
+ offset %= number_elements_total;
+ temp = (element_array + offset)->element_number;
+ (element_array + offset)->element_number = (element_array + loop)->element_number;
+ (element_array + loop)->element_number = temp;
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors * 2 );
+
+ // TRD : the insert threads
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->laoss = &laoss;
+ (ts+loop)->element_array = element_array + number_elements_per_thread*loop;
+ (ts+loop)->error_flag = LOWERED;
+ (ts+loop)->number_elements_per_thread = number_elements_per_thread;
+ }
+
+ // TRD : the cursor threads
+ for( loop = number_logical_processors ; loop < number_logical_processors * 2 ; loop++ )
+ {
+ (ts+loop)->laoss = &laoss;
+ (ts+loop)->element_array = NULL;
+ (ts+loop)->error_flag = LOWERED;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors * 2 );
+
+ util_thread_starter_new( &tts, number_logical_processors * 2 );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, new_ordered_with_cursor_insert_thread, ts+loop );
+ util_thread_starter_start( tts, &thread_handles[loop+number_logical_processors], loop+number_logical_processors, lp, new_ordered_with_cursor_cursor_thread, ts+loop+number_logical_processors );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors * 2 ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ /* TRD : validate the resultant list
+
+ the cursor threads were checking for orderedness
+ if that failed, they raise their error_flag
+ so validate the list, then check error_flags
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_elements_total;
+
+ lfds700_list_aos_query( &laoss, LFDS700_LIST_AOS_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ if( dvs == LFDS700_MISC_VALIDITY_VALID )
+ for( loop = number_logical_processors ; loop < number_logical_processors * 2 ; loop++ )
+ if( (ts+loop)->error_flag == RAISED )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ORDER;
+
+ lfds700_list_aos_cleanup( &laoss, NULL );
+
+ util_aligned_free( element_array );
+
+ free( ts );
+
+ internal_display_test_result( 1, "list_aos", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static int new_ordered_with_cursor_compare_function( void const *value_new, void const *value_in_list )
+{
+ int
+ cr = 0;
+
+ struct test_element
+ *e1,
+ *e2;
+
+ // TRD : value_new can be any value in its range
+ // TRD : value_in_list can be any value in its range
+
+ e1 = (struct test_element *) value_new;
+ e2 = (struct test_element *) value_in_list;
+
+ if( e1->element_number < e2->element_number )
+ cr = -1;
+
+ if( e1->element_number > e2->element_number )
+ cr = 1;
+
+ return( cr );
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_ordered_with_cursor_insert_thread( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ for( loop = 0 ; loop < ts->number_elements_per_thread ; loop++ )
+ {
+ LFDS700_LIST_AOS_SET_KEY_IN_ELEMENT( (ts->element_array+loop)->laose, ts->element_array+loop );
+ LFDS700_LIST_AOS_SET_VALUE_IN_ELEMENT( (ts->element_array+loop)->laose, ts->element_array+loop );
+ lfds700_list_aos_insert( ts->laoss, &(ts->element_array+loop)->laose, NULL, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_ordered_with_cursor_cursor_thread( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ prev_element_number;
+
+ lfds700_pal_uint_t
+ time_loop = 0;
+
+ struct lfds700_list_aos_element
+ *laose;
+
+ struct test_element
+ *element;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ prev_element_number = 0;
+
+ laose = LFDS700_LIST_AOS_GET_START( *ts->laoss );
+
+ // TRD : we may get start before any element has been added to the list
+ if( laose == NULL )
+ continue;
+
+ element = LFDS700_LIST_AOS_GET_VALUE_FROM_ELEMENT( *laose );
+
+ if( element->element_number < prev_element_number )
+ ts->error_flag = RAISED;
+
+ prev_element_number = element->element_number;
+
+ laose = LFDS700_LIST_AOS_GET_NEXT( *laose );
+
+ while( laose != NULL )
+ {
+ element = LFDS700_LIST_AOS_GET_VALUE_FROM_ELEMENT( *laose );
+
+ if( element->element_number <= prev_element_number )
+ ts->error_flag = RAISED;
+
+ prev_element_number = element->element_number;
+
+ laose = LFDS700_LIST_AOS_GET_NEXT( *laose );
+ }
+
+ if( time_loop++ == REDUCED_TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered.c
new file mode 100644
index 0000000000..37c37f2529
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered.c
@@ -0,0 +1,32 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_list_asu( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_CAS )
+ {
+ printf( "\n"
+ "List (add-only, singly-linked, unordered) Tests\n"
+ "===============================================\n" );
+
+ test_lfds700_list_asu_alignment();
+ test_lfds700_list_asu_new_start( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_list_asu_new_end( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_list_asu_new_after( list_of_logical_processors, memory_in_megabytes );
+ }
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_alignment.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_alignment.c
new file mode 100644
index 0000000000..43f451d4bf
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_alignment.c
@@ -0,0 +1,61 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_list_asu_alignment()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ /* TRD : these are compile time checks
+ but we do them here because this is a test programme
+ and it should indicate issues to users when it is *run*,
+ not when it is compiled, because a compile error normally
+ indicates a problem with the code itself and so is misleading
+ */
+
+ internal_display_test_name( "Alignment" );
+
+
+
+ // TRD : struct lfds700_list_asu_element
+ if( offsetof(struct lfds700_list_asu_element,next) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_asu_element,value) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_asu_element,key) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : struct lfds700_list_asu_state
+ if( offsetof(struct lfds700_list_asu_state,end) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_asu_state,start) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_asu_state,dummy_element) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_list_asu_state,key_compare_function) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "list_asu", dvs );
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_after.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_after.c
new file mode 100644
index 0000000000..5dcd6954aa
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_after.c
@@ -0,0 +1,254 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_list_asu_element
+ lasue;
+
+ lfds700_pal_uint_t
+ element_number,
+ thread_number;
+};
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements;
+
+ struct lfds700_list_asu_state
+ *lasus;
+
+ struct test_element
+ *element_array;
+
+ struct lfds700_list_asu_element
+ *first_element;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_after_thread( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_list_asu_new_after( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors,
+ *per_thread_counters,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue,
+ first_element;
+
+ struct lfds700_list_asu_state
+ lasus;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *element_array,
+ *element;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : run one thread per logical processor
+ run for 250k elements
+ we put a single first element into the list and
+ each thread loops, calling lfds700_list_asu_new_element_by_position( LFDS700_LIST_ASU_POSITION_AFTER ),
+ inserting after the single first element
+ data element contain s thread_number and element_number
+ verification should show element_number decreasing on a per thread basis
+ */
+
+ internal_display_test_name( "New after" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_init_valid_on_current_logical_core( &lasus, NULL, NULL );
+
+ LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( first_element, NULL );
+ LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( first_element, NULL );
+ lfds700_list_asu_insert_at_position( &lasus, &first_element, NULL, LFDS700_LIST_ASU_POSITION_START, &ps );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+
+ element_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ {
+ (element_array+(loop*number_elements)+subloop)->thread_number = loop;
+ (element_array+(loop*number_elements)+subloop)->element_number = subloop;
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {\
+ (ts+loop)->lasus = &lasus;
+ (ts+loop)->element_array = element_array + (loop*number_elements);
+ (ts+loop)->first_element = &first_element;
+ (ts+loop)->number_elements = number_elements;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, new_after_thread, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ free( ts );
+
+ /* TRD : validate the resultant list
+ iterate over each element
+ we expect to find element numbers increment on a per thread basis
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_elements * number_logical_processors + 1;
+
+ lfds700_list_asu_query( &lasus, LFDS700_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ *(per_thread_counters+loop) = number_elements - 1;
+
+ /* TRD : we have a leading element, after which all inserts occurred
+ we need to get past that element for validation
+ this is why we're not using lfds700_list_asu_get_start_and_then_next()
+ */
+
+ lasue = LFDS700_LIST_ASU_GET_START( lasus );
+
+ lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lasue != NULL )
+ {
+ element = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+
+ if( element->thread_number >= number_logical_processors )
+ {
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ break;
+ }
+
+ if( element->element_number < per_thread_counters[element->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( element->element_number > per_thread_counters[element->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( element->element_number == per_thread_counters[element->thread_number] )
+ per_thread_counters[element->thread_number]--;
+
+ lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
+ }
+
+ free( per_thread_counters );
+
+ lfds700_list_asu_cleanup( &lasus, NULL );
+
+ util_aligned_free( element_array );
+
+ internal_display_test_result( 1, "list_asu", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_after_thread( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
+ LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
+ lfds700_list_asu_insert_at_position( ts->lasus, &(ts->element_array+loop)->lasue, ts->first_element, LFDS700_LIST_ASU_POSITION_AFTER, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_end.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_end.c
new file mode 100644
index 0000000000..c6c66d007c
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_end.c
@@ -0,0 +1,229 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_list_asu_element
+ lasue;
+
+ lfds700_pal_uint_t
+ element_number,
+ thread_number;
+};
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements;
+
+ struct lfds700_list_asu_state
+ *lasus;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_end_thread( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_list_asu_new_end( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors,
+ *per_thread_counters,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue = NULL;
+
+ struct lfds700_list_asu_state
+ lasus;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *element_array,
+ *element;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : run one thread per logical processor
+ run for 250k elements
+ each thread loops, calling lfds700_list_asu_new_element_by_position( LFDS700_LIST_ASU_POSITION_END )
+ data element contain a thread_number and element_number
+ verification should show element_number increasing on a per thread basis
+ */
+
+ internal_display_test_name( "New end" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_list_asu_init_valid_on_current_logical_core( &lasus, NULL, NULL );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+
+ element_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ {
+ (element_array+(loop*number_elements)+subloop)->thread_number = loop;
+ (element_array+(loop*number_elements)+subloop)->element_number = subloop;
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->lasus = &lasus;
+ (ts+loop)->element_array = element_array + (loop*number_elements);
+ (ts+loop)->number_elements = number_elements;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, new_end_thread, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ free( ts );
+
+ /* TRD : validate the resultant list
+ iterate over each element
+ we expect to find element numbers increment on a per thread basis
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_elements * number_logical_processors;
+
+ lfds700_list_asu_query( &lasus, LFDS700_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ *(per_thread_counters+loop) = 0;
+
+ lasue = NULL;
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(lasus, lasue) )
+ {
+ element = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+
+ if( element->thread_number >= number_logical_processors )
+ {
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ break;
+ }
+
+ if( element->element_number > per_thread_counters[element->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( element->element_number < per_thread_counters[element->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( element->element_number == per_thread_counters[element->thread_number] )
+ per_thread_counters[element->thread_number]++;
+ }
+
+ free( per_thread_counters );
+
+ lfds700_list_asu_cleanup( &lasus, NULL );
+
+ util_aligned_free( element_array );
+
+ internal_display_test_result( 1, "list_asu", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_end_thread( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
+ LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
+ lfds700_list_asu_insert_at_position( ts->lasus, &(ts->element_array+loop)->lasue, NULL, LFDS700_LIST_ASU_POSITION_END, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_start.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_start.c
new file mode 100644
index 0000000000..f4244e2a12
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_list_addonly_singlylinked_unordered_new_start.c
@@ -0,0 +1,229 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ struct lfds700_list_asu_element
+ lasue;
+
+ lfds700_pal_uint_t
+ element_number,
+ thread_number;
+};
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements;
+
+ struct lfds700_list_asu_state
+ *lasus;
+
+ struct test_element
+ *element_array;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_start_thread( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_list_asu_new_start( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors,
+ *per_thread_counters,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue = NULL;
+
+ struct lfds700_list_asu_state
+ lasus;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_element
+ *element_array,
+ *element;
+
+ struct test_state
+ *ts;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : run one thread per logical processor
+ run for 250k elements
+ each thread loops, calling lfds700_list_asu_new_element_by_position( LFDS700_LIST_ASU_POSITION_START )
+ data element contain s thread_number and element_number
+ verification should show element_number decreasing on a per thread basis
+ */
+
+ internal_display_test_name( "New start" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_list_asu_init_valid_on_current_logical_core( &lasus, NULL, NULL );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+
+ element_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ {
+ (element_array+(loop*number_elements)+subloop)->thread_number = loop;
+ (element_array+(loop*number_elements)+subloop)->element_number = subloop;
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->lasus = &lasus;
+ (ts+loop)->element_array = element_array + (loop*number_elements);
+ (ts+loop)->number_elements = number_elements;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, new_start_thread, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ free( ts );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ /* TRD : validate the resultant list
+ iterate over each element
+ we expect to find element numbers increment on a per thread basis
+ */
+
+ vi.min_elements = vi.max_elements = number_elements * number_logical_processors;
+
+ lfds700_list_asu_query( &lasus, LFDS700_LIST_ASU_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ *(per_thread_counters+loop) = number_elements - 1;
+
+ lasue = NULL;
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(lasus, lasue) )
+ {
+ element = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+
+ if( element->thread_number >= number_logical_processors )
+ {
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ break;
+ }
+
+ if( element->element_number < per_thread_counters[element->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( element->element_number > per_thread_counters[element->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( element->element_number == per_thread_counters[element->thread_number] )
+ per_thread_counters[element->thread_number]--;
+ }
+
+ free( per_thread_counters );
+
+ lfds700_list_asu_cleanup( &lasus, NULL );
+
+ util_aligned_free( element_array );
+
+ internal_display_test_result( 1, "list_asu", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION new_start_thread( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ LFDS700_LIST_ASU_SET_KEY_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
+ LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( (ts->element_array+loop)->lasue, ts->element_array+loop );
+ lfds700_list_asu_insert_at_position( ts->lasus, &(ts->element_array+loop)->lasue, NULL, LFDS700_LIST_ASU_POSITION_START, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic.c
new file mode 100644
index 0000000000..2f733909a7
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic.c
@@ -0,0 +1,33 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_pal_atomic( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ printf( "\n"
+ "Abstraction Atomic Tests\n"
+ "========================\n" );
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_CAS )
+ test_lfds700_pal_atomic_cas( list_of_logical_processors );
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_DWCAS )
+ test_lfds700_pal_atomic_dwcas( list_of_logical_processors );
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_EXCHANGE )
+ test_lfds700_pal_atomic_exchange( list_of_logical_processors, memory_in_megabytes );
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_cas.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_cas.c
new file mode 100644
index 0000000000..543528d99c
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_cas.c
@@ -0,0 +1,176 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_lfds700_pal_atomic_cas_state
+{
+ lfds700_pal_uint_t
+ local_counter;
+
+ lfds700_pal_atom_t volatile
+ *shared_counter;
+};
+
+/***** private prototyps *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_cas( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_pal_atomic_cas( struct lfds700_list_asu_state *list_of_logical_processors )
+{
+ lfds700_pal_atom_t volatile LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ shared_counter;
+
+ lfds700_pal_uint_t
+ local_total = 0;
+
+ lfds700_pal_uint_t
+ loop,
+ number_logical_processors;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_lfds700_pal_atomic_cas_state
+ *atcs;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+
+ /* TRD : here we test pal_cas
+
+ we run one thread per CPU
+ we use pal_cas() to increment a shared counter
+ every time a thread successfully increments the counter,
+ it increments a thread local counter
+ the threads run for ten seconds
+ after the threads finish, we total the local counters
+ they should equal the shared counter
+ */
+
+ internal_display_test_name( "Atomic CAS" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ shared_counter = 0;
+
+ atcs = util_malloc_wrapper( sizeof(struct test_lfds700_pal_atomic_cas_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (atcs+loop)->shared_counter = &shared_counter;
+ (atcs+loop)->local_counter = 0;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_cas, atcs+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ // TRD : results
+ LFDS700_MISC_BARRIER_LOAD;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ local_total += (atcs+loop)->local_counter;
+
+ if( local_total == shared_counter )
+ puts( "passed" );
+
+ if( local_total != shared_counter )
+ {
+ puts( "failed" );
+ exit( EXIT_FAILURE );
+ }
+
+ // TRD : cleanup
+ free( atcs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_cas( void *util_thread_starter_thread_state )
+{
+ char unsigned
+ result;
+
+ lfds700_pal_uint_t
+ loop = 0;
+
+ lfds700_pal_atom_t LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_SINGLE_POINTER)
+ exchange,
+ compare;
+
+ struct test_lfds700_pal_atomic_cas_state
+ *atcs;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ atcs = (struct test_lfds700_pal_atomic_cas_state *) tsts->thread_user_state;
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( loop++ < 10000000 )
+ {
+ compare = *atcs->shared_counter;
+
+ do
+ {
+ exchange = compare + 1;
+ LFDS700_PAL_ATOMIC_CAS( atcs->shared_counter, &compare, exchange, LFDS700_MISC_CAS_STRENGTH_WEAK, result );
+ }
+ while( result == 0 );
+
+ atcs->local_counter++;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_dcas.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_dcas.c
new file mode 100644
index 0000000000..4973e73770
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_dcas.c
@@ -0,0 +1,177 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_lfds700_pal_atomic_dwcas_state
+{
+ lfds700_pal_uint_t
+ local_counter;
+
+ lfds700_pal_atom_t volatile
+ (*shared_counter)[2];
+};
+
+/***** private prototyps *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_dwcas( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_pal_atomic_dwcas( struct lfds700_list_asu_state *list_of_logical_processors )
+{
+ lfds700_pal_uint_t
+ local_total = 0,
+ loop,
+ number_logical_processors;
+
+ lfds700_pal_atom_t volatile LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ shared_counter[2] = { 0, 0 };
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_lfds700_pal_atomic_dwcas_state
+ *atds;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+
+ /* TRD : here we test pal_dwcas
+
+ we run one thread per CPU
+ we use pal_dwcas() to increment a shared counter
+ every time a thread successfully increments the counter,
+ it increments a thread local counter
+ the threads run for ten seconds
+ after the threads finish, we total the local counters
+ they should equal the shared counter
+ */
+
+ internal_display_test_name( "Atomic DWCAS" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ atds = util_malloc_wrapper( sizeof(struct test_lfds700_pal_atomic_dwcas_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (atds+loop)->shared_counter = &shared_counter;
+ (atds+loop)->local_counter = 0;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_dwcas, atds+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ // TRD : results
+ LFDS700_MISC_BARRIER_LOAD;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ local_total += (atds+loop)->local_counter;
+
+ if( local_total == shared_counter[0] )
+ puts( "passed" );
+
+ if( local_total != shared_counter[0] )
+ {
+ printf( "%llu != %llu\n", (int long long unsigned) local_total, (int long long unsigned) shared_counter[0] );
+ puts( "failed" );
+ exit( EXIT_FAILURE );
+ }
+
+ // TRD : cleanup
+ free( atds );
+
+ return;
+}
+
+#pragma warning( disable : 4702 )
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_dwcas( void *util_thread_starter_thread_state )
+{
+ char unsigned
+ result;
+
+ lfds700_pal_uint_t
+ loop = 0;
+
+ lfds700_pal_atom_t LFDS700_PAL_ALIGN(LFDS700_PAL_ALIGN_DOUBLE_POINTER)
+ exchange[2],
+ compare[2];
+
+ struct test_lfds700_pal_atomic_dwcas_state
+ *atds;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ atds = (struct test_lfds700_pal_atomic_dwcas_state *) tsts->thread_user_state;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( loop++ < 10000000 )
+ {
+ compare[0] = (*atds->shared_counter)[0];
+ compare[1] = (*atds->shared_counter)[1];
+
+ do
+ {
+ exchange[0] = compare[0] + 1;
+ exchange[1] = compare[1];
+ LFDS700_PAL_ATOMIC_DWCAS( atds->shared_counter, compare, exchange, LFDS700_MISC_CAS_STRENGTH_WEAK, result );
+ }
+ while( result == 0 );
+
+ atds->local_counter++;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_exchange.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_exchange.c
new file mode 100644
index 0000000000..ba6366e524
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_porting_abstraction_layer_atomic_exchange.c
@@ -0,0 +1,333 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ lfds700_pal_uint_t
+ counter,
+ *counter_array,
+ number_elements,
+ number_logical_processors;
+
+ lfds700_pal_uint_t volatile
+ *shared_exchange;
+};
+
+/***** private prototyps *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_exchange( void *util_thread_starter_thread_state );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_atomic_exchange( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_pal_atomic_exchange( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum flag
+ atomic_exchange_success_flag = RAISED,
+ exchange_success_flag = RAISED;
+
+ lfds700_pal_uint_t
+ loop,
+ *merged_counter_arrays,
+ number_elements,
+ number_logical_processors,
+ subloop;
+
+ lfds700_pal_uint_t volatile LFDS700_PAL_ALIGN(LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES)
+ exchange;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct test_state
+ *ts;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : here we test pal_atomic_exchange
+
+ we have one thread per logical core
+ there is one variable which every thread will exchange to/from
+ we know the number of logical cores
+ the threads have a counter each, which begins with their logical core number plus one
+ (plus one because the exchange counter begins with 0 already in place)
+ (e.g. thread 0 begins with its counter at 1, thread 1 begins with its counter at 2, etc)
+
+ there is an array per thread of 1 million elements, each a counter, set to 0
+
+ when running, each thread increments its counter by the number of threads
+ the threads busy loop, exchanging
+ every time aa thread pulls a number off the central, shared exchange variable,
+ it increments the counter for that variable in its thread-local counter array
+
+ (we're not using a global array, because we'd have to be atomic in our increments,
+ which is a slow-down we don't want)
+
+ at the end, we merge all the counter arrays and if the frequency for a counter is a value
+ other than 1, the exchange was not atomic
+
+ we perform the test twice, once with pal_atomic_exchange, once with a non-atomic exchange
+
+ we expect the atomic to pass and the non-atomic to fail
+ */
+
+ internal_display_test_name( "Atomic exchange" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(lfds700_pal_uint_t) * (number_logical_processors + 1) );
+
+ merged_counter_arrays = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_elements );
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ *(merged_counter_arrays+loop) = 0;
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->counter = loop + 1;
+ (ts+loop)->counter_array = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_elements );
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ *((ts+loop)->counter_array+subloop) = 0;
+ (ts+loop)->number_logical_processors = number_logical_processors;
+ (ts+loop)->shared_exchange = &exchange;
+ (ts+loop)->number_elements = number_elements;
+ }
+
+ exchange = 0;
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ // TRD : non-atomic
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_exchange, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ for( subloop = 0 ; subloop < number_logical_processors ; subloop++ )
+ *(merged_counter_arrays+loop) += *( (ts+subloop)->counter_array+loop );
+
+ /* TRD : the worker threads exit when their per-thread counter exceeds 1,000,000
+ as such the final number_logical_processors numbers are not read
+ we could change the threads to exit when the number they read exceeds 1,000,000
+ but then we'd need an if() in their work-loop,
+ and we need to go as fast as possible
+ */
+
+ for( loop = 0 ; loop < number_elements - number_logical_processors ; loop++ )
+ if( *(merged_counter_arrays+loop) != 1 )
+ exchange_success_flag = LOWERED;
+
+ // TRD : now for atomic exchange - we need to re-init the data structures
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ *(merged_counter_arrays+loop) = 0;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ *((ts+loop)->counter_array+subloop) = 0;
+
+ exchange = 0;
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_atomic_exchange, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ for( subloop = 0 ; subloop < number_logical_processors ; subloop++ )
+ *(merged_counter_arrays+loop) += *( (ts+subloop)->counter_array+loop );
+
+ for( loop = 0 ; loop < number_elements - number_logical_processors ; loop++ )
+ if( *(merged_counter_arrays+loop) != 1 )
+ atomic_exchange_success_flag = LOWERED;
+
+ // TRD : cleanup
+ free( merged_counter_arrays );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ free( (ts+loop)->counter_array );
+
+ util_thread_starter_delete( tts );
+ free( thread_handles );
+ free( ts );
+
+ /* TRD : results
+
+ on a single core, atomic and non-atomic exchange should both work
+
+ if we find our non-atomic test passes, then we can't really say anything
+ about whether or not the atomic test is really working
+ */
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ if( number_logical_processors == 1 )
+ {
+ if( exchange_success_flag == RAISED and atomic_exchange_success_flag == RAISED )
+ puts( "passed" );
+
+ if( exchange_success_flag != RAISED or atomic_exchange_success_flag != RAISED )
+ puts( "failed (atomic and non-atomic both failed)" );
+ }
+
+ if( number_logical_processors >= 2 )
+ {
+ if( atomic_exchange_success_flag == RAISED and exchange_success_flag == LOWERED )
+ puts( "passed" );
+
+ if( atomic_exchange_success_flag == RAISED and exchange_success_flag == RAISED )
+ puts( "indeterminate (atomic and non-atomic both passed)" );
+
+ if( atomic_exchange_success_flag == LOWERED )
+ {
+ puts( "failed (atomic failed)" );
+ exit( EXIT_FAILURE );
+ }
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_exchange( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ local_counter,
+ exchange;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ local_counter = ts->counter;
+
+ while( local_counter < ts->number_elements )
+ {
+ exchange = *ts->shared_exchange;
+ *ts->shared_exchange = local_counter;
+
+ ( *(ts->counter_array + exchange) )++;
+
+ local_counter += ts->number_logical_processors;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_atomic_exchange( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ local_counter,
+ exchange;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ local_counter = ts->counter;
+
+ while( local_counter < ts->number_elements )
+ {
+ exchange = local_counter;
+
+ LFDS700_PAL_ATOMIC_EXCHANGE( ts->shared_exchange, &exchange );
+
+ ( *(ts->counter_array + exchange) )++;
+
+ local_counter += ts->number_logical_processors;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue.c
new file mode 100644
index 0000000000..8e41b01b5d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue.c
@@ -0,0 +1,35 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_queue( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_DWCAS )
+ {
+ printf( "\n"
+ "Queue Tests\n"
+ "===========\n" );
+
+ test_lfds700_queue_alignment();
+ test_lfds700_queue_enqueuing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_queue_dequeuing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_queue_enqueuing_and_dequeuing( list_of_logical_processors );
+ test_lfds700_queue_rapid_enqueuing_and_dequeuing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_queue_enqueuing_and_dequeuing_with_free( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_queue_enqueuing_with_malloc_and_dequeuing_with_free( list_of_logical_processors );
+ }
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_alignment.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_alignment.c
new file mode 100644
index 0000000000..6f723825ea
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_alignment.c
@@ -0,0 +1,55 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_queue_alignment()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ /* TRD : these are compile time checks
+ but we do them here because this is a test programme
+ and it should indicate issues to users when it is *run*,
+ not when it is compiled, because a compile error normally
+ indicates a problem with the code itself and so is misleading
+ */
+
+ internal_display_test_name( "Alignment" );
+
+
+
+ // TRD : struct lfds700_queue_element
+ if( offsetof(struct lfds700_queue_element,next) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_queue_element,key) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : struct lfds700_queue_state
+ if( offsetof(struct lfds700_queue_state,enqueue) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_queue_state,dequeue) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_queue_state,user_state) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "queue", dvs );
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer.c
new file mode 100644
index 0000000000..4c660ab3e1
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer.c
@@ -0,0 +1,25 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_bss( struct lfds700_list_asu_state *list_of_logical_processors )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ printf( "\n"
+ "Queue (bounded, single consumer, single producer) Tests\n"
+ "=======================================================\n" );
+
+ // TRD : no alignment checks are required for queue_bss
+ test_lfds700_queue_bss_enqueuing();
+ test_lfds700_queue_bss_dequeuing();
+ test_lfds700_queue_bss_enqueuing_and_dequeuing( list_of_logical_processors );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_dequeuing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_dequeuing.c
new file mode 100644
index 0000000000..971555c443
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_dequeuing.c
@@ -0,0 +1,61 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_bss_dequeuing()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_queue_bss_element
+ element_array[128];
+
+ struct lfds700_queue_bss_state
+ qs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ void
+ *value;
+
+ /* TRD : create an empty queue
+ enqueue 128 elements
+ then dequeue the elements, in the same thread - we're API testing
+ it's a single producer queue, so we just do this in our current thread
+ since we're enqueuing and dequeuing in the same thread,
+
+ */
+
+ internal_display_test_name( "Dequeuing" );
+
+ lfds700_queue_bss_init_valid_on_current_logical_core( &qs, element_array, 128, NULL );
+
+ for( loop = 0 ; loop < 127 ; loop++ )
+ lfds700_queue_bss_enqueue( &qs, NULL, (void *) loop );
+
+ for( loop = 0 ; loop < 127 ; loop++ )
+ {
+ lfds700_queue_bss_dequeue( &qs, NULL, &value );
+ if( (lfds700_pal_uint_t) value != 127 - loop )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ }
+
+ vi.min_elements = vi.max_elements = 0;
+
+ lfds700_queue_bss_query( &qs, LFDS700_QUEUE_BSS_QUERY_VALIDATE, &vi, &dvs );
+
+ lfds700_queue_bss_cleanup( &qs, NULL );
+
+ internal_display_test_result( 1, "queue_bss", dvs );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing.c
new file mode 100644
index 0000000000..807337864a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing.c
@@ -0,0 +1,59 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_bss_enqueuing()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ int
+ rv;
+
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_queue_bss_element
+ element_array[128];
+
+ struct lfds700_queue_bss_state
+ qs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ /* TRD : create an empty queue
+ enqueue 128 elements
+ it's a single producer queue, so we just do this in our current thread
+ it's an API test
+ */
+
+ internal_display_test_name( "Enqueuing" );
+
+ lfds700_queue_bss_init_valid_on_current_logical_core( &qs, element_array, 128, NULL );
+
+ for( loop = 0 ; loop < 127 ; loop++ )
+ if( 1 != lfds700_queue_bss_enqueue(&qs, NULL, (void *) loop) )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ // TRD : at this point enqueuing one more should return 0
+ rv = lfds700_queue_bss_enqueue( &qs, NULL, (void *) loop );
+
+ if( rv != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ vi.min_elements = vi.max_elements = 127;
+
+ lfds700_queue_bss_query( &qs, LFDS700_QUEUE_BSS_QUERY_VALIDATE, &vi, &dvs );
+
+ lfds700_queue_bss_cleanup( &qs, NULL );
+
+ internal_display_test_result( 1, "queue_bss", dvs );
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing_and_dequeuing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing_and_dequeuing.c
new file mode 100644
index 0000000000..ad218609fd
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_bounded_singleconsumer_singleproducer_enqueuing_and_dequeuing.c
@@ -0,0 +1,260 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ enum flag
+ error_flag;
+
+ struct lfds700_queue_bss_state
+ *qs;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueuer( void *util_thread_starter_thread_state );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_dequeuer( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_bss_enqueuing_and_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_logical_processors,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_queue_bss_element
+ element_array[4];
+
+ struct lfds700_queue_bss_state
+ qs;
+
+ struct test_pal_logical_processor
+ *lp,
+ *lp_first;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+
+ /* TRD : so, this is the real test
+ problem is, because we use memory barriers only
+ and we only support one producer and one consumer
+ we need to ensure these threads are on different physical cores
+ if they're on the same core, the code would work even without memory barriers
+
+ problem is, in the test application, we only know the *number* of logical cores
+ obtaining topology information adds a great deal of complexity to the test app
+ and makes porting much harder
+
+ so, we know how many logical cores there are; my thought is to partially
+ permutate over them - we always run the producer on core 0, but we iterate
+ over the other logical cores, running the test once each time, with the
+ consumer being run on core 0, then core 1, then core 2, etc
+
+ (we run on core 0 for the single-cpu case; it's redundent, since a single
+ logical core running both producer and consumer will work, but otherwise
+ we have to skip the test, which is confusing for the user)
+
+ the test is one thread enqueuing and one thread dequeuing for two seconds
+ */
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ internal_display_test_name( "Enqueuing and dequeuing (%d seconds)", number_logical_processors * 2 );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * 2 );
+
+ for( loop = 0 ; loop < 2 ; loop++ )
+ {
+ (ts+loop)->qs = &qs;
+ (ts+loop)->error_flag = LOWERED;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * 2 );
+
+ /* TRD : producer always on core 0
+ iterate over the other cores with consumer
+ */
+
+ lasue = LFDS700_LIST_ASU_GET_START( *list_of_logical_processors );
+ lp_first = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+
+ while( lasue != NULL )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+
+ lfds700_queue_bss_init_valid_on_current_logical_core( &qs, element_array, 4, NULL );
+
+ util_thread_starter_new( &tts, 2 );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ util_thread_starter_start( tts, &thread_handles[0], 0, lp_first, thread_enqueuer, ts );
+ util_thread_starter_start( tts, &thread_handles[1], 1, lp, thread_dequeuer, ts+1 );
+
+ util_thread_starter_run( tts );
+
+ for( subloop = 0 ; subloop < 2 ; subloop++ )
+ test_pal_thread_wait( thread_handles[subloop] );
+
+ util_thread_starter_delete( tts );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lfds700_queue_bss_cleanup( &qs, NULL );
+
+ lasue = LFDS700_LIST_ASU_GET_NEXT( *lasue );
+ }
+
+ if( (ts+1)->error_flag == RAISED )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ free( thread_handles );
+
+ free( ts );
+
+ internal_display_test_result( 1, "queue_bss", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueuer( void *util_thread_starter_thread_state )
+{
+ int
+ rv;
+
+ lfds700_pal_uint_t
+ datum = 0,
+ time_loop = 0;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + 2 )
+ {
+ rv = lfds700_queue_bss_enqueue( ts->qs, NULL, (void *) datum );
+
+ if( rv == 1 )
+ if( ++datum == 4 )
+ datum = 0;
+
+ if( time_loop++ == TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_dequeuer( void *util_thread_starter_thread_state )
+{
+ int
+ rv;
+
+ lfds700_pal_uint_t
+ datum,
+ expected_datum = 0,
+ time_loop = 0;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + 2 )
+ {
+ rv = lfds700_queue_bss_dequeue( ts->qs, NULL, (void *) &datum );
+
+ if( rv == 1 )
+ {
+ if( datum != expected_datum )
+ ts->error_flag = RAISED;
+
+ if( ++expected_datum == 4 )
+ expected_datum = 0;
+ }
+
+ if( time_loop++ == TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_dequeuing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_dequeuing.c
new file mode 100644
index 0000000000..74f271d320
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_dequeuing.c
@@ -0,0 +1,215 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ enum flag
+ error_flag;
+
+ struct lfds700_queue_state
+ *qs;
+};
+
+struct test_element
+{
+ struct lfds700_queue_element
+ qe;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_dequeuer( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements_with_dummy_element,
+ number_elements_without_dummy_element,
+ number_logical_processors;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_state
+ qs;
+
+ struct lfds700_misc_validation_info
+ vi = { 0, 0 };
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : create a queue, add 1,000,000 elements
+
+ use a single thread to enqueue every element
+ each elements user data is an incrementing counter
+
+ then run one thread per CPU
+ where each busy-works dequeuing
+
+ when an element is dequeued, we check (on a per-thread basis) the
+ value dequeued is greater than the element previously dequeued
+
+ note we have no variation in the test for CAS+GC vs DWCAS
+ this is because all we do is dequeue
+ what we actually want to stress test is the queue
+ not CAS
+ so it's better to let the dequeue run as fast as possible
+ */
+
+ internal_display_test_name( "Dequeuing" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements_with_dummy_element = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct test_element);
+ number_elements_without_dummy_element = number_elements_with_dummy_element - 1;
+
+ te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements_with_dummy_element, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_queue_init_valid_on_current_logical_core( &qs, &(te_array + number_elements_without_dummy_element)->qe, &ps, NULL );
+
+ for( loop = 0 ; loop < number_elements_without_dummy_element ; loop++ )
+ {
+ LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( (te_array+loop)->qe, loop );
+ lfds700_queue_enqueue( &qs, &(te_array+loop)->qe, &ps );
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->qs = &qs;
+ (ts+loop)->error_flag = LOWERED;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_simple_dequeuer, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ // TRD : check queue is empty
+ lfds700_queue_query( &qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ // TRD : check for raised error flags
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ if( (ts+loop)->error_flag == RAISED )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ free( ts );
+
+ util_aligned_free( te_array );
+
+ lfds700_queue_cleanup( &qs, NULL );
+
+ internal_display_test_result( 1, "queue", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_dequeuer( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ *prev_value,
+ *value;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_queue_dequeue( ts->qs, &qe, &ps );
+ prev_value = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( lfds700_queue_dequeue(ts->qs, &qe, &ps) )
+ {
+ value = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+
+ if( value <= prev_value )
+ ts->error_flag = RAISED;
+
+ prev_value = value;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing.c
new file mode 100644
index 0000000000..89ccf30fcb
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing.c
@@ -0,0 +1,239 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements,
+ thread_number;
+
+ struct lfds700_queue_state
+ *qs;
+
+ struct test_element
+ *te_array;
+};
+
+struct test_element
+{
+ struct lfds700_queue_element
+ qe;
+
+ lfds700_pal_uint_t
+ counter,
+ thread_number;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_enqueuer( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_enqueuing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ *per_thread_counters,
+ loop,
+ number_elements,
+ number_logical_processors;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_element
+ dummy_qe,
+ *qe;
+
+ struct lfds700_queue_state
+ qs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : create an empty queue
+ then run one thread per CPU
+ where each thread busy-works, enqueuing elements from a freelist (one local freelist per thread)
+ until 100000 elements are enqueued, per thread
+ each element's void pointer of user data is a struct containing thread number and element number
+ where element_number is a thread-local counter starting at 0
+
+ when we're done, we check that all the elements are present
+ and increment on a per-thread basis
+ */
+
+ internal_display_test_name( "Enqueuing" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+
+ lfds700_queue_init_valid_on_current_logical_core( &qs, &dummy_qe, &ps, NULL );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->qs = &qs;
+ (ts+loop)->thread_number = loop;
+ (ts+loop)->number_elements = number_elements;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_simple_enqueuer, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ /* TRD : first, validate the queue
+
+ then dequeue
+ we expect to find element numbers increment on a per thread basis
+ */
+
+ vi.min_elements = vi.max_elements = number_elements * number_logical_processors;
+
+ lfds700_queue_query( &qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ *(per_thread_counters+loop) = 0;
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_queue_dequeue(&qs, &qe, &ps) )
+ {
+ te = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+
+ if( te->thread_number >= number_logical_processors )
+ {
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ break;
+ }
+
+ if( te->counter > per_thread_counters[te->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( te->counter < per_thread_counters[te->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( te->counter == per_thread_counters[te->thread_number] )
+ per_thread_counters[te->thread_number]++;
+ }
+
+ free( per_thread_counters );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ util_aligned_free( (ts+loop)->te_array );
+
+ free( ts );
+
+ lfds700_queue_cleanup( &qs, NULL );
+
+ internal_display_test_result( 1, "queue", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_enqueuer( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ ts->te_array = util_aligned_malloc( sizeof(struct test_element) * ts->number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ (ts->te_array+loop)->thread_number = ts->thread_number;
+ (ts->te_array+loop)->counter = loop;
+ }
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( (ts->te_array+loop)->qe, ts->te_array+loop );
+ lfds700_queue_enqueue( ts->qs, &(ts->te_array+loop)->qe, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_and_dequeuing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_and_dequeuing.c
new file mode 100644
index 0000000000..1469635fd4
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_and_dequeuing.c
@@ -0,0 +1,250 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ enum flag
+ error_flag;
+
+ lfds700_pal_uint_t
+ counter,
+ number_logical_processors,
+ *per_thread_counters,
+ thread_number;
+
+ struct lfds700_queue_state
+ *qs;
+};
+
+struct test_element
+{
+ struct lfds700_queue_element
+ qe,
+ *qe_use;
+
+ lfds700_pal_uint_t
+ counter,
+ thread_number;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueuer_and_dequeuer( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_enqueuing_and_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_logical_processors,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_state
+ qs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : qt can be any value in its range
+
+ /* TRD : create a queue with one element per thread
+ each thread constly dequeues and enqueues from that one queue
+ where when enqueuing sets in the element
+ its thread number and counter
+ and when dequeuing, checks the thread number and counter
+ against previously seen counter for that thread
+ where it should always see a higher number
+ */
+
+ internal_display_test_name( "Enqueuing and dequeuing (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ te_array = util_aligned_malloc( sizeof(struct test_element) * (number_logical_processors+1), LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_queue_init_valid_on_current_logical_core( &qs, &(te_array+number_logical_processors)->qe, &ps, NULL );
+
+ // TRD : we assume the test will iterate at least once (or we'll have a false negative)
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (te_array+loop)->thread_number = loop;
+ (te_array+loop)->counter = 0;
+ LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( (te_array+loop)->qe, te_array+loop );
+ lfds700_queue_enqueue( &qs, &(te_array+loop)->qe, &ps );
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->qs = &qs;
+ (ts+loop)->thread_number = loop;
+ (ts+loop)->counter = 0;
+ (ts+loop)->error_flag = LOWERED;
+ (ts+loop)->per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+ (ts+loop)->number_logical_processors = number_logical_processors;
+
+ for( subloop = 0 ; subloop < number_logical_processors ; subloop++ )
+ *((ts+loop)->per_thread_counters+subloop) = 0;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_enqueuer_and_dequeuer, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_logical_processors;
+
+ lfds700_queue_query( &qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ if( (ts+loop)->error_flag == RAISED )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ free( (ts+loop)->per_thread_counters );
+
+ util_aligned_free( te_array );
+
+ free( ts );
+
+ lfds700_queue_cleanup( &qs, NULL );
+
+ internal_display_test_result( 1, "queue", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueuer_and_dequeuer( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ time_loop = 0;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct test_element
+ *te;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ lfds700_queue_dequeue( ts->qs, &qe, &ps );
+ te = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+
+ if( te->thread_number >= ts->number_logical_processors )
+ ts->error_flag = RAISED;
+ else
+ {
+ if( te->counter < ts->per_thread_counters[te->thread_number] )
+ ts->error_flag = RAISED;
+
+ if( te->counter >= ts->per_thread_counters[te->thread_number] )
+ ts->per_thread_counters[te->thread_number] = te->counter+1;
+ }
+
+ te->thread_number = ts->thread_number;
+ te->counter = ++ts->counter;
+
+ LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( *qe, te );
+ lfds700_queue_enqueue( ts->qs, qe, &ps );
+
+ if( time_loop++ == TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_and_dequeuing_with_free.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_and_dequeuing_with_free.c
new file mode 100644
index 0000000000..21be07052d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_and_dequeuing_with_free.c
@@ -0,0 +1,241 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_of_elements_per_thread;
+
+ struct lfds700_queue_state
+ *qs;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueue_dequeuer_with_free( void *util_thread_starter_thread_state );
+static void queue_element_cleanup_callback( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_enqueuing_and_dequeuing_with_free( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors,
+ number_of_elements_per_thread;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct lfds700_queue_state
+ qs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_state
+ *tts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : the M&Q queue supports free()ing queue elements after they've been dequeued
+ we need to test this
+ we spawn one thread per logical core
+ there's one master queue which all threads work on
+ we create one freelist per thread
+ and allocate as many queue elements as we can (no payload)
+ - but note each allocate is its own malloc()
+ each freelist receives an equal share (i.e. we get the mallocs out of the way)
+ each thread enqueues as rapidly as possible
+ and dequeues as rapidly as possible
+ (i.e. each thread loops, doing an enqueue and a dequeue)
+ when the dequeue is done, the element is free()ed
+ */
+
+ internal_display_test_name( "Enqueuing and dequeuing with free" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct lfds700_freelist_element) + sizeof(struct lfds700_queue_element) );
+ number_of_elements_per_thread = number_elements / number_logical_processors;
+ qe = util_aligned_malloc( sizeof(struct lfds700_queue_element), (lfds700_pal_uint_t) LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+ lfds700_queue_init_valid_on_current_logical_core( &qs, qe, &ps, NULL );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->qs = &qs;
+ (ts+loop)->number_of_elements_per_thread = number_of_elements_per_thread;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_enqueue_dequeuer_with_free, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = 0;
+ vi.max_elements = 0;
+
+ lfds700_queue_query( &qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ lfds700_queue_cleanup( &qs, queue_element_cleanup_callback );
+
+ free( ts );
+
+ internal_display_test_result( 1, "queue", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueue_dequeuer_with_free( void *util_thread_starter_thread_state )
+{
+ enum flag
+ finished_flag = LOWERED;
+
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_freelist_element
+ *fe,
+ *fe_array;
+
+ struct lfds700_freelist_state
+ fs;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_freelist_init_valid_on_current_logical_core( &fs, NULL );
+
+ fe_array = util_malloc_wrapper( sizeof(struct lfds700_freelist_element) * ts->number_of_elements_per_thread );
+
+ for( loop = 0 ; loop < ts->number_of_elements_per_thread ; loop++ )
+ {
+ qe = util_aligned_malloc( sizeof(struct lfds700_queue_element), LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+ LFDS700_FREELIST_SET_VALUE_IN_ELEMENT( fe_array[loop], qe );
+ lfds700_freelist_push( &fs, &fe_array[loop], &ps );
+ }
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( finished_flag == LOWERED )
+ {
+ loop = 0;
+ while( loop++ < 1000 and lfds700_freelist_pop(&fs, &fe, &ps) )
+ {
+ qe = LFDS700_FREELIST_GET_VALUE_FROM_ELEMENT( *fe );
+ lfds700_queue_enqueue( ts->qs, qe, &ps );
+ }
+
+ if( loop < 1000 )
+ finished_flag = RAISED;
+
+ loop = 0;
+ while( loop++ < 1000 and lfds700_queue_dequeue(ts->qs, &qe, &ps) )
+ util_aligned_free( qe );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ lfds700_freelist_cleanup( &fs, NULL );
+
+ free( fe_array );
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void queue_element_cleanup_callback( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag )
+{
+ assert( qs != NULL );
+ assert( qe != NULL );
+ // TRD : dummy_element_flag can be any value in its range
+
+ util_aligned_free( qe );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_with_malloc_and_dequeuing_with_free.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_with_malloc_and_dequeuing_with_free.c
new file mode 100644
index 0000000000..0f0fa7f081
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_enqueuing_with_malloc_and_dequeuing_with_free.c
@@ -0,0 +1,208 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ struct lfds700_queue_state
+ *qs;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueuer_with_malloc_and_dequeuer_with_free( void *util_thread_starter_thread_state );
+static void queue_element_cleanup_callback( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_enqueuing_with_malloc_and_dequeuing_with_free( struct lfds700_list_asu_state *list_of_logical_processors )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_logical_processors;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct lfds700_queue_state
+ qs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : qt can be any value in its range
+
+ /* TRD : one thread per logical core
+ each thread loops for ten seconds
+ mallocs and enqueues 1k elements, then dequeues and frees 1k elements
+ */
+
+ internal_display_test_name( "Enqueuing with malloc dequeuing with free (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ qe = util_aligned_malloc( sizeof(struct lfds700_queue_element), LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_queue_init_valid_on_current_logical_core( &qs, qe, &ps, NULL );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ (ts+loop)->qs = &qs;
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_enqueuer_with_malloc_and_dequeuer_with_free, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = 0;
+
+ lfds700_queue_query( &qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ free( ts );
+
+ lfds700_queue_cleanup( &qs, queue_element_cleanup_callback );
+
+ internal_display_test_result( 1, "queue", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_enqueuer_with_malloc_and_dequeuer_with_free( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop,
+ time_loop = 0;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ for( loop = 0 ; loop < 1000 ; loop++ )
+ {
+ qe = util_aligned_malloc( sizeof(struct lfds700_queue_element), LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+ lfds700_queue_enqueue( ts->qs, qe, &ps );
+ }
+
+ for( loop = 0 ; loop < 1000 ; loop++ )
+ {
+ lfds700_queue_dequeue( ts->qs, &qe, &ps );
+ util_aligned_free( qe );
+ }
+
+ if( time_loop++ == REDUCED_TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+static void queue_element_cleanup_callback( struct lfds700_queue_state *qs, struct lfds700_queue_element *qe, enum lfds700_misc_flag dummy_element_flag )
+{
+ assert( qs != NULL );
+ assert( qe != NULL );
+ // TRD : dummy_element_flag can be any value in its range
+
+ util_aligned_free( qe );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_rapid_enqueuing_and_dequeuing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_rapid_enqueuing_and_dequeuing.c
new file mode 100644
index 0000000000..ec3963a336
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_queue_rapid_enqueuing_and_dequeuing.c
@@ -0,0 +1,264 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ lfds700_pal_uint_t
+ counter,
+ thread_number;
+
+ struct lfds700_queue_state
+ *qs;
+};
+
+struct test_element
+{
+ struct lfds700_queue_element
+ qe,
+ *qe_use;
+
+ lfds700_pal_uint_t
+ counter,
+ thread_number;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_enqueuer_and_dequeuer( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_queue_rapid_enqueuing_and_dequeuing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements_with_dummy_element,
+ number_elements_without_dummy_element,
+ number_logical_processors,
+ *per_thread_counters;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct lfds700_queue_state
+ qs;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array,
+ *te;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a single queue with 50,000 elements
+ we don't want too many elements, so we ensure plenty of element re-use
+ each thread simply loops dequeuing and enqueuing
+ where the user data indicates thread number and an increment counter
+ vertification is that the counter increments on a per-thread basis
+ */
+
+ internal_display_test_name( "Rapid enqueuing and dequeuing (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements_with_dummy_element = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct test_element);
+
+ if( number_elements_with_dummy_element > (10000 * number_logical_processors) + 1 )
+ number_elements_with_dummy_element = (10000 * number_logical_processors) + 1;
+
+ number_elements_without_dummy_element = number_elements_with_dummy_element - 1;
+
+ vi.min_elements = number_elements_without_dummy_element;
+ vi.max_elements = number_elements_without_dummy_element;
+
+ te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements_with_dummy_element, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_queue_init_valid_on_current_logical_core( &qs, &(te_array+number_elements_without_dummy_element)->qe, &ps, NULL );
+
+ // TRD : we assume the test will iterate at least once (or we'll have a false negative)
+ for( loop = 0 ; loop < number_elements_without_dummy_element ; loop++ )
+ {
+ (te_array+loop)->thread_number = loop;
+ (te_array+loop)->counter = 0;
+ LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( (te_array+loop)->qe, te_array+loop );
+ lfds700_queue_enqueue( &qs, &(te_array+loop)->qe, &ps );
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->qs = &qs;
+ (ts+loop)->thread_number = loop;
+ (ts+loop)->counter = 0;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_rapid_enqueuer_and_dequeuer, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lfds700_queue_query( &qs, LFDS700_QUEUE_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ // TRD : now check results
+ per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ *(per_thread_counters+loop) = 0;
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_queue_dequeue(&qs, &qe, &ps) )
+ {
+ te = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+
+ if( te->thread_number >= number_logical_processors )
+ {
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ break;
+ }
+
+ if( per_thread_counters[te->thread_number] == 0 )
+ per_thread_counters[te->thread_number] = te->counter;
+
+ if( te->counter > per_thread_counters[te->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( te->counter < per_thread_counters[te->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( te->counter == per_thread_counters[te->thread_number] )
+ per_thread_counters[te->thread_number]++;
+ }
+
+ free( per_thread_counters );
+
+ lfds700_queue_cleanup( &qs, NULL );
+
+ util_aligned_free( te_array );
+
+ free( ts );
+
+ internal_display_test_result( 1, "queue", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_enqueuer_and_dequeuer( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ time_loop = 0;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_queue_element
+ *qe;
+
+ struct test_element
+ *te;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ lfds700_queue_dequeue( ts->qs, &qe, &ps );
+ te = LFDS700_QUEUE_GET_VALUE_FROM_ELEMENT( *qe );
+
+ te->thread_number = ts->thread_number;
+ te->counter = ts->counter++;
+
+ LFDS700_QUEUE_SET_VALUE_IN_ELEMENT( *qe, te );
+ lfds700_queue_enqueue( ts->qs, qe, &ps );
+
+ if( time_loop++ == TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer.c
new file mode 100644
index 0000000000..0a7de0761b
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer.c
@@ -0,0 +1,31 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_ringbuffer( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_DWCAS )
+ {
+ printf( "\n"
+ "Ringbuffer Tests\n"
+ "================\n" );
+
+ test_lfds700_ringbuffer_reading( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_ringbuffer_reading_and_writing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_ringbuffer_writing( list_of_logical_processors, memory_in_megabytes );
+ }
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_reading.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_reading.c
new file mode 100644
index 0000000000..00d378992e
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_reading.c
@@ -0,0 +1,217 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ enum flag
+ error_flag;
+
+ lfds700_pal_uint_t
+ read_count;
+
+ struct lfds700_ringbuffer_state
+ *rs;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_reader( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_ringbuffer_reading( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs[2] = { LFDS700_MISC_VALIDITY_VALID, LFDS700_MISC_VALIDITY_VALID };
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements_with_dummy_element,
+ number_elements_without_dummy_element,
+ number_logical_processors,
+ total_read = 0;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_ringbuffer_element
+ *re_array;
+
+ struct lfds700_ringbuffer_state
+ rs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a single ringbuffer
+ with 1,000,000 elements
+ we populate the ringbuffer, where the
+ user data is an incrementing counter
+
+ we create one thread per CPU
+ where each thread busy-works,
+ reading until the ringbuffer is empty
+
+ each thread keep track of the number of reads it manages
+ and that each user data it reads is greater than the
+ previous user data that was read
+ */
+
+ internal_display_test_name( "Reading" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements_with_dummy_element = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct lfds700_ringbuffer_element);
+ number_elements_without_dummy_element = number_elements_with_dummy_element - 1;
+
+ vi.min_elements = 0;
+ vi.max_elements = number_elements_without_dummy_element;
+
+ re_array = util_aligned_malloc( sizeof(struct lfds700_ringbuffer_element) * number_elements_with_dummy_element, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_ringbuffer_init_valid_on_current_logical_core( &rs, re_array, number_elements_with_dummy_element, &ps, NULL );
+
+ // TRD : init the ringbuffer contents for the test
+ for( loop = 0 ; loop < number_elements_without_dummy_element ; loop++ )
+ lfds700_ringbuffer_write( &rs, NULL, (void *) (size_t) loop, NULL, NULL, NULL, &ps );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->rs = &rs;
+ (ts+loop)->read_count = 0;
+ (ts+loop)->error_flag = LOWERED;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_simple_reader, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lfds700_ringbuffer_query( &rs, LFDS700_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) dvs );
+
+ // TRD : check for raised error flags
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ if( (ts+loop)->error_flag == RAISED )
+ dvs[0] = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ // TRD : check thread reads total to 1,000,000
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ total_read += (ts+loop)->read_count;
+
+ if( total_read < number_elements_without_dummy_element )
+ dvs[0] = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( total_read > number_elements_without_dummy_element )
+ dvs[0] = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ free( ts );
+
+ lfds700_ringbuffer_cleanup( &rs, NULL );
+
+ util_aligned_free( re_array );
+
+ internal_display_test_result( 2, "queue", dvs[0], "freelist", dvs[1] );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_reader( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ *prev_value,
+ *value;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_ringbuffer_read( ts->rs, NULL, (void **) &prev_value, &ps );
+ ts->read_count++;
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( lfds700_ringbuffer_read(ts->rs, NULL, (void **) &value, &ps) )
+ {
+ if( value <= prev_value )
+ ts->error_flag = RAISED;
+
+ prev_value = value;
+
+ ts->read_count++;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_reading_and_writing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_reading_and_writing.c
new file mode 100644
index 0000000000..152c331892
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_reading_and_writing.c
@@ -0,0 +1,261 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ enum flag
+ error_flag;
+
+ lfds700_pal_uint_t
+ counter,
+ number_logical_processors,
+ *per_thread_counters,
+ thread_number;
+
+ struct lfds700_ringbuffer_state
+ *rs;
+};
+
+struct test_element
+{
+ lfds700_pal_uint_t
+ datum,
+ thread_number;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_reader_writer( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_ringbuffer_reading_and_writing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs[2] = { LFDS700_MISC_VALIDITY_VALID, LFDS700_MISC_VALIDITY_VALID };
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements_with_dummy_element,
+ number_elements_without_dummy_element,
+ number_logical_processors,
+ subloop;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_ringbuffer_element
+ *re_array;
+
+ struct lfds700_ringbuffer_state
+ rs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a single ringbuffer
+ with 100,000 elements
+ the ringbuffers starts empty
+
+ we create one thread per CPU
+ where each thread busy-works writing
+ and then immediately reading
+ for ten seconds
+
+ the user data in each written element is a combination
+ of the thread number and the counter
+
+ while a thread runs, it keeps track of the
+ counters for the other threads and throws an error
+ if it sees the number stay the same or decrease
+ */
+
+ internal_display_test_name( "Reading and writing (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements_with_dummy_element = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) + sizeof(struct lfds700_ringbuffer_element) );
+ number_elements_without_dummy_element = number_elements_with_dummy_element - 1;
+
+ vi.min_elements = 0;
+ vi.max_elements = number_elements_without_dummy_element;
+
+ re_array = util_aligned_malloc( sizeof(struct lfds700_ringbuffer_element) * number_elements_with_dummy_element, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_ringbuffer_init_valid_on_current_logical_core( &rs, re_array, number_elements_with_dummy_element, &ps, NULL );
+
+ te_array = util_malloc_wrapper( sizeof(struct test_element) * number_elements_without_dummy_element );
+
+ // TRD : populate the ringbuffer
+ for( loop = 0 ; loop < number_elements_without_dummy_element ; loop++ )
+ {
+ te_array[loop].thread_number = 0;
+ te_array[loop].datum = (lfds700_pal_uint_t) -1 ;
+ lfds700_ringbuffer_write( &rs, NULL, &te_array[loop], NULL, NULL, NULL, &ps );
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->rs = &rs;
+ (ts+loop)->thread_number = loop;
+ (ts+loop)->counter = 0;
+ (ts+loop)->number_logical_processors = number_logical_processors;
+ (ts+loop)->error_flag = LOWERED;
+ (ts+loop)->per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( subloop = 0 ; subloop < number_logical_processors ; subloop++ )
+ *((ts+loop)->per_thread_counters+subloop) = 0;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_reader_writer, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lfds700_ringbuffer_query( &rs, LFDS700_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE, (void *) &vi, (void *) dvs );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ if( (ts+loop)->error_flag == RAISED )
+ dvs[0] = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ free( (ts+loop)->per_thread_counters );
+
+ free( ts );
+
+ lfds700_ringbuffer_cleanup( &rs, NULL );
+
+ util_aligned_free( re_array );
+
+ free( te_array );
+
+ internal_display_test_result( 2, "queue", dvs[0], "freelist", dvs[1] );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_reader_writer( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ time_loop = 0;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_element
+ *te;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ lfds700_ringbuffer_read( ts->rs, NULL, (void **) &te, &ps );
+
+ if( te->thread_number >= ts->number_logical_processors )
+ ts->error_flag = RAISED;
+ else
+ {
+ if( te->datum < ts->per_thread_counters[te->thread_number] )
+ ts->error_flag = RAISED;
+
+ if( te->datum >= ts->per_thread_counters[te->thread_number] )
+ ts->per_thread_counters[te->thread_number] = te->datum+1;
+ }
+
+ te->thread_number = ts->thread_number;
+ te->datum = ts->counter++;
+
+ lfds700_ringbuffer_write( ts->rs, NULL, te, NULL, NULL, NULL, &ps );
+
+ if( time_loop++ == TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_writing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_writing.c
new file mode 100644
index 0000000000..702aabc58d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_ringbuffer_writing.c
@@ -0,0 +1,272 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element
+{
+ lfds700_pal_uint_t
+ thread_number,
+ datum;
+};
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ thread_number,
+ write_count;
+
+ struct test_element
+ te;
+
+ struct lfds700_ringbuffer_state
+ *rs;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_writer( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_ringbuffer_writing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs[2] = { LFDS700_MISC_VALIDITY_VALID, LFDS700_MISC_VALIDITY_VALID };
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements_with_dummy_element,
+ number_elements_without_dummy_element,
+ number_logical_processors,
+ *per_thread_counters;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_ringbuffer_element
+ *re_array;
+
+ struct lfds700_ringbuffer_state
+ rs;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te,
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a single ringbuffer
+ with n elements
+ we create n test elements
+ which are thread_number/counter pairs
+ init them to safe values
+ and fully populate the ringbuffer
+
+ we create one thread per CPU
+ where each thread busy-works writing
+ for ten seconds; each thread has one extra element
+ which it uses for the first write and after that
+ it uses the element it picks up from overwriting
+
+ the user data in each written element is a combination
+ of the thread number and the counter
+
+ after the threads are complete, we validate by
+ checking the user data counters increment on a per thread
+ basis
+ */
+
+ internal_display_test_name( "Writing (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements_with_dummy_element = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) + sizeof(struct lfds700_ringbuffer_element) );
+ number_elements_without_dummy_element = number_elements_with_dummy_element - 1;
+
+ vi.min_elements = number_elements_without_dummy_element;
+ vi.max_elements = number_elements_without_dummy_element;
+
+ re_array = util_aligned_malloc( sizeof(struct lfds700_ringbuffer_element) * number_elements_with_dummy_element, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lfds700_ringbuffer_init_valid_on_current_logical_core( &rs, re_array, number_elements_with_dummy_element, &ps, NULL );
+
+ te_array = util_malloc_wrapper( sizeof(struct lfds700_ringbuffer_element) * number_elements_without_dummy_element );
+
+ // TRD : init the test elements and write them into the ringbuffer
+ for( loop = 0 ; loop < number_elements_without_dummy_element ; loop++ )
+ {
+ te_array[loop].thread_number = 0;
+ te_array[loop].datum = 0;
+ lfds700_ringbuffer_write( &rs, NULL, &te_array[loop], NULL, NULL, NULL, &ps );
+ }
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->rs = &rs;
+ (ts+loop)->thread_number = loop;
+ (ts+loop)->write_count = 0;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_simple_writer, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ // TRD : now check results
+ per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ *(per_thread_counters+loop) = 0;
+
+ lfds700_ringbuffer_query( &rs, LFDS700_RINGBUFFER_QUERY_SINGLETHREADED_VALIDATE, &vi, dvs );
+
+ while( dvs[0] == LFDS700_MISC_VALIDITY_VALID and dvs[1] == LFDS700_MISC_VALIDITY_VALID and lfds700_ringbuffer_read(&rs, NULL, (void **) &te, &ps) )
+ {
+ if( te->thread_number >= number_logical_processors )
+ {
+ dvs[0] = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ break;
+ }
+
+ if( per_thread_counters[te->thread_number] == 0 )
+ per_thread_counters[te->thread_number] = te->datum;
+
+ if( te->datum < per_thread_counters[te->thread_number] )
+ dvs[0] = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( te->datum >= per_thread_counters[te->thread_number] )
+ per_thread_counters[te->thread_number] = te->datum+1;
+ }
+
+ free( per_thread_counters );
+
+ lfds700_ringbuffer_cleanup( &rs, NULL );
+
+ free( ts );
+
+ util_aligned_free( re_array );
+
+ free( te_array );
+
+ internal_display_test_result( 2, "queue", dvs[0], "freelist", dvs[1] );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_simple_writer( void *util_thread_starter_thread_state )
+{
+ enum lfds700_misc_flag
+ overwrite_occurred_flag;
+
+ lfds700_pal_uint_t
+ time_loop = 0;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_element
+ *te;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ ts->te.thread_number = 0;
+ ts->te.datum = 0;
+
+ lfds700_ringbuffer_write( ts->rs, NULL, &ts->te, &overwrite_occurred_flag, NULL, (void **) &te, &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ te->thread_number = ts->thread_number;
+ te->datum = ts->write_count++;
+
+ lfds700_ringbuffer_write( ts->rs, NULL, te, &overwrite_occurred_flag, NULL, (void **) &te, &ps );
+
+ if( time_loop++ == TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack.c
new file mode 100644
index 0000000000..af3a37512a
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack.c
@@ -0,0 +1,33 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_stack( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ if( LFDS700_MISC_ATOMIC_SUPPORT_DWCAS )
+ {
+ printf( "\n"
+ "Stack Tests\n"
+ "===========\n" );
+
+ test_lfds700_stack_alignment();
+ test_lfds700_stack_popping( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_stack_pushing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_stack_popping_and_pushing( list_of_logical_processors, memory_in_megabytes );
+ test_lfds700_stack_rapid_popping_and_pushing( list_of_logical_processors );
+ }
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_alignment.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_alignment.c
new file mode 100644
index 0000000000..7add41bd48
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_alignment.c
@@ -0,0 +1,43 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4127 ) // TRD : disables MSVC warning for condition expressions being const
+
+void test_lfds700_stack_alignment()
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ /* TRD : these are compile time checks
+ but we do them here because this is a test programme
+ and it should indicate issues to users when it is *run*,
+ not when it is compiled, because a compile error normally
+ indicates a problem with the code itself and so is misleading
+ */
+
+ internal_display_test_name( "Alignment" );
+
+
+
+ // TRD : struct lfds700_stack_state
+ if( offsetof(struct lfds700_stack_state,top) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ if( offsetof(struct lfds700_stack_state,user_state) % LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES != 0 )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "stack", dvs );
+
+ return;
+}
+
+#pragma warning( default : 4127 )
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_popping.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_popping.c
new file mode 100644
index 0000000000..461730604c
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_popping.c
@@ -0,0 +1,202 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ struct lfds700_stack_state
+ *ss;
+};
+
+struct test_element
+{
+ struct lfds700_stack_element
+ se;
+
+ enum flag
+ popped_flag;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_stack_popping( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_stack_state
+ ss;
+
+ struct lfds700_misc_validation_info
+ vi = { 0, 0 };
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create a stack
+
+ we then populate the stack with 1,000,000 elements
+ each void pointer of data points to the containing test element
+
+ we then run one thread per CPU
+ where each thread loops, popping as quickly as possible
+ upon popping, a flag is set in the containing test element
+
+ the threads run till the source stack is empty
+
+ we then check the poppged flag, all should be raised
+
+ then tidy up
+
+ no CAS+GC code, as we only pop
+ */
+
+ internal_display_test_name( "Popping" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_stack_init_valid_on_current_logical_core( &ss, NULL );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / sizeof(struct test_element) ;
+
+ te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ {
+ (te_array+loop)->popped_flag = LOWERED;
+ LFDS700_STACK_SET_VALUE_IN_ELEMENT( (te_array+loop)->se, te_array+loop );
+ lfds700_stack_push( &ss, &(te_array+loop)->se, &ps );
+ }
+
+ ts = util_aligned_malloc( sizeof(struct test_state) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ (ts+loop)->ss = &ss;
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_popping, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ lfds700_stack_query( &ss, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, (void *) &dvs );
+
+ // TRD : now we check each element has popped_flag set to RAISED
+ for( loop = 0 ; loop < number_elements ; loop++ )
+ if( (te_array+loop)->popped_flag == LOWERED )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+
+ // TRD : cleanup
+ lfds700_stack_cleanup( &ss, NULL );
+ util_aligned_free( te_array );
+ util_aligned_free( ts );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "stack", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping( void *util_thread_starter_thread_state )
+{
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_stack_element
+ *se;
+
+ struct test_element
+ *te;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ while( lfds700_stack_pop(ts->ss, &se, &ps) )
+ {
+ te = LFDS700_STACK_GET_VALUE_FROM_ELEMENT( *se );
+ te->popped_flag = RAISED;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_popping_and_pushing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_popping_and_pushing.c
new file mode 100644
index 0000000000..03c3254c77
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_popping_and_pushing.c
@@ -0,0 +1,316 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_element;
+
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements;
+
+ struct lfds700_stack_state
+ *ss,
+ ss_thread_local;
+
+ struct test_element
+ *ss_thread_local_te_array;
+};
+
+struct test_element
+{
+ struct lfds700_stack_element
+ se,
+ thread_local_se;
+
+ lfds700_pal_uint_t
+ datum;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping_and_pushing_start_popping( void *util_thread_starter_thread_state );
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping_and_pushing_start_pushing( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_stack_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors,
+ subloop;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_stack_state
+ ss;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we have two threads per CPU
+ the threads loop for ten seconds
+ the first thread pushes 10000 elements then pops 10000 elements
+ the second thread pops 10000 elements then pushes 10000 elements
+ all pushes and pops go onto the single main stack
+
+ after time is up, all threads push what they have remaining onto
+ the main stack
+
+ we then validate the main stack
+ */
+
+ internal_display_test_name( "Popping and pushing (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors * 2 );
+
+ lfds700_stack_init_valid_on_current_logical_core( &ss, NULL );
+
+ te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ // TRD : some initial elements so the pushing threads can start immediately
+ for( loop = 0 ; loop < number_elements * number_logical_processors ; loop++ )
+ {
+ (te_array+loop)->datum = loop;
+ LFDS700_STACK_SET_VALUE_IN_ELEMENT( (te_array+loop)->se, te_array+loop );
+ lfds700_stack_push( &ss, &(te_array+loop)->se, &ps );
+ }
+
+ ts = util_aligned_malloc( sizeof(struct test_state) * number_logical_processors * 2, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ // TRD : first set of threads
+ (ts+loop)->ss = &ss;
+ (ts+loop)->number_elements = number_elements;
+ lfds700_stack_init_valid_on_current_logical_core( &(ts+loop)->ss_thread_local, NULL );
+
+ // TRD : second set of threads
+ (ts+loop+number_logical_processors)->ss = &ss;
+ (ts+loop+number_logical_processors)->number_elements = number_elements;
+ lfds700_stack_init_valid_on_current_logical_core( &(ts+loop+number_logical_processors)->ss_thread_local, NULL );
+
+ // TRD : fill the pushing thread stacks
+ (ts+loop+number_logical_processors)->ss_thread_local_te_array = util_aligned_malloc( sizeof(struct test_element) * number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( subloop = 0 ; subloop < number_elements ; subloop++ )
+ {
+ ((ts+loop+number_logical_processors)->ss_thread_local_te_array+subloop)->datum = loop;
+ LFDS700_STACK_SET_VALUE_IN_ELEMENT( ((ts+loop+number_logical_processors)->ss_thread_local_te_array+subloop)->thread_local_se, (ts+loop+number_logical_processors)->ss_thread_local_te_array+subloop );
+ lfds700_stack_push( &(ts+loop+number_logical_processors)->ss_thread_local, &((ts+loop+number_logical_processors)->ss_thread_local_te_array+subloop)->thread_local_se, &ps );
+ }
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors * 2 );
+
+ util_thread_starter_new( &tts, number_logical_processors * 2 );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_popping_and_pushing_start_popping, ts+loop );
+ util_thread_starter_start( tts, &thread_handles[loop+number_logical_processors], loop+number_logical_processors, lp, thread_popping_and_pushing_start_pushing, ts+loop+number_logical_processors );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors * 2 ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_elements * number_logical_processors * 2;
+
+ lfds700_stack_query( &ss, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ lfds700_stack_cleanup( &ss, NULL );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ lfds700_stack_cleanup( &(ts+loop)->ss_thread_local, NULL );
+ lfds700_stack_cleanup( &(ts+loop+number_logical_processors)->ss_thread_local, NULL );
+ util_aligned_free( (ts+loop+number_logical_processors)->ss_thread_local_te_array );
+ }
+
+ util_aligned_free( ts );
+
+ util_aligned_free( te_array );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "stack", dvs );
+
+ return;
+}
+
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping_and_pushing_start_popping( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ count;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_stack_element
+ *se;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ start_time = time( NULL );
+
+ while( time(NULL) < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ count = 0;
+
+ while( count < ts->number_elements )
+ if( lfds700_stack_pop(ts->ss, &se, &ps) )
+ {
+ lfds700_stack_push( &ts->ss_thread_local, se, &ps );
+ count++;
+ }
+
+ // TRD : return our local stack to the main stack
+ while( lfds700_stack_pop(&ts->ss_thread_local, &se, &ps) )
+ lfds700_stack_push( ts->ss, se, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_popping_and_pushing_start_pushing( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ count;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_stack_element
+ *se;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ start_time = time( NULL );
+
+ while( time(NULL) < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ // TRD : return our local stack to the main stack
+ while( lfds700_stack_pop(&ts->ss_thread_local, &se, &ps) )
+ lfds700_stack_push( ts->ss, se, &ps );
+
+ count = 0;
+
+ while( count < ts->number_elements )
+ if( lfds700_stack_pop(ts->ss, &se, &ps) )
+ {
+ lfds700_stack_push( &ts->ss_thread_local, se, &ps );
+ count++;
+ }
+ }
+
+ // TRD : now push whatever we have in our local stack
+ while( lfds700_stack_pop(&ts->ss_thread_local, &se, &ps) )
+ lfds700_stack_push( ts->ss, se, &ps );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_pushing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_pushing.c
new file mode 100644
index 0000000000..bdf2b9b640
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_pushing.c
@@ -0,0 +1,251 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ lfds700_pal_uint_t
+ number_elements,
+ thread_number;
+
+ struct lfds700_stack_state
+ *ss;
+
+ struct test_element
+ *te_array;
+};
+
+struct test_element
+{
+ struct lfds700_stack_element
+ se;
+
+ lfds700_pal_uint_t
+ datum,
+ thread_number;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_pushing( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_stack_pushing( struct lfds700_list_asu_state *list_of_logical_processors, lfds700_pal_uint_t memory_in_megabytes )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_elements,
+ number_logical_processors,
+ *per_thread_counters;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_stack_element
+ *se;
+
+ struct lfds700_stack_state
+ ss;
+
+ struct lfds700_misc_validation_info
+ vi;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te,
+ *first_te = NULL;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : memory_in_megabytes can be any value in its range
+
+ /* TRD : we create an empty stack
+
+ we then create one thread per CPU, where each thread
+ pushes 100,000 elements each as quickly as possible to the stack
+ (the threads themselves alloc these elements, to obtain NUMA closeness)
+
+ the data pushed is a counter and a thread ID
+
+ the threads exit when the stack is full
+
+ we then validate the stack;
+
+ checking that the counts increment on a per unique ID basis
+ and that the number of elements we pop equals 100,000 per thread
+ (since each element has an incrementing counter which is
+ unique on a per unique ID basis, we can know we didn't lose
+ any elements)
+
+ there's no CAS+GC code, as we only push
+ */
+
+ internal_display_test_name( "Pushing" );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ number_elements = ( memory_in_megabytes * ONE_MEGABYTE_IN_BYTES ) / ( sizeof(struct test_element) * number_logical_processors );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ // TRD : the main stack
+ lfds700_stack_init_valid_on_current_logical_core( &ss, NULL );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ (ts+loop)->ss = &ss;
+ (ts+loop)->thread_number = loop;
+ (ts+loop)->number_elements = number_elements;
+ }
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_pushing, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ // TRD : the stack is now fully pushed; time to verify
+ per_thread_counters = util_malloc_wrapper( sizeof(lfds700_pal_uint_t) * number_logical_processors );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ *(per_thread_counters+loop) = number_elements - 1;
+
+ vi.min_elements = vi.max_elements = number_elements * number_logical_processors;
+
+ lfds700_stack_query( &ss, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ while( dvs == LFDS700_MISC_VALIDITY_VALID and lfds700_stack_pop(&ss, &se, &ps) )
+ {
+ te = LFDS700_STACK_GET_VALUE_FROM_ELEMENT( *se );
+
+ if( first_te == NULL )
+ first_te = te;
+
+ if( te->thread_number >= number_logical_processors )
+ {
+ dvs = LFDS700_MISC_VALIDITY_INVALID_TEST_DATA;
+ break;
+ }
+
+ if( te->datum > per_thread_counters[te->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_ADDITIONAL_ELEMENTS;
+
+ if( te->datum < per_thread_counters[te->thread_number] )
+ dvs = LFDS700_MISC_VALIDITY_INVALID_MISSING_ELEMENTS;
+
+ if( te->datum == per_thread_counters[te->thread_number] )
+ per_thread_counters[te->thread_number]--;
+ }
+
+ // TRD : clean up
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ util_aligned_free( (ts+loop)->te_array );
+
+ free( per_thread_counters );
+
+ free( ts );
+
+ lfds700_stack_cleanup( &ss, NULL );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "stack", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_pushing( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ // TRD : alloc local 100,000 elements
+ ts->te_array = util_aligned_malloc( sizeof(struct test_element) * ts->number_elements, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ (ts->te_array+loop)->thread_number = ts->thread_number;
+ (ts->te_array+loop)->datum = loop;
+ }
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ for( loop = 0 ; loop < ts->number_elements ; loop++ )
+ {
+ LFDS700_STACK_SET_VALUE_IN_ELEMENT( (ts->te_array+loop)->se, ts->te_array+loop );
+ lfds700_stack_push( ts->ss, &(ts->te_array+loop)->se, &ps );
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_rapid_popping_and_pushing.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_rapid_popping_and_pushing.c
new file mode 100644
index 0000000000..d771457c86
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_lfds700_stack_rapid_popping_and_pushing.c
@@ -0,0 +1,217 @@
+/***** includes *****/
+#include "internal.h"
+
+/***** structs *****/
+struct test_state
+{
+ struct lfds700_stack_state
+ *ss;
+};
+
+struct test_element
+{
+ struct lfds700_stack_element
+ se;
+
+ lfds700_pal_uint_t
+ datum;
+};
+
+/***** private prototypes *****/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *util_thread_starter_thread_state );
+
+
+
+
+
+/****************************************************************************/
+void test_lfds700_stack_rapid_popping_and_pushing( struct lfds700_list_asu_state *list_of_logical_processors )
+{
+ enum lfds700_misc_validity
+ dvs = LFDS700_MISC_VALIDITY_VALID;
+
+ lfds700_pal_uint_t
+ loop,
+ number_logical_processors;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_list_asu_element
+ *lasue;
+
+ struct lfds700_stack_state
+ ss;
+
+ struct lfds700_misc_validation_info
+ vi = { 0, 0 };
+
+ struct test_pal_logical_processor
+ *lp;
+
+ struct util_thread_starter_state
+ *tts;
+
+ struct test_element
+ *te_array;
+
+ struct test_state
+ *ts;
+
+ test_pal_thread_state_t
+ *thread_handles;
+
+ assert( list_of_logical_processors != NULL );
+ // TRD : st can be any value in its range
+
+ /* TRD : in these tests there is a fundamental antagonism between
+ how much checking/memory clean up that we do and the
+ likelyhood of collisions between threads in their lock-free
+ operations
+
+ the lock-free operations are very quick; if we do anything
+ much at all between operations, we greatly reduce the chance
+ of threads colliding
+
+ so we have some tests which do enough checking/clean up that
+ they can tell the stack is valid and don't leak memory
+ and here, this test now is one of those which does minimal
+ checking - in fact, the nature of the test is that you can't
+ do any real checking - but goes very quickly
+
+ what we do is create a small stack and then run one thread
+ per CPU, where each thread simply pushes and then immediately
+ pops
+
+ the test runs for ten seconds
+
+ after the test is done, the only check we do is to traverse
+ the stack, checking for loops and ensuring the number of
+ elements is correct
+ */
+
+ internal_display_test_name( "Rapid popping and pushing (%d seconds)", TEST_DURATION_IN_SECONDS );
+
+ lfds700_list_asu_query( list_of_logical_processors, LFDS700_LIST_ASU_QUERY_GET_POTENTIALLY_INACCURATE_COUNT, NULL, (void **) &number_logical_processors );
+
+ lfds700_misc_prng_init( &ps );
+
+ ts = util_malloc_wrapper( sizeof(struct test_state) * number_logical_processors );
+
+ lfds700_stack_init_valid_on_current_logical_core( &ss, NULL );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ (ts+loop)->ss = &ss;
+
+ thread_handles = util_malloc_wrapper( sizeof(test_pal_thread_state_t) * number_logical_processors );
+
+ // TRD : we need one element per thread
+ te_array = util_aligned_malloc( sizeof(struct test_element) * number_logical_processors, LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ {
+ LFDS700_STACK_SET_VALUE_IN_ELEMENT( (te_array+loop)->se, te_array+loop );
+ lfds700_stack_push( &ss, &(te_array+loop)->se, &ps );
+ }
+
+ util_thread_starter_new( &tts, number_logical_processors );
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ loop = 0;
+ lasue = NULL;
+
+ while( LFDS700_LIST_ASU_GET_START_AND_THEN_NEXT(*list_of_logical_processors, lasue) )
+ {
+ lp = LFDS700_LIST_ASU_GET_VALUE_FROM_ELEMENT( *lasue );
+ util_thread_starter_start( tts, &thread_handles[loop], loop, lp, thread_rapid_popping_and_pushing, ts+loop );
+ loop++;
+ }
+
+ util_thread_starter_run( tts );
+
+ for( loop = 0 ; loop < number_logical_processors ; loop++ )
+ test_pal_thread_wait( thread_handles[loop] );
+
+ util_thread_starter_delete( tts );
+
+ free( thread_handles );
+
+ LFDS700_MISC_BARRIER_LOAD;
+
+ vi.min_elements = vi.max_elements = number_logical_processors;
+
+ lfds700_stack_query( &ss, LFDS700_STACK_QUERY_SINGLETHREADED_VALIDATE, &vi, &dvs );
+
+ lfds700_stack_cleanup( &ss, NULL );
+
+ util_aligned_free( te_array );
+
+ free( ts );
+
+ // TRD : print the test result
+ internal_display_test_result( 1, "stack", dvs );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+static test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION thread_rapid_popping_and_pushing( void *util_thread_starter_thread_state )
+{
+ lfds700_pal_uint_t
+ time_loop = 0;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct lfds700_stack_element
+ *se;
+
+ struct test_state
+ *ts;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+
+ time_t
+ current_time,
+ start_time;
+
+ LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
+
+ assert( util_thread_starter_thread_state != NULL );
+
+ tsts = (struct util_thread_starter_thread_state *) util_thread_starter_thread_state;
+ ts = (struct test_state *) tsts->thread_user_state;
+
+ lfds700_misc_prng_init( &ps );
+
+ util_thread_starter_ready_and_wait( tsts );
+
+ current_time = start_time = time( NULL );
+
+ while( current_time < start_time + TEST_DURATION_IN_SECONDS )
+ {
+ lfds700_stack_pop( ts->ss, &se, &ps );
+ lfds700_stack_push( ts->ss, se, &ps );
+
+ if( time_loop++ == TIME_LOOP_COUNT )
+ {
+ time_loop = 0;
+ time( ¤t_time );
+ }
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return( (test_pal_thread_return_t) EXIT_SUCCESS );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_get_logical_core_ids.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_get_logical_core_ids.c
new file mode 100644
index 0000000000..eb62c5b4cc
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_get_logical_core_ids.c
@@ -0,0 +1,245 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#if( defined _WIN32 && !defined _KERNEL_MODE && NTDDI_VERSION >= NTDDI_WIN7 )
+
+ /* TRD : _WIN32 indicates 64-bit or 32-bit Windows
+ !_KERNEL_MODE indicates Windows user-mode
+ NTDDI_VERSION indicates Windows version
+ - GetLogicalProcessorInformationEx requires Windows 7
+ */
+
+ #ifdef TEST_PAL_GET_LOGICAL_CORE_IDS
+ #error More than one porting abstraction layer matches current platform in test_porting_abstraction_layer_get_logical_core_ids.c
+ #endif
+
+ #define TEST_PAL_GET_LOGICAL_CORE_IDS
+
+ void test_pal_get_logical_core_ids( struct lfds700_list_asu_state *lasus )
+ {
+ BOOL
+ rv;
+
+ DWORD
+ loop,
+ number_slpie,
+ slpie_length = 0;
+
+ lfds700_pal_uint_t
+ bitmask,
+ logical_processor_number,
+ windows_logical_processor_group_number;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
+ *slpie = NULL;
+
+ assert( lasus != NULL );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_init_valid_on_current_logical_core( lasus, NULL, NULL );
+
+ rv = GetLogicalProcessorInformationEx( RelationGroup, slpie, &slpie_length );
+ slpie = malloc( slpie_length );
+ rv = GetLogicalProcessorInformationEx( RelationGroup, slpie, &slpie_length );
+ number_slpie = slpie_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX);
+
+ for( loop = 0 ; loop < number_slpie ; loop++ )
+ if( (slpie+loop)->Relationship == RelationGroup )
+ for( windows_logical_processor_group_number = 0 ; windows_logical_processor_group_number < (slpie+loop)->Group.ActiveGroupCount ; windows_logical_processor_group_number++ )
+ for( logical_processor_number = 0 ; logical_processor_number < sizeof(KAFFINITY) * BITS_PER_BYTE ; logical_processor_number++ )
+ {
+ bitmask = (lfds700_pal_uint_t) 1 << logical_processor_number;
+
+ // TRD : if we've found a processor for this group, add it to the list
+ if( (slpie+loop)->Group.GroupInfo[windows_logical_processor_group_number].ActiveProcessorMask & bitmask )
+ {
+ lp = util_aligned_malloc( sizeof(struct test_pal_logical_processor), LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lp->logical_processor_number = logical_processor_number;
+ lp->windows_logical_processor_group_number = windows_logical_processor_group_number;
+
+ LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( lp->lasue, lp );
+ lfds700_list_asu_insert_at_start( lasus, &lp->lasue, &ps );
+ }
+ }
+
+ free( slpie );
+
+ return;
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined _WIN32 && !defined _KERNEL_MODE && NTDDI_VERSION >= NTDDI_WINXP && NTDDI_VERSION < NTDDI_WIN7 )
+
+ /* TRD : _WIN32 indicates 64-bit or 32-bit Windows
+ !_KERNEL_MODE indicates Windows user-mode
+ NTDDI_VERSION indicates Windows version
+ - GetLogicalProcessorInformation requires XP SP3
+ */
+
+ #ifdef TEST_PAL_GET_LOGICAL_CORE_IDS
+ #error More than one porting abstraction layer matches current platform in test_porting_abstraction_layer_get_logical_core_ids.c
+ #endif
+
+ #define TEST_PAL_GET_LOGICAL_CORE_IDS
+
+ void test_pal_get_logical_core_ids( struct lfds700_list_asu_state *lasus )
+ {
+ DWORD
+ slpi_length = 0;
+
+ lfds700_pal_uint_t
+ number_slpi,
+ loop;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ SYSTEM_LOGICAL_PROCESSOR_INFORMATION
+ *slpi = NULL;
+
+ ULONG_PTR
+ mask;
+
+ assert( lasus != NULL );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_init_valid_on_current_logical_core( lasus, NULL, NULL );
+
+ *number_logical_processors = 0;
+
+ GetLogicalProcessorInformation( slpi, &slpi_length );
+ slpi = malloc( slpi_length );
+ GetLogicalProcessorInformation( slpi, &slpi_length );
+ number_slpi = slpi_length / sizeof(SYSTEM_LOGICAL_PROCESSOR_INFORMATION);
+
+ for( loop = 0 ; loop < number_slpi ; loop++ )
+ if( (slpi+loop)->Relationship == RelationProcessorCore )
+ for( logical_processor_number = 0 ; logical_processor_number < sizeof(ULONG_PTR) * BITS_PER_BYTE ; logical_processor_number++ )
+ {
+ bitmask = 1 << logical_processor_number;
+
+ if( (slpi+loop)->ProcessorMask & bitmask )
+ {
+ lp = util_aligned_malloc( sizeof(struct test_pal_logical_processor), LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lp->logical_processor_number = logical_processor_number;
+ lp->windows_logical_processor_group_number = 0;
+
+ LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( lp->lasue, lp );
+ lfds700_list_asu_insert_at_start( lasus, &lp->lasue, &ps );
+ }
+
+ free( slpi );
+
+ return;
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __linux__ )
+
+ /* TRD : __linux__ indicates Linux
+ __STDC__ indicates Standard Library
+ __STDC_HOSTED__ indicates Standard Library hosted implementation
+ - fopen requires a Standard Library hosted environment
+ - setbuf requires a Standard Library hosted environment
+ - fgets requires a Standard Library hosted environment
+ - sscanf requires a Standard Library hosted environment
+ - fclose requires a Standard Library hosted environment
+ */
+
+ #ifdef TEST_PAL_GET_LOGICAL_CORE_IDS
+ #error More than one porting abstraction layer matches current platform in test_porting_abstraction_layer_get_logical_core_ids.c
+ #endif
+
+ #define TEST_PAL_GET_LOGICAL_CORE_IDS
+
+ void test_pal_get_logical_core_ids( struct lfds700_list_asu_state *lasus )
+ {
+ char
+ diskbuffer[BUFSIZ],
+ string[1024];
+
+ FILE
+ *diskfile;
+
+ int long long unsigned
+ logical_processor_number;
+
+ struct lfds700_misc_prng_state
+ ps;
+
+ struct test_pal_logical_processor
+ *lp;
+
+ assert( lasus != NULL );
+
+ lfds700_misc_prng_init( &ps );
+
+ lfds700_list_asu_init_valid_on_current_logical_core( lasus, NULL, NULL );
+
+ diskfile = fopen( "/proc/cpuinfo", "r" );
+
+ if( diskfile != NULL )
+ {
+ setbuf( diskfile, diskbuffer );
+
+ while( NULL != fgets(string, 1024, diskfile) )
+ if( 1 == sscanf(string, "processor : %llu", &logical_processor_number) )
+ {
+ lp = util_aligned_malloc( sizeof(struct test_pal_logical_processor), LFDS700_PAL_ATOMIC_ISOLATION_IN_BYTES );
+
+ lp->logical_processor_number = (lfds700_pal_uint_t) logical_processor_number;
+ lp->windows_logical_processor_group_number = 0;
+
+ LFDS700_LIST_ASU_SET_VALUE_IN_ELEMENT( lp->lasue, lp );
+ lfds700_list_asu_insert_at_start( lasus, &lp->lasue, &ps );
+ }
+
+ fclose( diskfile );
+ }
+
+ return;
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( !defined TEST_PAL_GET_LOGICAL_CORE_IDS )
+
+ #error test_pal_get_logical_core_ids() not implemented for this platform.
+
+#endif
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_operating_system.h b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_operating_system.h
new file mode 100644
index 0000000000..1c0ab03eee
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_operating_system.h
@@ -0,0 +1,82 @@
+/****************************************************************************/
+#if( defined _MSC_VER )
+ /* TRD : MSVC compiler
+
+ an unfortunately necessary hack for MSVC
+ MSVC only defines __STDC__ if /Za is given, where /Za turns off MSVC C extensions -
+ which prevents Windows header files from compiling.
+ */
+
+ #define __STDC__ 1
+ #define __STDC_HOSTED__ 1
+#endif
+
+#if( defined __linux__ )
+ #define _GNU_SOURCE
+ #include
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined _MSC_VER && _MSC_VER >= 1310 && NTDDI_VERSION >= NTDDI_WINXP && defined _WIN32 )
+
+ #ifdef TEST_PAL_PORTING_ABSTRACTION_LAYER
+ #error More than one porting abstraction layer matches current platform.
+ #endif
+
+ #define TEST_PAL_PORTING_ABSTRACTION_LAYER
+
+ #define TEST_PAL_OS_STRING "Windows"
+
+ #include
+
+ typedef HANDLE test_pal_thread_state_t;
+ typedef DWORD test_pal_thread_return_t;
+
+ #define TEST_PAL_CALLING_CONVENTION WINAPI
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __GNUC__ && defined __linux__ && _POSIX_THREADS > 0 )
+
+ #ifdef TEST_PAL_PORTING_ABSTRACTION_LAYER
+ #error More than one porting abstraction layer matches current platform.
+ #endif
+
+ #define TEST_PAL_PORTING_ABSTRACTION_LAYER
+
+ #define TEST_PAL_OS_STRING "Linux"
+
+ #define _GNU_SOURCE
+
+ #include
+ #include
+ #include
+ #include
+
+ typedef pthread_t test_pal_thread_state_t;
+ typedef void * test_pal_thread_return_t;
+
+ #define TEST_PAL_CALLING_CONVENTION
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( !defined TEST_PAL_PORTING_ABSTRACTION_LAYER )
+
+ #error No matching porting abstraction layer in test_porting_abstraction_layer_operating_system.h
+
+#endif
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_thread_start.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_thread_start.c
new file mode 100644
index 0000000000..83a09814aa
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_thread_start.c
@@ -0,0 +1,336 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#if( defined _WIN32 && !defined _KERNEL_MODE && NTDDI_VERSION >= NTDDI_WIN7 )
+
+ /* TRD : _WIN32 indicates 32-bit or 64-bit Windows
+ !_KERNEL_MODE indicates Windows user-mode
+ NTDDI_VERSION indicates Windows version
+ - GetCurrentProcess requires XP
+ - InitializeProcThreadAttributeList requires Windows 7
+ - CreateRemoteThreadEx requires Windows 7
+ */
+
+ #ifdef TEST_PAL_THREAD_START
+ #error More than one porting abstraction layer matches the current platform in test_porting_abstraction_layer_thread_start.c
+ #endif
+
+ #define TEST_PAL_THREAD_START
+
+ int test_pal_thread_start( test_pal_thread_state_t *thread_state,
+ struct test_pal_logical_processor *lp,
+ test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state),
+ void *thread_user_state )
+ {
+ BOOL
+ brv;
+
+ DWORD
+ thread_id;
+
+ GROUP_AFFINITY
+ ga;
+
+ int
+ rv = 0;
+
+ LPPROC_THREAD_ATTRIBUTE_LIST
+ attribute_list;
+
+ SIZE_T
+ attribute_list_length;
+
+ assert( thread_state != NULL );
+ assert( lp != NULL );
+ assert( thread_function != NULL );
+ // TRD : thread_user_state can be NULL
+
+ /* TRD : here we're using CreateRemoteThreadEx() to start a thread in our own process
+ we do this because as a function, it allows us to specify processor and processor group affinity in the create call
+ */
+
+ brv = InitializeProcThreadAttributeList( NULL, 1, 0, &attribute_list_length );
+ attribute_list = malloc( attribute_list_length );
+ brv = InitializeProcThreadAttributeList( attribute_list, 1, 0, &attribute_list_length );
+
+ ga.Mask = ( (KAFFINITY) 1 << lp->logical_processor_number );
+ ga.Group = (WORD) lp->windows_logical_processor_group_number;
+ memset( ga.Reserved, 0, sizeof(WORD) * 3 );
+
+ brv = UpdateProcThreadAttribute( attribute_list, 0, PROC_THREAD_ATTRIBUTE_GROUP_AFFINITY, &ga, sizeof(GROUP_AFFINITY), NULL, NULL );
+ *thread_state = CreateRemoteThreadEx( GetCurrentProcess(), NULL, 0, thread_function, thread_user_state, NO_FLAGS, attribute_list, &thread_id );
+
+ DeleteProcThreadAttributeList( attribute_list );
+ free( attribute_list );
+
+ if( *thread_state != NULL )
+ rv = 1;
+
+ return( rv );
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined _WIN32 && !defined _KERNEL_MODE && NTDDI_VERSION >= NTDDI_WINXP && NTDDI_VERSION < NTDDI_WIN7 )
+
+ /* TRD : _WIN32 indicates 64-bit or 32-bit Windows
+ NTDDI_VERSION indicates Windows version
+ - CreateThread requires XP
+ - SetThreadAffinityMask requires XP
+ - ResumeThread requires XP
+ */
+
+ #ifdef TEST_PAL_THREAD_START
+ #error More than one porting abstraction layer matches the current platform in test_porting_abstraction_layer_thread_start.c
+ #endif
+
+ #define TEST_PAL_THREAD_START
+
+ int test_pal_thread_start( test_pal_thread_state_t *thread_state,
+ struct test_pal_logical_processor *lp,
+ test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state),
+ void *thread_user_state )
+ {
+ int
+ rv = 0;
+
+ DWORD
+ thread_id;
+
+ DWORD_PTR
+ affinity_mask,
+ result;
+
+ assert( thread_state != NULL );
+ assert( lp != NULL );
+ assert( thread_function != NULL );
+ // TRD : thread_user_state can be NULL
+
+ /* TRD : Vista and earlier do not support processor groups
+ as such, there is a single implicit processor group
+ also, there's no support for actually starting a thread in its correct NUMA node / logical processor
+ so we make the best of it; we start suspended, set the affinity, and then resume
+ the thread itself internally is expected to be making allocs from the correct NUMA node
+ */
+
+ *thread_state = CreateThread( NULL, 0, thread_function, thread_user_state, CREATE_SUSPENDED, &thread_id );
+
+ affinity_mask = (DWORD_PTR) (1 << lp->logical_processor_number);
+
+ SetThreadAffinityMask( *thread_state, affinity_mask );
+
+ ResumeThread( *thread_state );
+
+ if( *thread_state != NULL )
+ rv = 1;
+
+ return( rv );
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( defined __linux__ && _POSIX_THREADS > 0 )
+
+ /* TRD : __linux__ indicates Linux
+ - gettid requires Linux
+ - sched_setaffinity requires Linux
+ _POSIX_THREADS indicates POSIX threads
+ - pthread_create requires POSIX
+ */
+
+ #ifdef TEST_PAL_THREAD_START
+ #error More than one porting abstraction layer matches the current platform in test_porting_abstraction_layer_thread_start.c
+ #endif
+
+ #define TEST_PAL_THREAD_START
+
+ /***** structs *****/
+ struct test_pal_internal_thread_state
+ {
+ struct test_pal_logical_processor
+ lp;
+
+ test_pal_thread_return_t
+ (TEST_PAL_CALLING_CONVENTION *thread_function)( void *thread_user_state );
+
+ void
+ *thread_user_state;
+ };
+
+ /***** prototypes *****/
+ test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION test_pal_internal_thread_function( void *thread_user_state );
+
+ /****************************************************************************/
+ int test_pal_thread_start( test_pal_thread_state_t *thread_state,
+ struct test_pal_logical_processor *lp,
+ test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state),
+ void *thread_user_state )
+ {
+ int
+ rv;
+
+ struct test_pal_internal_thread_state
+ *its;
+
+ /* TRD : this implementation works on Linux only as it uses sched_setaffinity(), which is Linux specific
+ although I cannot currently test, I believe this function also works on Android
+
+ this implementation exists because the pthreads function for setting thread affinity,
+ pthread_attr_setaffinity_np(), works on Linux, but not Android
+ */
+
+ assert( thread_state != NULL );
+ assert( lp != NULL );
+ assert( thread_function != NULL );
+ // TRD : thread_user_state can be NULL
+
+ its = malloc( sizeof(struct test_pal_internal_thread_state) );
+
+ its->lp = *lp;
+ its->thread_function = thread_function;
+ its->thread_user_state = thread_user_state;
+
+ rv = pthread_create( thread_state, NULL, test_pal_internal_thread_function, its );
+
+ if( rv == 0 )
+ rv = 1;
+
+ return( rv );
+ }
+
+ /****************************************************************************/
+ test_pal_thread_return_t TEST_PAL_CALLING_CONVENTION test_pal_internal_thread_function( void *thread_user_state )
+ {
+ cpu_set_t
+ cpuset;
+
+ pid_t
+ tid;
+
+ struct test_pal_internal_thread_state
+ *its;
+
+ test_pal_thread_return_t
+ rv;
+
+ assert( thread_user_state != NULL );
+
+ /* TRD : the APIs under Linux/POSIX for setting thread affinity are in a mess
+ pthreads offers pthread_attr_setaffinity_np(), which glibc supports,
+ but which is not supported by Android
+ Linux offers sched_setaffinity(), but this needs a *thread pid*,
+ and the only API to get a thread pid is gettid(), which works for
+ and only for *the calling thread*
+
+ so we come to this - a wrapper thread function, which is the function used
+ when starting a thread; this calls gettid() and then sched_setaffinity(),
+ and then calls into the actual thread function
+
+ generally shaking my head in disbelief at this point
+ */
+
+ assert( thread_user_state != NULL );
+
+ its = (struct test_pal_internal_thread_state *) thread_user_state;
+
+ CPU_ZERO( &cpuset );
+ CPU_SET( its->lp.logical_processor_number, &cpuset );
+
+ tid = syscall( SYS_gettid );
+
+ sched_setaffinity( tid, sizeof(cpu_set_t), &cpuset );
+
+ rv = its->thread_function( its->thread_user_state );
+
+ free( its );
+
+ return( rv );
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( !defined __linux__ && _POSIX_THREADS > 0 )
+
+ /* TRD : !__linux__ indicates not Linux
+ _POSIX_THREADS indicates POSIX threads
+ - pthread_attr_init requires POSIX
+ - pthread_attr_setaffinity_np requires POSIX
+ - pthread_create requires POSIX
+ - pthread_attr_destroy requires POSIX
+ */
+
+ #ifdef TEST_PAL_THREAD_START
+ #error More than one porting abstraction layer matches the current platform in test_porting_abstraction_layer_thread_start.c
+ #endif
+
+ #define TEST_PAL_THREAD_START
+
+ int test_pal_thread_start( test_pal_thread_state_t *thread_state,
+ struct test_pal_logical_processor *lp,
+ test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state),
+ void *thread_user_state )
+ {
+ int
+ rv = 0,
+ rv_create;
+
+ cpu_set_t
+ cpuset;
+
+ pthread_attr_t
+ attr;
+
+ assert( thread_state != NULL );
+ assert( lp != NULL );
+ assert( thread_function != NULL );
+ // TRD : thread_user_state can be NULL
+
+ pthread_attr_init( &attr );
+
+ CPU_ZERO( &cpuset );
+ CPU_SET( lp->logical_processor_number, &cpuset );
+ pthread_attr_setaffinity_np( &attr, sizeof(cpuset), &cpuset );
+
+ rv_create = pthread_create( thread_state, &attr, thread_function, thread_user_state );
+
+ if( rv_create == 0 )
+ rv = 1;
+
+ pthread_attr_destroy( &attr );
+
+ return( rv );
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( !defined TEST_PAL_THREAD_START )
+
+ #error test_pal_thread_start() not implemented for this platform.
+
+#endif
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_thread_wait.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_thread_wait.c
new file mode 100644
index 0000000000..bd4a8c01f7
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/test_porting_abstraction_layer_thread_wait.c
@@ -0,0 +1,69 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+#if( defined _WIN32 && NTDDI_VERSION >= NTDDI_WINXP )
+
+ /* TRD : _WIN32 indicates 32-bit or 64-bit Windows
+ NTDDI_VERSION indicates Windows version
+ - WaitForSingleObject requires XP
+ */
+
+ #ifdef TEST_PAL_THREAD_WAIT
+ #error More than one porting abstraction layer matches current platform in test_porting_abstraction_layer_thread_wait.c
+ #endif
+
+ #define TEST_PAL_THREAD_WAIT
+
+ void test_pal_thread_wait( test_pal_thread_state_t thread_state )
+ {
+ WaitForSingleObject( thread_state, INFINITE );
+
+ return;
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( _POSIX_THREADS > 0 )
+
+ /* TRD : POSIX threads
+
+ _POSIX_THREADS indicates POSIX threads
+ - pthread_join requires POSIX
+ */
+
+ #ifdef TEST_PAL_THREAD_WAIT
+ #error More than one porting abstraction layer matches current platform in test_porting_abstraction_layer_thread_wait.c
+ #endif
+
+ #define TEST_PAL_THREAD_WAIT
+
+ void test_pal_thread_wait( test_pal_thread_state_t thread_state )
+ {
+ pthread_join( thread_state, NULL );
+
+ return;
+ }
+
+#endif
+
+
+
+
+
+/****************************************************************************/
+#if( !defined TEST_PAL_THREAD_WAIT )
+
+ #error test_pal_thread_wait() not implemented for this platform.
+
+#endif
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_cmdline.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_cmdline.c
new file mode 100644
index 0000000000..9173d607c9
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_cmdline.c
@@ -0,0 +1,184 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+void util_cmdline_init( struct util_cmdline_state *cs )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ assert( cs != NULL );
+
+ for( loop = 0 ; loop < NUMBER_OF_LOWERCASE_LETTERS_IN_LATIN_ALPHABET ; loop++ )
+ {
+ cs->args[loop].arg_type = LIBCOMMON_CMDLINE_ARG_TYPE_UNSET;
+ cs->args[loop].processed_flag = LOWERED;
+ }
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+#pragma warning( disable : 4100 )
+
+void util_cmdline_cleanup( struct util_cmdline_state *cs )
+{
+ assert( cs != NULL );
+
+ return;
+}
+
+#pragma warning( default : 4100 )
+
+
+
+
+
+/****************************************************************************/
+void util_cmdline_add_arg( struct util_cmdline_state *cs, char arg_letter, enum util_cmdline_arg_type arg_type )
+{
+ lfds700_pal_uint_t
+ index;
+
+ assert( cs != NULL );
+ assert( arg_letter >= 'a' and arg_letter <= 'z' );
+ // TRD : arg_type can be any value in its range
+
+ index = arg_letter - 'a';
+
+ cs->args[index].arg_type = arg_type;
+
+ if( arg_type == LIBCOMMON_CMDLINE_ARG_TYPE_FLAG )
+ cs->args[index].arg_data.flag.flag = LOWERED;
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+int util_cmdline_process_args( struct util_cmdline_state *cs, int argc, char **argv )
+{
+ char
+ *arg;
+
+ int
+ arg_letter,
+ cc,
+ loop,
+ rv = 1;
+
+ lfds700_pal_uint_t
+ index;
+
+ assert( cs != NULL );
+ assert( argc >= 1 );
+ assert( argv != NULL );
+
+ for( loop = 1 ; loop < argc ; loop++ )
+ {
+ arg = *(argv+loop);
+
+ switch( *arg )
+ {
+ case '-':
+ arg_letter = tolower( *(arg+1) );
+
+ if( arg_letter >= 'a' and arg_letter <= 'z' )
+ {
+ index = arg_letter - 'a';
+
+ switch( cs->args[index].arg_type )
+ {
+ case LIBCOMMON_CMDLINE_ARG_TYPE_INTEGER_RANGE:
+ if( loop+1 >= argc )
+ rv = 0;
+
+ if( loop+1 < argc )
+ {
+ cc = sscanf( *(argv+loop+1), "%llu-%llu", &cs->args[index].arg_data.integer_range.integer_start, &cs->args[index].arg_data.integer_range.integer_end );
+
+ if( cc != 2 )
+ rv = 0;
+
+ if( cc == 2 )
+ {
+ cs->args[index].processed_flag = RAISED;
+ loop++;
+ }
+ }
+ break;
+
+ case LIBCOMMON_CMDLINE_ARG_TYPE_INTEGER:
+ if( loop+1 >= argc )
+ rv = 0;
+
+ if( loop+1 < argc )
+ {
+ cc = sscanf( *(argv+loop+1), "%llu", &cs->args[index].arg_data.integer.integer );
+
+ if( cc != 1 )
+ rv = 0;
+
+ if( cc == 1 )
+ {
+ cs->args[index].processed_flag = RAISED;
+ loop++;
+ }
+ }
+ break;
+
+ case LIBCOMMON_CMDLINE_ARG_TYPE_FLAG:
+ cs->args[index].arg_data.flag.flag = RAISED;
+ cs->args[index].processed_flag = RAISED;
+ break;
+
+ case LIBCOMMON_CMDLINE_ARG_TYPE_UNSET:
+ break;
+ }
+ }
+ break;
+
+ default:
+ rv = 0;
+ break;
+ }
+ }
+
+ return( rv );
+}
+
+
+
+
+
+/****************************************************************************/
+void util_cmdline_get_arg_data( struct util_cmdline_state *cs, char arg_letter, union util_cmdline_arg_data **arg_data )
+{
+ lfds700_pal_uint_t
+ index;
+
+ assert( cs != NULL );
+ assert( arg_letter >= 'a' and arg_letter <= 'z' );
+ assert( arg_data != NULL );
+
+ index = arg_letter - 'a';
+
+ if( cs->args[index].processed_flag == RAISED )
+ *arg_data = &cs->args[index].arg_data;
+ else
+ *arg_data = NULL;
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_cmdline.h b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_cmdline.h
new file mode 100644
index 0000000000..a19b073499
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_cmdline.h
@@ -0,0 +1,69 @@
+/***** defines *****/
+#define NUMBER_OF_LOWERCASE_LETTERS_IN_LATIN_ALPHABET 26
+
+/***** enums *****/
+enum util_cmdline_arg_type
+{
+ LIBCOMMON_CMDLINE_ARG_TYPE_INTEGER_RANGE,
+ LIBCOMMON_CMDLINE_ARG_TYPE_INTEGER,
+ LIBCOMMON_CMDLINE_ARG_TYPE_FLAG,
+ LIBCOMMON_CMDLINE_ARG_TYPE_UNSET
+};
+
+/***** structs *****/
+struct util_cmdline_arg_integer_range
+{
+ int long long unsigned
+ integer_start,
+ integer_end;
+};
+
+struct util_cmdline_arg_integer
+{
+ int long long unsigned
+ integer;
+};
+
+struct util_cmdline_arg_flag
+{
+ enum flag
+ flag;
+};
+
+union util_cmdline_arg_data
+{
+ struct util_cmdline_arg_integer_range
+ integer_range;
+
+ struct util_cmdline_arg_integer
+ integer;
+
+ struct util_cmdline_arg_flag
+ flag;
+};
+
+struct util_cmdline_arg_letter_and_data
+{
+ enum util_cmdline_arg_type
+ arg_type;
+
+ enum flag
+ processed_flag;
+
+ union util_cmdline_arg_data
+ arg_data;
+};
+
+struct util_cmdline_state
+{
+ struct util_cmdline_arg_letter_and_data
+ args[NUMBER_OF_LOWERCASE_LETTERS_IN_LATIN_ALPHABET];
+};
+
+/***** public protoypes *****/
+void util_cmdline_init( struct util_cmdline_state *cs );
+void util_cmdline_cleanup( struct util_cmdline_state *cs );
+void util_cmdline_add_arg( struct util_cmdline_state *cs, char arg_letter, enum util_cmdline_arg_type arg_type );
+int util_cmdline_process_args( struct util_cmdline_state *cs, int argc, char **argv );
+void util_cmdline_get_arg_data( struct util_cmdline_state *cs, char arg_letter, union util_cmdline_arg_data **arg_data );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_memory_helpers.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_memory_helpers.c
new file mode 100644
index 0000000000..3d4c0e79f4
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_memory_helpers.c
@@ -0,0 +1,75 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+void *util_aligned_malloc( lfds700_pal_uint_t size, lfds700_pal_uint_t align_in_bytes )
+{
+ lfds700_pal_uint_t
+ offset;
+
+ void
+ *memory,
+ *original_memory;
+
+ // TRD : size can be any value in its range
+ // TRD : align_in_bytes can be any value in its range
+
+ /* TRD : helper function to provide aligned allocations
+ no porting required
+ */
+
+ original_memory = memory = util_malloc_wrapper( size + sizeof(void *) + align_in_bytes );
+
+ if( memory != NULL )
+ {
+ memory = (void **) memory + 1;
+ offset = align_in_bytes - (lfds700_pal_uint_t) memory % align_in_bytes;
+ memory = (char unsigned *) memory + offset;
+ *( (void **) memory - 1 ) = original_memory;
+ }
+
+ return( memory );
+}
+
+
+
+
+
+/****************************************************************************/
+void util_aligned_free( void *memory )
+{
+ assert( memory != NULL );
+
+ // TRD : the "void *" stored above memory points to the root of the allocation
+ free( *( (void **) memory - 1 ) );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void *util_malloc_wrapper( lfds700_pal_uint_t size )
+{
+ void
+ *memory;
+
+ // TRD : size can be any value in its range
+
+ memory = malloc( size );
+
+ if( memory == NULL )
+ {
+ puts( "malloc() failed, exiting." );
+ exit( EXIT_FAILURE );
+ }
+
+ return( memory );
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_memory_helpers.h b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_memory_helpers.h
new file mode 100644
index 0000000000..8341a1f2e3
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_memory_helpers.h
@@ -0,0 +1,5 @@
+/***** public prototypes *****/
+void *util_aligned_malloc( lfds700_pal_uint_t size, lfds700_pal_uint_t align_in_bytes );
+void util_aligned_free( void *memory );
+void *util_malloc_wrapper( lfds700_pal_uint_t size );
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_thread_starter.c b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_thread_starter.c
new file mode 100644
index 0000000000..c008fa2c5d
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_thread_starter.c
@@ -0,0 +1,151 @@
+/***** includes *****/
+#include "internal.h"
+
+
+
+
+
+/****************************************************************************/
+void util_thread_starter_new( struct util_thread_starter_state **tts, lfds700_pal_uint_t number_threads )
+{
+ lfds700_pal_uint_t
+ loop;
+
+ assert( tts != NULL );
+ // TRD : number_threads cam be any value in its range
+
+ *tts = util_malloc_wrapper( sizeof(struct util_thread_starter_state) );
+
+ (*tts)->tsts = util_malloc_wrapper( sizeof(struct util_thread_starter_thread_state) * number_threads );
+ (*tts)->thread_start_flag = LOWERED;
+ (*tts)->number_thread_states = number_threads;
+
+ for( loop = 0 ; loop < number_threads ; loop++ )
+ {
+ ((*tts)->tsts+loop)->thread_ready_flag = LOWERED;
+ ((*tts)->tsts+loop)->thread_start_flag = &(*tts)->thread_start_flag;
+ }
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void util_thread_starter_start( struct util_thread_starter_state *tts,
+ test_pal_thread_state_t *thread_state,
+ lfds700_pal_uint_t thread_number,
+ struct test_pal_logical_processor *lp,
+ test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)( void *thread_user_state ),
+ void *thread_user_state )
+{
+ assert( tts != NULL );
+ assert( thread_state != NULL );
+ assert( lp != NULL );
+ assert( thread_function != NULL );
+ // TRD : thread_user_state can be NULL
+
+ (tts->tsts+thread_number)->thread_user_state = thread_user_state;
+
+ util_thread_start_wrapper( thread_state, lp, thread_function, tts->tsts+thread_number );
+
+ // TRD : wait for the thread to indicate it is ready and waiting
+ while( (tts->tsts+thread_number)->thread_ready_flag == LOWERED );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void util_thread_starter_ready_and_wait( struct util_thread_starter_thread_state *tsts )
+{
+ assert( tsts != NULL );
+
+ tsts->thread_ready_flag = RAISED;
+
+ LFDS700_MISC_BARRIER_FULL;
+
+ // TRD : threads here are all looping, so we don't need to force a store
+
+ while( *tsts->thread_start_flag == LOWERED )
+ LFDS700_MISC_BARRIER_LOAD;
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void util_thread_starter_run( struct util_thread_starter_state *tts )
+{
+ assert( tts != NULL );
+
+ /* TRD : all threads at this point are ready to go
+ as we wait for their ready flag immediately after their spawn
+ */
+
+ tts->thread_start_flag = RAISED;
+
+ LFDS700_MISC_BARRIER_STORE;
+
+ lfds700_misc_force_store();
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void util_thread_starter_delete( struct util_thread_starter_state *tts )
+{
+ assert( tts != NULL );
+
+ free( tts->tsts );
+
+ free( tts );
+
+ return;
+}
+
+
+
+
+
+/****************************************************************************/
+void util_thread_start_wrapper( test_pal_thread_state_t *thread_state,
+ struct test_pal_logical_processor *lp,
+ test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state),
+ void *thread_user_state )
+{
+ int
+ rv;
+
+ assert( thread_state != NULL );
+ assert( lp != NULL );
+ assert( thread_function != NULL );
+ // TRD : thread_user_state can be NULL
+
+ rv = test_pal_thread_start( thread_state, lp, thread_function, thread_user_state );
+
+ if( rv == 0 )
+ {
+ puts( "test_pal_thread_start() failed." );
+ exit( EXIT_FAILURE );
+ }
+
+ return;
+}
+
diff --git a/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_thread_starter.h b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_thread_starter.h
new file mode 100644
index 0000000000..5587edf1c0
--- /dev/null
+++ b/openair2/UTIL/LFDS/liblfds7.0.0/test/src/util_thread_starter.h
@@ -0,0 +1,41 @@
+/***** structs *****/
+struct util_thread_starter_thread_state
+{
+ // TRD : must be volatile or the compiler optimizes it away into a single load
+ enum flag volatile
+ thread_ready_flag,
+ *thread_start_flag;
+
+ void
+ *thread_user_state;
+};
+
+struct util_thread_starter_state
+{
+ enum flag volatile
+ thread_start_flag;
+
+ lfds700_pal_uint_t
+ number_thread_states;
+
+ struct util_thread_starter_thread_state
+ *tsts;
+};
+
+/***** prototypes *****/
+void util_thread_starter_new( struct util_thread_starter_state **tts, lfds700_pal_uint_t number_threads );
+void util_thread_starter_start( struct util_thread_starter_state *tts,
+ test_pal_thread_state_t *thread_state,
+ lfds700_pal_uint_t thread_number,
+ struct test_pal_logical_processor *lp,
+ test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)( void *thread_user_state ),
+ void *thread_user_state );
+void util_thread_starter_ready_and_wait( struct util_thread_starter_thread_state *tsts );
+void util_thread_starter_run( struct util_thread_starter_state *tts );
+void util_thread_starter_delete( struct util_thread_starter_state *tts );
+
+void util_thread_start_wrapper( test_pal_thread_state_t *thread_state,
+ struct test_pal_logical_processor *lp,
+ test_pal_thread_return_t (TEST_PAL_CALLING_CONVENTION *thread_function)(void *thread_user_state),
+ void *thread_user_state );
+