Merge branch 'develop' of https://gitlab.eurecom.fr/oai/openairinterface5g into develop1B

This commit is contained in:
gabrielC
2016-12-06 12:05:25 +01:00
291 changed files with 39208 additions and 1084 deletions
+254
View File
@@ -0,0 +1,254 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file link_manager.c
* \brief this is the implementation of a link manager
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#include "link_manager.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
/* that thread reads messages in the queue and sends them to the link */
static void *link_manager_sender_thread(void *_manager)
{
link_manager_t *manager = _manager;
void *data;
int size;
int priority;
LOG_D(MAC, "starting link manager sender thread\n");
while (manager->run) {
while (message_get(manager->send_queue, &data, &size, &priority) == 0) {
link_send_packet(manager->socket_link, data, size);
free(data);
}
// if (message_get(manager->send_queue, &data, &size, &priority))
// goto error;
//if (link_send_packet(manager->socket_link, data, size))
// goto error;
//free(data);
}
LOG_D(MAC, "link manager sender thread quits\n");
return NULL;
error:
LOG_E(MAC, "%s: error\n", __FUNCTION__);
return NULL;
}
/* that thread receives messages from the link and puts them in the queue */
static void *link_manager_receiver_thread(void *_manager)
{
link_manager_t *manager = _manager;
void *data;
int size;
LOG_D(MAC, "starting link manager receiver thread\n");
while (manager->run) {
if (link_receive_packet(manager->socket_link, &data, &size))
goto error;
/* todo: priority */
if (message_put(manager->receive_queue, data, size, 0))
goto error;
}
LOG_D(MAC, "link manager receiver thread quits\n");
return NULL;
error:
LOG_E(MAC, "%s: error\n", __FUNCTION__);
return NULL;
}
link_manager_t *create_link_manager(
message_queue_t *send_queue,
message_queue_t *receive_queue,
socket_link_t *link)
{
link_manager_t *ret = NULL;
pthread_attr_t attr;
pthread_t t;
LOG_D(MAC, "create new link manager\n");
ret = calloc(1, sizeof(link_manager_t));
if (ret == NULL)
goto error;
ret->send_queue = send_queue;
ret->receive_queue = receive_queue;
ret->socket_link = link;
ret->run = 1;
if (pthread_attr_init(&attr))
goto error;
// Make the async interface threads real-time
//#ifndef LOWLATENCY
struct sched_param sched_param_recv_thread;
struct sched_param sched_param_send_thread;
sched_param_recv_thread.sched_priority = sched_get_priority_max(SCHED_RR) - 1;
pthread_attr_setschedparam(&attr, &sched_param_recv_thread);
pthread_attr_setschedpolicy(&attr, SCHED_RR);
//#endif
if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED))
goto error;
if (pthread_create(&t, &attr, link_manager_sender_thread, ret))
goto error;
ret->sender = t;
if (pthread_create(&t, &attr, link_manager_receiver_thread, ret))
/* we should destroy the other thread here */
goto error;
ret->receiver = t;
if (pthread_attr_destroy(&attr))
/* to be clean we should destroy the threads at this point,
* even if in practice we never reach it */
goto error;
return ret;
error:
LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
free(ret);
return NULL;
}
void destroy_link_manager(link_manager_t *manager)
{
LOG_D(MAC, "destroying link manager\n");
manager->run = 0;
/* todo: force threads to stop (using a dummy message?) */
}
#ifdef SERVER_TEST
#include <string.h>
int main(void)
{
socket_link_t *link;
message_queue_t *send_queue;
message_queue_t *receive_queue;
link_manager_t *manager;
void *data;
int size;
int priority;
printf("starting server\n");
link = new_link_server(2210);
if (link == NULL) goto error;
send_queue = new_message_queue();
if (send_queue == NULL) goto error;
receive_queue = new_message_queue();
if (receive_queue == NULL) goto error;
manager = create_link_manager(send_queue, receive_queue, link);
if (manager == NULL) goto error;
data = strdup("hello"); if (data == NULL) goto error;
if (message_put(send_queue, data, 6, 100)) goto error;
if (message_get(receive_queue, &data, &size, &priority)) goto error;
printf("received message:\n");
printf(" data: %s\n", (char *)data);
printf(" size: %d\n", size);
printf(" priority: %d\n", priority);
printf("server ends\n");
return 0;
error:
printf("there was an error\n");
return 1;
}
#endif
#ifdef CLIENT_TEST
#include <string.h>
#include <unistd.h>
int main(void)
{
socket_link_t *link;
message_queue_t *send_queue;
message_queue_t *receive_queue;
link_manager_t *manager;
void *data;
int size;
int priority;
printf("starting client\n");
link = new_link_client("127.0.0.1", 2210);
if (link == NULL) goto error;
send_queue = new_message_queue();
if (send_queue == NULL) goto error;
receive_queue = new_message_queue();
if (receive_queue == NULL) goto error;
manager = create_link_manager(send_queue, receive_queue, link);
if (manager == NULL) goto error;
if (message_get(receive_queue, &data, &size, &priority)) goto error;
printf("received message:\n");
printf(" data: %s\n", (char *)data);
printf(" size: %d\n", size);
printf(" priority: %d\n", priority);
data = strdup("world"); if (data == NULL) goto error;
if (message_put(send_queue, data, 6, 200)) goto error;
/* let's wait for the message to be sent (unreliable sleep, but does it for the test) */
sleep(1);
printf("client ends\n");
return 0;
error:
printf("there was an error\n");
return 1;
}
#endif
+63
View File
@@ -0,0 +1,63 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file link_manager.h
* \brief this is the implementation of a link manager
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#ifndef LINK_MANAGER_H
#define LINK_MANAGER_H
//#include "message_queue.h"
#include "ringbuffer_queue.h"
#include "socket_link.h"
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
message_queue_t *send_queue;
message_queue_t *receive_queue;
socket_link_t *socket_link;
pthread_t sender;
pthread_t receiver;
volatile int run;
} link_manager_t;
link_manager_t *create_link_manager(
message_queue_t *send_queue,
message_queue_t *receive_queue,
socket_link_t *link);
void destroy_link_manager(link_manager_t *);
#ifdef __cplusplus
}
#endif
#endif /* LINK_MANAGER_H */
+204
View File
@@ -0,0 +1,204 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file message_queue.c
* \brief this is the implementation of a message queue
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#include "message_queue.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
message_queue_t *new_message_queue(void)
{
message_queue_t *ret = NULL;
ret = calloc(1, sizeof(message_queue_t));
if (ret == NULL)
goto error;
ret->mutex = calloc(1, sizeof(pthread_mutex_t));
if (ret->mutex == NULL)
goto error;
if (pthread_mutex_init(ret->mutex, NULL))
goto error;
ret->cond = calloc(1, sizeof(pthread_cond_t));
if (ret->cond == NULL)
goto error;
if (pthread_cond_init(ret->cond, NULL))
goto error;
return ret;
error:
LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
if (ret != NULL) {
free(ret->mutex);
free(ret->cond);
memset(ret, 0, sizeof(message_queue_t));
free(ret);
}
return NULL;
}
int message_put(message_queue_t *queue, void *data, int size, int priority)
{
message_t *m = NULL;
m = calloc(1, sizeof(message_t));
if (m == NULL)
goto error;
m->data = data;
m->size = size;
m->priority = priority;
m->next = NULL;
if (pthread_mutex_lock(queue->mutex))
goto error;
if (queue->count == 0)
queue->head = m;
else
queue->tail->next = m;
queue->tail = m;
queue->count++;
if (pthread_cond_signal(queue->cond)) {
LOG_E(MAC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
pthread_mutex_unlock(queue->mutex);
exit(1);
}
if (pthread_mutex_unlock(queue->mutex)) {
LOG_E(MAC, "%s:%d:%s: fatal error\n", __FILE__, __LINE__, __FUNCTION__);
exit(1);
}
return 0;
error:
free(m);
LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int message_get(message_queue_t *queue, void **data, int *size, int *priority)
{
message_t *m;
if (pthread_mutex_lock(queue->mutex))
goto error;
while (queue->count == 0) {
if (pthread_cond_wait(queue->cond, queue->mutex)) {
pthread_mutex_unlock(queue->mutex);
goto error;
}
}
m = queue->head;
queue->head = queue->head->next;
if (queue->head == NULL)
queue->tail = NULL;
queue->count--;
if (pthread_mutex_unlock(queue->mutex))
goto error;
*data = m->data;
*size = m->size;
*priority = m->priority;
free(m);
return 0;
error:
LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
/* when calling this function, the queue must not be used anymore (we don't lock it) */
/* we suppose that the data pointer in messages was allocated by malloc/calloc/realloc */
void destroy_message_queue(message_queue_t *queue)
{
while (queue->head) {
message_t *m = queue->head;
queue->head = queue->head->next;
free(m->data);
memset(m, 0, sizeof(message_t));
free(m);
}
free(queue->mutex);
free(queue->cond);
memset(queue, 0, sizeof(message_queue_t));
free(queue);
}
#ifdef TEST
/* some very basic tests */
int main(void)
{
void *data;
int size;
int priority;
message_queue_t *q;
char *s;
q = new_message_queue();
if (q == NULL) goto error;
if (message_put(q, "hello", 6, 0)) goto error;
if (message_put(q, "world", 6, 1)) goto error;
if (message_get(q, &data, &size, &priority)) goto error;
printf("message:\n data: '%s'\n size: %d\n priority: %d\n",
(char *)data, size, priority);
if (message_get(q, &data, &size, &priority)) goto error;
printf("message:\n data: '%s'\n size: %d\n priority: %d\n",
(char *)data, size, priority);
/* let's put a message before destroying the queue */
s = malloc(10); if (s == NULL) goto error;
sprintf(s, "hello");
if (message_put(q, s, 6, 0)) goto error;
destroy_message_queue(q);
return 0;
error:
printf("error\n");
return 1;
}
#endif
+64
View File
@@ -0,0 +1,64 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file message_queue.h
* \brief this is the implementation of a message queue
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#ifndef MESSAGE_QUEUE_H
#define MESSAGE_QUEUE_H
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct message_t {
void *data;
int size;
int priority;
struct message_t *next;
} message_t;
typedef struct {
message_t *head;
message_t *tail;
volatile int count;
pthread_mutex_t *mutex;
pthread_cond_t *cond;
} message_queue_t;
message_queue_t *new_message_queue(void);
int message_put(message_queue_t *queue, void *data, int size, int priority);
int message_get(message_queue_t *queue, void **data, int *size, int *priority);
void destroy_message_queue(message_queue_t *queue);
#ifdef __cplusplus
}
#endif
#endif /* MESSAGE_QUEUE_H */
+136
View File
@@ -0,0 +1,136 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file ringbuffer_queue.c
* \brief Lock-free ringbuffer used for async message passing of agent
* \author Xenofon Foukas
* \date March 2016
* \version 1.0
* \email: x.foukas@sms.ed.ac.uk
* @ingroup _mac
*/
#include "ringbuffer_queue.h"
#include "log.h"
message_queue_t * new_message_queue(int size) {
message_queue_t *ret = NULL;
ret = calloc(1, sizeof(message_queue_t));
if (ret == NULL)
goto error;
lfds700_misc_library_init_valid_on_current_logical_core();
lfds700_misc_prng_init(&(ret->ps));
ret->ringbuffer_array = malloc(sizeof(struct lfds700_ringbuffer_element) * size);
lfds700_ringbuffer_init_valid_on_current_logical_core(&(ret->ringbuffer_state),
ret->ringbuffer_array,
size,
&(ret->ps),
NULL);
return ret;
error:
LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
if (ret != NULL) {
free(ret->ringbuffer_array);
memset(ret, 0, sizeof(message_queue_t));
free(ret);
}
return NULL;
}
int message_put(message_queue_t *queue, void *data, int size, int priority) {
struct lfds700_misc_prng_state ls;
enum lfds700_misc_flag overwrite_occurred_flag;
message_t *overwritten_msg;
message_t *m = NULL;
LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
lfds700_misc_prng_init(&ls);
m = calloc(1, sizeof(message_t));
if (m == NULL)
goto error;
m->data = data;
m->size = size;
m->priority = priority;
lfds700_ringbuffer_write(&(queue->ringbuffer_state),
NULL,
(void *) m,
&overwrite_occurred_flag,
NULL,
(void **) &overwritten_msg,
&ls);
if (overwrite_occurred_flag == LFDS700_MISC_FLAG_RAISED) {
free(overwritten_msg->data);
free(overwritten_msg);
}
return 0;
error:
free(m);
LOG_E(MAC, "%s: an error occured\n", __FUNCTION__);
return -1;
}
int message_get(message_queue_t *queue, void **data, int *size, int *priority) {
message_t *m;
struct lfds700_misc_prng_state ls;
LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
lfds700_misc_prng_init(&ls);
if (lfds700_ringbuffer_read(&(queue->ringbuffer_state), NULL, (void **) &m, &ls) == 0) {
return -1;
}
*data = m->data;
*size = m->size;
*priority = m->priority;
free(m);
return 0;
}
message_queue_t destroy_message_queue(message_queue_t *queue) {
struct lfds700_misc_prng_state ls;
message_t *m;
LFDS700_MISC_MAKE_VALID_ON_CURRENT_LOGICAL_CORE_INITS_COMPLETED_BEFORE_NOW_ON_ANY_OTHER_LOGICAL_CORE;
lfds700_misc_prng_init(&ls);
while (lfds700_ringbuffer_read(&(queue->ringbuffer_state), NULL, (void **) &m, &ls) != 0) {
free(m->data);
memset(m, 0, sizeof(message_t));
free(m);
}
free(queue->ringbuffer_array);
memset(queue, 0, sizeof(message_queue_t));
free(queue);
}
+53
View File
@@ -0,0 +1,53 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file ringbuffer_queue.h
* \brief Lock-free ringbuffer used for async message passing of agent
* \author Xenofon Foukas
* \date March 2016
* \version 1.0
* \email: x.foukas@sms.ed.ac.uk
* @ingroup _mac
*/
#ifndef RINGBUFFER_QUEUE_H
#define RINGBUFFER_QUEUE_H
#include "liblfds700.h"
typedef struct message_s {
void *data;
int size;
int priority;
} message_t;
typedef struct {
struct lfds700_misc_prng_state ps;
struct lfds700_ringbuffer_element *ringbuffer_array;
struct lfds700_ringbuffer_state ringbuffer_state;
} message_queue_t;
message_queue_t * new_message_queue(int size);
int message_put(message_queue_t *queue, void *data, int size, int priority);
int message_get(message_queue_t *queue, void **data, int *size, int *priority);
message_queue_t destroy_message_queue(message_queue_t *queue);
#endif /* RINGBUFFER_QUEUE_H */
+357
View File
@@ -0,0 +1,357 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file socket_link.c
* \brief this is the implementation of a TCP socket ASYNC IF
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#include "socket_link.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <stdint.h>
socket_link_t *new_link_server(int port)
{
socket_link_t *ret = NULL;
int reuse;
struct sockaddr_in addr;
socklen_t addrlen;
int socket_server = -1;
int no_delay;
ret = calloc(1, sizeof(socket_link_t));
if (ret == NULL) {
LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__);
goto error;
}
ret->socket_fd = -1;
LOG_D(MAC, "create a new link server socket at port %d\n", port);
socket_server = socket(AF_INET, SOCK_STREAM, 0);
if (socket_server == -1) {
LOG_E(MAC, "%s:%d: socket: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
reuse = 1;
if (setsockopt(socket_server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
LOG_E(MAC, "%s:%d: setsockopt: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
no_delay = 1;
if (setsockopt(socket_server, IPPROTO_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay)) == -1) {
LOG_E(MAC, "%s:%d: setsockopt: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
addr.sin_addr.s_addr = INADDR_ANY;
if (bind(socket_server, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
LOG_E(MAC, "%s:%d: bind: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
if (listen(socket_server, 5)) {
LOG_E(MAC, "%s:%d: listen: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
addrlen = sizeof(addr);
ret->socket_fd = accept(socket_server, (struct sockaddr *)&addr, &addrlen);
if (ret->socket_fd == -1) {
LOG_E(MAC, "%s:%d: accept: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
close(socket_server);
LOG_D(MAC, "connection from %s:%d\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
return ret;
error:
close(socket_server);
if (ret != NULL) close(ret->socket_fd);
free(ret);
LOG_E(MAC, "ERROR in new_link_server (see above), returning NULL\n");
return NULL;
}
socket_link_t *new_link_client(char *server, int port)
{
socket_link_t *ret = NULL;
struct sockaddr_in addr;
int no_delay;
ret = calloc(1, sizeof(socket_link_t));
if (ret == NULL) {
LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__);
goto error;
}
ret->socket_fd = -1;
LOG_D(MAC, "create a new link client socket connecting to %s:%d\n", server, port);
ret->socket_fd = socket(AF_INET, SOCK_STREAM, 0);
if (ret->socket_fd == -1) {
LOG_E(MAC, "%s:%d: socket: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
no_delay = 1;
if (setsockopt(ret->socket_fd, SOL_TCP, TCP_NODELAY, &no_delay, sizeof(no_delay)) == -1) {
LOG_E(MAC, "%s:%d: setsockopt: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
if (inet_aton(server, &addr.sin_addr) == 0) {
LOG_E(MAC, "invalid IP address '%s', use a.b.c.d notation\n", server);
goto error;
}
if (connect(ret->socket_fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) {
LOG_E(MAC, "%s:%d: connect: %s\n", __FILE__, __LINE__, strerror(errno));
goto error;
}
LOG_D(MAC, "connection to %s:%d established\n", inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
return ret;
error:
if (ret != NULL) close(ret->socket_fd);
free(ret);
LOG_E(MAC, "ERROR in new_link_client (see above), returning NULL\n");
return NULL;
}
/*
* return -1 on error and 0 if the sending was fine
*/
static int socket_send(int socket_fd, void *buf, int size)
{
char *s = buf;
int l;
while (size) {
l = send(socket_fd, s, size, MSG_NOSIGNAL);
if (l == -1) goto error;
if (l == 0) { LOG_E(MAC, "%s:%d: this cannot happen, normally...\n", __FILE__, __LINE__); abort(); }
size -= l;
s += l;
}
return 0;
error:
LOG_E(MAC, "socket_send: ERROR: %s\n", strerror(errno));
return -1;
}
/*
* return -1 on error and 0 if the receiving was fine
*/
static int socket_receive(int socket_fd, void *buf, int size)
{
char *s = buf;
int l;
while (size) {
l = read(socket_fd, s, size);
if (l == -1) goto error;
if (l == 0) goto socket_closed;
size -= l;
s += l;
}
return 0;
error:
LOG_E(MAC, "socket_receive: ERROR: %s\n", strerror(errno));
return -1;
socket_closed:
LOG_E(MAC, "socket_receive: socket closed\n");
return -1;
}
/*
* return -1 on error and 0 if the sending was fine
*/
int link_send_packet(socket_link_t *link, void *data, int size)
{
char sizebuf[4];
int32_t s = size;
/* send the size first, maximum is 2^31 bytes */
sizebuf[0] = (s >> 24) & 255;
sizebuf[1] = (s >> 16) & 255;
sizebuf[2] = (s >> 8) & 255;
sizebuf[3] = s & 255;
if (socket_send(link->socket_fd, sizebuf, 4) == -1)
goto error;
link->bytes_sent += 4;
if (socket_send(link->socket_fd, data, size) == -1)
goto error;
link->bytes_sent += size;
link->packets_sent++;
return 0;
error:
return -1;
}
/*
* return -1 on error and 0 if the sending was fine
*/
int link_receive_packet(socket_link_t *link, void **ret_data, int *ret_size)
{
unsigned char sizebuf[4];
int32_t size;
void *data = NULL;
/* received the size first, maximum is 2^31 bytes */
if (socket_receive(link->socket_fd, sizebuf, 4) == -1)
goto error;
size = (sizebuf[0] << 24) |
(sizebuf[1] << 16) |
(sizebuf[2] << 8) |
sizebuf[3];
link->bytes_received += 4;
data = malloc(size);
if (data == NULL) {
LOG_E(MAC, "%s:%d: out of memory\n", __FILE__, __LINE__);
goto error;
}
if (socket_receive(link->socket_fd, data, size) == -1)
goto error;
link->bytes_received += size;
link->packets_received++;
*ret_data = data;
*ret_size = size;
return 0;
error:
free(data);
*ret_data = NULL;
*ret_size = 0;
return -1;
}
/*
* return -1 on error, 0 if all is fine
*/
int close_link(socket_link_t *link)
{
close(link->socket_fd);
memset(link, 0, sizeof(socket_link_t));
free(link);
return 0;
}
#ifdef SERVER_TEST
#include <inttypes.h>
int main(void)
{
void *data;
int size;
socket_link_t *l = new_link_server(2210);
if (l == NULL) { printf("no link created\n"); return 1; }
printf("link is up\n");
printf("server starts sleeping...\n");
/* this sleep is here to test for broken pipe. You can run "nc localhost 2210"
* and interrupt it quickly so that the server gets a 'broken' pipe on the
* following link_send_packet.
*/
sleep(1);
printf("... done\n");
if (link_send_packet(l, "hello\n", 6+1) ||
link_send_packet(l, "world\n", 6+1)) return 1;
if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data);
if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data);
printf("stats:\n");
printf(" sent packets %"PRIu64"\n", l->packets_sent);
printf(" sent bytes %"PRIu64"\n", l->bytes_sent);
printf(" received packets %"PRIu64"\n", l->packets_received);
printf(" received bytes %"PRIu64"\n", l->bytes_received);
if (close_link(l)) return 1;
printf("link is down\n");
return 0;
}
#endif
#ifdef CLIENT_TEST
#include <inttypes.h>
int main(void)
{
void *data;
int size;
socket_link_t *l = new_link_client("127.0.0.1", 2210);
if (l == NULL) { printf("no link created\n"); return 1; }
printf("link is up\n");
if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data);
if (link_receive_packet(l, &data, &size)) return 1; printf("%s", (char *)data); free(data);
if (link_send_packet(l, "bye\n", 4+1) ||
link_send_packet(l, "server\n", 7+1)) return 1;
printf("stats:\n");
printf(" sent packets %"PRIu64"\n", l->packets_sent);
printf(" sent bytes %"PRIu64"\n", l->bytes_sent);
printf(" received packets %"PRIu64"\n", l->packets_received);
printf(" received bytes %"PRIu64"\n", l->bytes_received);
if (close_link(l)) return 1;
printf("link is down\n");
return 0;
}
#endif
+58
View File
@@ -0,0 +1,58 @@
/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.0 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*! \file socket_link.h
* \brief this is the implementation of a TCP socket ASYNC IF
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#ifndef SOCKET_LINK_H
#define SOCKET_LINK_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
int socket_fd;
uint64_t bytes_sent;
uint64_t packets_sent;
uint64_t bytes_received;
uint64_t packets_received;
} socket_link_t;
socket_link_t *new_link_server(int port);
socket_link_t *new_link_client(char *server, int port);
int link_send_packet(socket_link_t *link, void *data, int size);
int link_receive_packet(socket_link_t *link, void **data, int *size);
int close_link(socket_link_t *link);
#ifdef __cplusplus
}
#endif
#endif /* SOCKET_LINK_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 );
}
@@ -0,0 +1,63 @@
/***** includes *****/
#include "lfds700_queue_bounded_singleconsumer_singleproducer_internal.h"
/****************************************************************************/
void lfds700_queue_bss_init_valid_on_current_logical_core( struct lfds700_queue_bss_state *qbsss,
struct lfds700_queue_bss_element *element_array,
lfds700_pal_uint_t number_elements,
void *user_state )
{
LFDS700_PAL_ASSERT( qbsss != NULL );
LFDS700_PAL_ASSERT( element_array != NULL );
LFDS700_PAL_ASSERT( number_elements >= 2 );
LFDS700_PAL_ASSERT( ( number_elements & (number_elements-1) ) == 0 ); // TRD : number_elements must be a positive integer power of 2
// TRD : user_state can be NULL
/* TRD : the use of mask and the restriction on a power of two
upon the number of elements bears some remark
in this queue, there are a fixed number of elements
we have a read index and a write index
when we write, and thre is space to write, we increment the write index
(if no space to write, we just return)
when we read, and there are elements to be read, we after reading increment the read index
(if no elements to read, we just return)
the problem is - how do we handle wrap around?
e.g. when I write, but my write index is now equal to the number of elements
the usual solution is to modulus the write index by the nunmber of elements
problem is modulus is slow
there is a better way
first, we restrict the number of elements to be a power of two
so imagine we have a 64-bit system and we set the number of elements to be 2^64
this gives us a bit pattern of 1000 0000 0000 0000 (...etc, lots of zeros)
now (just roll with this for a bit) subtract one from this
this gives us a mask (on a two's compliment machine)
0111 1111 1111 1111 (...etc, lots of ones)
so what we do now, when we increment an index (think of the write index as the example)
we bitwise and it with the mask
now think about thwt happens
all the numbers up to 2^64 will be unchanged - their MSB is never set, and we and with all the other bits
but when we finally hit 2^64 and need to roll over... bingo!
we drop MSB (which we finally have) and have the value 0!
this is exactly what we want
bitwise and is much faster than modulus
*/
qbsss->number_elements = number_elements;
qbsss->mask = qbsss->number_elements - 1;
qbsss->read_index = 0;
qbsss->write_index = 0;
qbsss->element_array = element_array;
qbsss->user_state = user_state;
LFDS700_MISC_BARRIER_STORE;
lfds700_misc_force_store();
return;
}
@@ -0,0 +1,5 @@
/***** the library wide include file *****/
#include "../liblfds700_internal.h"
/***** private prototypes *****/

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