Added proto_agent files for a simple message exchange in oaisim

This commit is contained in:
Nikos Makris
2016-09-05 14:09:22 +03:00
parent e508be85d4
commit bc5e30318f
187 changed files with 24588 additions and 0 deletions
+499
View File
@@ -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 <http://www.gnu.org/licenses/>.
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;
}
+51
View File
@@ -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 <http://www.gnu.org/licenses/>.
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
@@ -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 <http://www.gnu.org/licenses/>.
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);
}
@@ -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 <http://www.gnu.org/licenses/>.
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_*/
@@ -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 <http://www.gnu.org/licenses/>.
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<stdio.h>
#include <dlfcn.h>
#include <time.h>
#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;
}
*/
@@ -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 <http://www.gnu.org/licenses/>.
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 <time.h>
#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
@@ -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 <http://www.gnu.org/licenses/>.
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 <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#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
@@ -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 <http://www.gnu.org/licenses/>.
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));
}
@@ -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 <http://www.gnu.org/licenses/>.
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);
}
@@ -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 <http://www.gnu.org/licenses/>.
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_*/
@@ -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 <assert.h> ends up being included
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1,705 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug DLL|Win32">
<Configuration>Debug DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug DLL|x64">
<Configuration>Debug DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug LIB|Win32">
<Configuration>Debug LIB</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug LIB|x64">
<Configuration>Debug LIB</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release DLL|Win32">
<Configuration>Release DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release DLL|x64">
<Configuration>Release DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release LIB|Win32">
<Configuration>Release LIB</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release LIB|x64">
<Configuration>Release LIB</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v110</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug LIB|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release LIB|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">
<LinkIncremental>
</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'">
<LinkIncremental>
</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">
<LinkIncremental>
</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'">
<LinkIncremental>
</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<IntrinsicFunctions>true</IntrinsicFunctions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<SmallerTypeCheck>true</SmallerTypeCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>true</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<BrowseInformation>true</BrowseInformation>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<SDLCheck>true</SDLCheck>
<MinimalRebuild>false</MinimalRebuild>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
</Lib>
<Lib>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<IntrinsicFunctions>true</IntrinsicFunctions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<SmallerTypeCheck>true</SmallerTypeCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>true</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<BrowseInformation>true</BrowseInformation>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<SDLCheck>true</SDLCheck>
<MinimalRebuild>false</MinimalRebuild>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>kernel32.lib;msvcrtd.lib</AdditionalDependencies>
<LinkStatus>
</LinkStatus>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>liblfds700.def</ModuleDefinitionFile>
<MapExports>true</MapExports>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
<GenerateMapFile>true</GenerateMapFile>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
</Lib>
<Lib>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<IntrinsicFunctions>true</IntrinsicFunctions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<SmallerTypeCheck>true</SmallerTypeCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>true</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<BrowseInformation>true</BrowseInformation>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<SDLCheck>true</SDLCheck>
<MinimalRebuild>false</MinimalRebuild>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<OmitFramePointers>false</OmitFramePointers>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
</Lib>
<Lib>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<IntrinsicFunctions>true</IntrinsicFunctions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<SmallerTypeCheck>true</SmallerTypeCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>true</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<BrowseInformation>true</BrowseInformation>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<SDLCheck>true</SDLCheck>
<MinimalRebuild>false</MinimalRebuild>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<OmitFramePointers>false</OmitFramePointers>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>liblfds700.def</ModuleDefinitionFile>
<MapExports>true</MapExports>
<OptimizeReferences>false</OptimizeReferences>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
<AdditionalDependencies>kernel32.lib;msvcrtd.lib</AdditionalDependencies>
<GenerateMapFile>true</GenerateMapFile>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
</Lib>
<Lib>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>
</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<OmitFramePointers>true</OmitFramePointers>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>
</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<OmitFramePointers>true</OmitFramePointers>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;msvcrt.lib</AdditionalDependencies>
<LinkStatus>
</LinkStatus>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>liblfds700.def</ModuleDefinitionFile>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>
</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<OmitFramePointers>true</OmitFramePointers>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>
</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<OmitFramePointers>true</OmitFramePointers>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>liblfds700.def</ModuleDefinitionFile>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
<AdditionalDependencies>kernel32.lib;msvcrt.lib</AdditionalDependencies>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\inc\liblfds700.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_btree_addonly_unbalanced.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_freelist.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_hash_addonly.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_ordered_singlylinked.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_singlylinked_unordered.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_misc.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_compiler.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_operating_system.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_processor.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue_bounded_singleconsumer_singleproducer.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_ringbuffer.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_stack.h" />
<ClInclude Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_internal.h" />
<ClInclude Include="..\..\src\lfds700_freelist\lfds700_freelist_internal.h" />
<ClInclude Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_internal.h" />
<ClInclude Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_internal.h" />
<ClInclude Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_internal.h" />
<ClInclude Include="..\..\src\lfds700_misc\lfds700_misc_internal.h" />
<ClInclude Include="..\..\src\lfds700_queue\lfds700_queue_internal.h" />
<ClInclude Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_internal.h" />
<ClInclude Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_internal.h" />
<ClInclude Include="..\..\src\lfds700_stack\lfds700_stack_internal.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_get.c" />
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_init.c" />
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_insert.c" />
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_query.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_init.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_pop.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_push.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_query.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_get.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_init.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_insert.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_iterate.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_query.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_get.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_init.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_insert.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_query.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_get.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_init.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_insert.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_query.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_globals.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_init.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_prng.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_query.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_dequeue.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_enqueue.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_init.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_query.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_init.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_query.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_init.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_query.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_read.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_write.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_init.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_pop.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_push.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_query.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,279 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="Header Files\liblfds700">
<UniqueIdentifier>{258be429-7dac-4999-b995-753aa2f0c505}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_freelist">
<UniqueIdentifier>{469abf8e-47d8-4678-bd66-7c7e65c5f52e}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_ringbuffer">
<UniqueIdentifier>{62ee141b-2acb-4555-b016-7be20a57f2bf}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_stack">
<UniqueIdentifier>{19c73b0f-25e0-4166-9093-427f1dfb4f70}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_queue">
<UniqueIdentifier>{00eb30fe-e638-4c2b-8ca1-1f09c4a0ed45}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_misc">
<UniqueIdentifier>{400ae4e9-2281-4549-b918-59d1a27a2d07}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_btree_addonly_unbalanced">
<UniqueIdentifier>{0b1fafc3-817b-4c18-8eb1-121884e3a29b}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_hash_addonly">
<UniqueIdentifier>{bcbadc74-1748-4696-aad7-7fdbe5614624}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_list_addonly_ordered_singlylinked">
<UniqueIdentifier>{c45194af-7b41-4c28-bc0e-1095ec347664}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_queue_bounded_singleconsumer_singleproducer">
<UniqueIdentifier>{6250c4d5-ac8e-4c28-93de-0954c5bed1cb}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_list_addonly_singlylinked_unordered">
<UniqueIdentifier>{3ac93721-1d81-49e4-9581-dbc12ace5c0c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\inc\liblfds700.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_freelist\lfds700_freelist_internal.h">
<Filter>Source Files\lfds700_freelist</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_queue\lfds700_queue_internal.h">
<Filter>Source Files\lfds700_queue</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_stack\lfds700_stack_internal.h">
<Filter>Source Files\lfds700_stack</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_btree_addonly_unbalanced.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_freelist.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_hash_addonly.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_ordered_singlylinked.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_singlylinked_unordered.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_misc.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_compiler.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_operating_system.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_processor.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue_bounded_singleconsumer_singleproducer.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_ringbuffer.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_stack.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_internal.h">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_misc\lfds700_misc_internal.h">
<Filter>Source Files\lfds700_misc</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_internal.h">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_internal.h">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_internal.h">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_internal.h">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_internal.h">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_cleanup.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_init.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_pop.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_push.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_query.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_cleanup.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_dequeue.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_enqueue.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_init.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_query.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_cleanup.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_init.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_pop.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_push.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_query.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_cleanup.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_get.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_init.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_insert.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_iterate.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_query.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_cleanup.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_globals.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_init.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_prng.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_query.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_cleanup.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_get.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_init.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_insert.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_query.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_cleanup.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_init.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_query.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_read.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_write.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_init.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_query.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_cleanup.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_get.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_init.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_insert.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_query.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_cleanup.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_get.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_init.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_insert.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_query.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
@@ -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
@@ -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
@@ -0,0 +1,733 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug DLL|Win32">
<Configuration>Debug DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug DLL|x64">
<Configuration>Debug DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug LIB|Win32">
<Configuration>Debug LIB</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug LIB|x64">
<Configuration>Debug LIB</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release DLL|Win32">
<Configuration>Release DLL</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release DLL|x64">
<Configuration>Release DLL</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release LIB|Win32">
<Configuration>Release LIB</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release LIB|x64">
<Configuration>Release LIB</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{1E5D7D09-94F2-455D-AE5E-6C7F4C96BCE0}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>WindowsKernelModeDriver8.0</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug LIB|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release LIB|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
<IncludePath>$(ProjectDir);$(IncludePath);</IncludePath>
<LibraryPath>$(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">
<LinkIncremental>
</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
<IncludePath>$(ProjectDir);$(IncludePath);</IncludePath>
<LibraryPath>$(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
<IncludePath>$(ProjectDir);$(IncludePath);</IncludePath>
<LibraryPath>$(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'">
<LinkIncremental>
</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
<IncludePath>$(ProjectDir);$(IncludePath);</IncludePath>
<LibraryPath>$(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|Win32'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
<IncludePath>$(ProjectDir);$(IncludePath);</IncludePath>
<LibraryPath>$(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">
<LinkIncremental>
</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
<IncludePath>$(ProjectDir);$(IncludePath);</IncludePath>
<LibraryPath>$(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|x64'">
<LinkIncremental>true</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
<IncludePath>$(ProjectDir);$(IncludePath);</IncludePath>
<LibraryPath>$(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);</LibraryPath>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'">
<LinkIncremental>
</LinkIncremental>
<OutDir>$(ProjectDir)..\..\bin\$(Platform) $(Configuration)\</OutDir>
<IntDir>$(ProjectDir)..\..\obj\$(Platform) $(Configuration)\</IntDir>
<IncludePath>$(ProjectDir);$(IncludePath);</IncludePath>
<LibraryPath>$(WDKContentRoot)lib\$(DDKSpec)\KM\$(DDKPlatform);$(LibraryPath);</LibraryPath>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<IntrinsicFunctions>true</IntrinsicFunctions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<SmallerTypeCheck>true</SmallerTypeCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>true</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<BrowseInformation>true</BrowseInformation>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<SDLCheck>true</SDLCheck>
<MinimalRebuild>false</MinimalRebuild>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<AdditionalOptions>/kernel %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
<Lib>
<SubSystem>Native</SubSystem>
</Lib>
<Lib>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<IntrinsicFunctions>true</IntrinsicFunctions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<SmallerTypeCheck>true</SmallerTypeCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>true</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<BrowseInformation>true</BrowseInformation>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<SDLCheck>true</SDLCheck>
<MinimalRebuild>false</MinimalRebuild>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<AdditionalOptions>/kernel %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Native</SubSystem>
<AdditionalDependencies>kernel32.lib;msvcrtd.lib</AdditionalDependencies>
<LinkStatus>
</LinkStatus>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>liblfds700.def</ModuleDefinitionFile>
<MapExports>true</MapExports>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
<GenerateMapFile>true</GenerateMapFile>
<Driver>WDM</Driver>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
</Lib>
<Lib>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug LIB|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<IntrinsicFunctions>true</IntrinsicFunctions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<SmallerTypeCheck>true</SmallerTypeCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>true</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<BrowseInformation>true</BrowseInformation>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<SDLCheck>true</SDLCheck>
<MinimalRebuild>false</MinimalRebuild>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<OmitFramePointers>false</OmitFramePointers>
<AdditionalOptions>/kernel %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
<Lib>
<SubSystem>Native</SubSystem>
</Lib>
<Lib>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug DLL|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<IntrinsicFunctions>true</IntrinsicFunctions>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<SmallerTypeCheck>true</SmallerTypeCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>true</FloatingPointExceptions>
<CreateHotpatchableImage>false</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<BrowseInformation>true</BrowseInformation>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<SDLCheck>true</SDLCheck>
<MinimalRebuild>false</MinimalRebuild>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<OmitFramePointers>false</OmitFramePointers>
<AdditionalOptions>/kernel %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Native</SubSystem>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>liblfds700.def</ModuleDefinitionFile>
<MapExports>true</MapExports>
<OptimizeReferences>false</OptimizeReferences>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
<AdditionalDependencies>kernel32.lib;msvcrtd.lib</AdditionalDependencies>
<GenerateMapFile>true</GenerateMapFile>
<Driver>WDM</Driver>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
</Lib>
<Lib>
<LinkTimeCodeGeneration>false</LinkTimeCodeGeneration>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>
</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<OmitFramePointers>true</OmitFramePointers>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<AdditionalOptions>/kernel %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
<Lib>
<SubSystem>Native</SubSystem>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|Win32'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>
</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<OmitFramePointers>true</OmitFramePointers>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<AdditionalOptions>/kernel %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<TargetMachine>MachineX86</TargetMachine>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Native</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<AdditionalDependencies>kernel32.lib;msvcrt.lib</AdditionalDependencies>
<LinkStatus>
</LinkStatus>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>liblfds700.def</ModuleDefinitionFile>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
<Driver>WDM</Driver>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX86</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
<ProjectReference>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
</ProjectReference>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release LIB|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>
</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<OmitFramePointers>true</OmitFramePointers>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<AdditionalOptions>/kernel %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
<SubSystem>Windows</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
<Lib>
<SubSystem>Native</SubSystem>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release DLL|x64'">
<ClCompile>
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;LFDS700_BUILD_TYPE_STRING="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>
</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<WarningLevel>Level4</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<CompileAsManaged>false</CompileAsManaged>
<CompileAsWinRT>false</CompileAsWinRT>
<TreatWarningAsError>true</TreatWarningAsError>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
<IntrinsicFunctions>true</IntrinsicFunctions>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<StringPooling>true</StringPooling>
<ExceptionHandling>false</ExceptionHandling>
<BufferSecurityCheck>false</BufferSecurityCheck>
<FunctionLevelLinking>
</FunctionLevelLinking>
<EnableParallelCodeGeneration>
</EnableParallelCodeGeneration>
<EnableEnhancedInstructionSet>
</EnableEnhancedInstructionSet>
<FloatingPointExceptions>false</FloatingPointExceptions>
<CreateHotpatchableImage>
</CreateHotpatchableImage>
<RuntimeTypeInfo>false</RuntimeTypeInfo>
<OpenMPSupport>false</OpenMPSupport>
<CompileAs>CompileAsC</CompileAs>
<UseFullPaths>true</UseFullPaths>
<ErrorReporting>None</ErrorReporting>
<OmitFramePointers>true</OmitFramePointers>
<DisableSpecificWarnings>4068</DisableSpecificWarnings>
<EnableFiberSafeOptimizations>true</EnableFiberSafeOptimizations>
<AdditionalOptions>/kernel %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
<SubSystem>Native</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<TreatLinkerWarningAsErrors>true</TreatLinkerWarningAsErrors>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
<ModuleDefinitionFile>liblfds700.def</ModuleDefinitionFile>
<LinkErrorReporting>NoErrorReport</LinkErrorReporting>
<AdditionalDependencies>kernel32.lib;msvcrt.lib</AdditionalDependencies>
<Driver>WDM</Driver>
</Link>
<Lib>
<TreatLibWarningAsErrors>true</TreatLibWarningAsErrors>
</Lib>
<Lib>
<TargetMachine>MachineX64</TargetMachine>
</Lib>
<Lib>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="..\..\inc\liblfds700.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_btree_addonly_unbalanced.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_freelist.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_hash_addonly.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_ordered_singlylinked.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_singlylinked_unordered.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_misc.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_compiler.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_operating_system.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_processor.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue_bounded_singleconsumer_singleproducer.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_ringbuffer.h" />
<ClInclude Include="..\..\inc\liblfds700\lfds700_stack.h" />
<ClInclude Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_internal.h" />
<ClInclude Include="..\..\src\lfds700_freelist\lfds700_freelist_internal.h" />
<ClInclude Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_internal.h" />
<ClInclude Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_internal.h" />
<ClInclude Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_internal.h" />
<ClInclude Include="..\..\src\lfds700_misc\lfds700_misc_internal.h" />
<ClInclude Include="..\..\src\lfds700_queue\lfds700_queue_internal.h" />
<ClInclude Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_internal.h" />
<ClInclude Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_internal.h" />
<ClInclude Include="..\..\src\lfds700_stack\lfds700_stack_internal.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_get.c" />
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_init.c" />
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_insert.c" />
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_query.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_init.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_pop.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_push.c" />
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_query.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_get.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_init.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_insert.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_iterate.c" />
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_query.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_get.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_init.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_insert.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_query.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_get.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_init.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_insert.c" />
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_query.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_globals.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_init.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_prng.c" />
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_query.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_dequeue.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_enqueue.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_init.c" />
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_query.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_init.c" />
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_query.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_init.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_query.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_read.c" />
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_write.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_cleanup.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_init.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_pop.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_push.c" />
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_query.c" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
@@ -0,0 +1,279 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="Header Files\liblfds700">
<UniqueIdentifier>{258be429-7dac-4999-b995-753aa2f0c505}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_freelist">
<UniqueIdentifier>{469abf8e-47d8-4678-bd66-7c7e65c5f52e}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_ringbuffer">
<UniqueIdentifier>{62ee141b-2acb-4555-b016-7be20a57f2bf}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_stack">
<UniqueIdentifier>{19c73b0f-25e0-4166-9093-427f1dfb4f70}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_queue">
<UniqueIdentifier>{00eb30fe-e638-4c2b-8ca1-1f09c4a0ed45}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_queue_bounded_singleconsumer_singleproducer">
<UniqueIdentifier>{6250c4d5-ac8e-4c28-93de-0954c5bed1cb}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_misc">
<UniqueIdentifier>{400ae4e9-2281-4549-b918-59d1a27a2d07}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_list_addonly_ordered_singlylinked">
<UniqueIdentifier>{c45194af-7b41-4c28-bc0e-1095ec347664}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_list_addonly_singlylinked_unordered">
<UniqueIdentifier>{8b3cbb5c-7436-429f-9b72-bae1f4721746}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_hash_addonly">
<UniqueIdentifier>{bcbadc74-1748-4696-aad7-7fdbe5614624}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_btree_addonly_unbalanced">
<UniqueIdentifier>{0b1fafc3-817b-4c18-8eb1-121884e3a29b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\inc\liblfds700.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_freelist\lfds700_freelist_internal.h">
<Filter>Source Files\lfds700_freelist</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_stack\lfds700_stack_internal.h">
<Filter>Source Files\lfds700_stack</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_queue\lfds700_queue_internal.h">
<Filter>Source Files\lfds700_queue</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_btree_addonly_unbalanced.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_freelist.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_hash_addonly.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_ordered_singlylinked.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_singlylinked_unordered.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_misc.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_compiler.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_operating_system.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_processor.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue_bounded_singleconsumer_singleproducer.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_ringbuffer.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_stack.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_internal.h">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_internal.h">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_internal.h">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_misc\lfds700_misc_internal.h">
<Filter>Source Files\lfds700_misc</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_internal.h">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_internal.h">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_internal.h">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_cleanup.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_init.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_pop.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_push.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_query.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_cleanup.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_init.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_pop.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_push.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_query.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_cleanup.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_dequeue.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_enqueue.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_init.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_query.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_cleanup.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_get.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_init.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_insert.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_iterate.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_query.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_cleanup.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_get.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_init.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_insert.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_query.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_cleanup.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_get.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_init.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_insert.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_query.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_cleanup.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_globals.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_init.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_prng.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_query.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_init.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_query.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_cleanup.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_get.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_init.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_insert.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_query.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_cleanup.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_init.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_query.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_read.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_write.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
@@ -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
@@ -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
@@ -0,0 +1,279 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Source Files">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="Header Files">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
</Filter>
<Filter Include="Header Files\liblfds700">
<UniqueIdentifier>{258be429-7dac-4999-b995-753aa2f0c505}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_freelist">
<UniqueIdentifier>{469abf8e-47d8-4678-bd66-7c7e65c5f52e}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_ringbuffer">
<UniqueIdentifier>{62ee141b-2acb-4555-b016-7be20a57f2bf}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_stack">
<UniqueIdentifier>{19c73b0f-25e0-4166-9093-427f1dfb4f70}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_queue">
<UniqueIdentifier>{00eb30fe-e638-4c2b-8ca1-1f09c4a0ed45}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_queue_bounded_singleconsumer_singleproducer">
<UniqueIdentifier>{6250c4d5-ac8e-4c28-93de-0954c5bed1cb}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_misc">
<UniqueIdentifier>{400ae4e9-2281-4549-b918-59d1a27a2d07}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_list_addonly_ordered_singlylinked">
<UniqueIdentifier>{c45194af-7b41-4c28-bc0e-1095ec347664}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_list_addonly_singlylinked_unordered">
<UniqueIdentifier>{8b3cbb5c-7436-429f-9b72-bae1f4721746}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_hash_addonly">
<UniqueIdentifier>{bcbadc74-1748-4696-aad7-7fdbe5614624}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\lfds700_btree_addonly_unbalanced">
<UniqueIdentifier>{0b1fafc3-817b-4c18-8eb1-121884e3a29b}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\inc\liblfds700.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_freelist\lfds700_freelist_internal.h">
<Filter>Source Files\lfds700_freelist</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_stack\lfds700_stack_internal.h">
<Filter>Source Files\lfds700_stack</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_queue\lfds700_queue_internal.h">
<Filter>Source Files\lfds700_queue</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_btree_addonly_unbalanced.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_freelist.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_hash_addonly.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_ordered_singlylinked.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_list_addonly_singlylinked_unordered.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_misc.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_compiler.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_operating_system.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_porting_abstraction_layer_processor.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_queue_bounded_singleconsumer_singleproducer.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_ringbuffer.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\inc\liblfds700\lfds700_stack.h">
<Filter>Header Files\liblfds700</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_internal.h">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_internal.h">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_internal.h">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_misc\lfds700_misc_internal.h">
<Filter>Source Files\lfds700_misc</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_internal.h">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_internal.h">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClInclude>
<ClInclude Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_internal.h">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_cleanup.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_init.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_pop.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_push.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_freelist\lfds700_freelist_query.c">
<Filter>Source Files\lfds700_freelist</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_cleanup.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_init.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_pop.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_push.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_stack\lfds700_stack_query.c">
<Filter>Source Files\lfds700_stack</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_cleanup.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_dequeue.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_enqueue.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_init.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue\lfds700_queue_query.c">
<Filter>Source Files\lfds700_queue</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_cleanup.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_get.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_init.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_insert.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_iterate.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_hash_addonly\lfds700_hash_addonly_query.c">
<Filter>Source Files\lfds700_hash_addonly</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_cleanup.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_get.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_init.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_insert.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_ordered_singlylinked\lfds700_list_addonly_ordered_singlylinked_query.c">
<Filter>Source Files\lfds700_list_addonly_ordered_singlylinked</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_cleanup.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_get.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_init.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_insert.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_btree_addonly_unbalanced\lfds700_btree_addonly_unbalanced_query.c">
<Filter>Source Files\lfds700_btree_addonly_unbalanced</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_cleanup.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_globals.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_init.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_prng.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_misc\lfds700_misc_query.c">
<Filter>Source Files\lfds700_misc</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_cleanup.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_dequeue.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_enqueue.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_init.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_queue_bounded_singleconsumer_singleproducer\lfds700_queue_bounded_singleconsumer_singleproducer_query.c">
<Filter>Source Files\lfds700_queue_bounded_singleconsumer_singleproducer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_cleanup.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_get.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_init.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_insert.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_list_addonly_singlylinked_unordered\lfds700_list_addonly_singlylinked_unordered_query.c">
<Filter>Source Files\lfds700_list_addonly_singlylinked_unordered</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_cleanup.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_init.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_query.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_read.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
<ClCompile Include="..\..\src\lfds700_ringbuffer\lfds700_ringbuffer_write.c">
<Filter>Source Files\lfds700_ringbuffer</Filter>
</ClCompile>
</ItemGroup>
</Project>
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup />
</Project>
@@ -0,0 +1,3 @@
DIRS = single_dir_for_windows_kernel
@@ -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 )
@@ -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
@@ -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.
@@ -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).
@@ -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).
@@ -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
@@ -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
@@ -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
@@ -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 );
@@ -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 );
@@ -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 );
@@ -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 );
@@ -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 );
@@ -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;
}
@@ -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
@@ -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 <assert.h>
#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 <assert.h>
#include <intrin.h>
#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 <assert.h>
#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 <linux/module.h>
#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
@@ -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
@@ -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 );
@@ -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 );
@@ -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 );
@@ -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 );
@@ -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;
}
@@ -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 );
}
@@ -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;
}
@@ -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 );
}
@@ -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 *****/
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -0,0 +1,5 @@
/***** the library wide include file *****/
#include "../liblfds700_internal.h"
/***** private prototypes *****/
@@ -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 );
}
@@ -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;
}
@@ -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;
}
@@ -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 )
@@ -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 );
}
@@ -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;
}
@@ -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 );
}
@@ -0,0 +1,5 @@
/***** the library wide include file *****/
#include "../liblfds700_internal.h"
/***** private prototypes *****/
@@ -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 );
}
@@ -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;
}
@@ -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;
}
@@ -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 );
}
@@ -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;
}
@@ -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 );
}
@@ -0,0 +1,5 @@
/***** the library wide include file *****/
#include "../liblfds700_internal.h"
/***** private prototypes *****/
@@ -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;
}
@@ -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;
}
@@ -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 );
}
@@ -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;
}
@@ -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 )
@@ -0,0 +1,5 @@
/***** the library wide include file *****/
#include "../liblfds700_internal.h"
/***** private prototypes *****/
@@ -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;
}
@@ -0,0 +1,15 @@
/***** includes *****/
#include "lfds700_misc_internal.h"
/****************************************************************************/
void lfds700_misc_library_cleanup( void )
{
// TRD : we do nuuuuuuthin'
return;
}
@@ -0,0 +1,11 @@
/***** includes *****/
#include "lfds700_misc_internal.h"
/****************************************************************************/
struct lfds700_misc_globals
lfds700_misc_globals;
@@ -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;
}
@@ -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 );
@@ -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;
}
@@ -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;
}
@@ -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;
}
@@ -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 );
}
@@ -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;
}
@@ -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;
}
@@ -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 *****/
@@ -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;
}
@@ -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;
}
@@ -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 );
}
@@ -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 );
}

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