Add slist.
Slist removed from skygw_utils and added as a separate component. Nobody seems to be using it, so it could also simply be removed. Left in place for the time being.
This commit is contained in:
@ -1,4 +1,4 @@
|
|||||||
add_library(maxscale-common SHARED adminusers.c atomic.c buffer.c config.c dbusers.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c modutil.c monitor.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c spinlock.c thread.c users.c utils.c ${CMAKE_SOURCE_DIR}/utils/skygw_utils.cc statistics.c)
|
add_library(maxscale-common SHARED adminusers.c atomic.c buffer.c config.c dbusers.c dcb.c filter.c externcmd.c gwbitmask.c gwdirs.c gw_utils.c hashtable.c hint.c housekeeper.c load_utils.c log_manager.cc maxscale_pcre2.c memlog.c modutil.c monitor.c query_classifier.c poll.c random_jkiss.c resultset.c secrets.c server.c service.c session.c slist.c spinlock.c thread.c users.c utils.c ${CMAKE_SOURCE_DIR}/utils/skygw_utils.cc statistics.c)
|
||||||
|
|
||||||
target_link_libraries(maxscale-common ${MARIADB_CONNECTOR_LIBRARIES} ${LZMA_LINK_FLAGS} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ssl aio pthread crypt dl crypto inih z rt m stdc++)
|
target_link_libraries(maxscale-common ${MARIADB_CONNECTOR_LIBRARIES} ${LZMA_LINK_FLAGS} ${PCRE2_LIBRARIES} ${CURL_LIBRARIES} ssl aio pthread crypt dl crypto inih z rt m stdc++)
|
||||||
|
|
||||||
|
|||||||
366
server/core/slist.c
Normal file
366
server/core/slist.c
Normal file
@ -0,0 +1,366 @@
|
|||||||
|
|
||||||
|
/*
|
||||||
|
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
|
||||||
|
* software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation,
|
||||||
|
* version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||||
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright MariaDB Corporation Ab 2013-2014
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <slist.h>
|
||||||
|
#include <atomic.h>
|
||||||
|
|
||||||
|
static slist_cursor_t* slist_cursor_init(slist_t* list);
|
||||||
|
static slist_t* slist_init_ex(bool create_cursors);
|
||||||
|
static slist_node_t* slist_node_init(void* data, slist_cursor_t* cursor);
|
||||||
|
static void slist_add_node(slist_t* list, slist_node_t* node);
|
||||||
|
|
||||||
|
#if defined(NOT_USED)
|
||||||
|
static slist_node_t* slist_node_get_next(slist_node_t* curr_node);
|
||||||
|
static slist_node_t* slist_get_first(slist_t* list);
|
||||||
|
static slist_cursor_t* slist_get_cursor(slist_t* list);
|
||||||
|
#endif /*< NOT_USED */
|
||||||
|
|
||||||
|
/** End of static function declarations */
|
||||||
|
|
||||||
|
static slist_t* slist_init_ex(bool create_cursors)
|
||||||
|
{
|
||||||
|
slist_t* list;
|
||||||
|
|
||||||
|
list = (slist_t*) calloc(1, sizeof (slist_t));
|
||||||
|
list->slist_chk_top = CHK_NUM_SLIST;
|
||||||
|
list->slist_chk_tail = CHK_NUM_SLIST;
|
||||||
|
|
||||||
|
if (create_cursors)
|
||||||
|
{
|
||||||
|
list->slist_cursors_list = slist_init_ex(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static slist_node_t* slist_node_init(void* data, slist_cursor_t* cursor)
|
||||||
|
{
|
||||||
|
slist_node_t* node;
|
||||||
|
|
||||||
|
node = (slist_node_t*) calloc(1, sizeof (slist_node_t));
|
||||||
|
node->slnode_chk_top = CHK_NUM_SLIST_NODE;
|
||||||
|
node->slnode_chk_tail = CHK_NUM_SLIST_NODE;
|
||||||
|
node->slnode_data = data;
|
||||||
|
CHK_SLIST_NODE(node);
|
||||||
|
|
||||||
|
if (cursor != NULL)
|
||||||
|
{
|
||||||
|
node->slnode_cursor_refcount += 1;
|
||||||
|
cursor->slcursor_pos = node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void slist_add_node(slist_t* list, slist_node_t* node)
|
||||||
|
{
|
||||||
|
CHK_SLIST(list);
|
||||||
|
CHK_SLIST_NODE(node);
|
||||||
|
|
||||||
|
if (list->slist_tail != NULL)
|
||||||
|
{
|
||||||
|
CHK_SLIST_NODE(list->slist_tail);
|
||||||
|
CHK_SLIST_NODE(list->slist_head);
|
||||||
|
ss_dassert(list->slist_tail->slnode_next == NULL);
|
||||||
|
list->slist_tail->slnode_next = node;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
list->slist_head = node;
|
||||||
|
}
|
||||||
|
list->slist_tail = node;
|
||||||
|
node->slnode_list = list;
|
||||||
|
list->slist_nelems += 1;
|
||||||
|
CHK_SLIST(list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(NOT_USED)
|
||||||
|
|
||||||
|
static slist_node_t* slist_node_get_next(slist_node_t* curr_node)
|
||||||
|
{
|
||||||
|
CHK_SLIST_NODE(curr_node);
|
||||||
|
|
||||||
|
if (curr_node->slnode_next != NULL)
|
||||||
|
{
|
||||||
|
CHK_SLIST_NODE(curr_node->slnode_next);
|
||||||
|
return (curr_node->slnode_next);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static slist_node_t* slist_get_first(slist_t* list)
|
||||||
|
{
|
||||||
|
CHK_SLIST(list);
|
||||||
|
|
||||||
|
if (list->slist_head != NULL)
|
||||||
|
{
|
||||||
|
CHK_SLIST_NODE(list->slist_head);
|
||||||
|
return list->slist_head;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static slist_cursor_t* slist_get_cursor(slist_t* list)
|
||||||
|
{
|
||||||
|
CHK_SLIST(list);
|
||||||
|
|
||||||
|
slist_cursor_t* c;
|
||||||
|
|
||||||
|
c = slist_cursor_init(list);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
#endif /*< NOT_USED */
|
||||||
|
|
||||||
|
static slist_cursor_t* slist_cursor_init(slist_t* list)
|
||||||
|
{
|
||||||
|
CHK_SLIST(list);
|
||||||
|
slist_cursor_t* c;
|
||||||
|
|
||||||
|
c = (slist_cursor_t *) calloc(1, sizeof (slist_cursor_t));
|
||||||
|
c->slcursor_chk_top = CHK_NUM_SLIST_CURSOR;
|
||||||
|
c->slcursor_chk_tail = CHK_NUM_SLIST_CURSOR;
|
||||||
|
c->slcursor_list = list;
|
||||||
|
/** Set cursor position is list is not empty */
|
||||||
|
if (list->slist_head != NULL)
|
||||||
|
{
|
||||||
|
list->slist_head->slnode_cursor_refcount += 1;
|
||||||
|
c->slcursor_pos = list->slist_head;
|
||||||
|
}
|
||||||
|
/** Add cursor to cursor list */
|
||||||
|
slist_add_node(list->slist_cursors_list, slist_node_init(c, NULL));
|
||||||
|
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @node Create a cursor and a list with cursors supported. 19.6.2013 :
|
||||||
|
* supports only cursor per list.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param void - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @return returns a pointer to cursor, which is not positioned
|
||||||
|
* because the list is empty.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @details (write detailed description here)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
slist_cursor_t* slist_init(void)
|
||||||
|
{
|
||||||
|
slist_t* list;
|
||||||
|
slist_cursor_t* slc;
|
||||||
|
|
||||||
|
list = slist_init_ex(true);
|
||||||
|
CHK_SLIST(list);
|
||||||
|
slc = slist_cursor_init(list);
|
||||||
|
CHK_SLIST_CURSOR(slc);
|
||||||
|
|
||||||
|
return slc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @node moves cursor to the first node of list.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param c - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @return true if there is first node in the list
|
||||||
|
* false is the list is empty.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @details (write detailed description here)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool slcursor_move_to_begin(slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
bool succp = true;
|
||||||
|
slist_t* list;
|
||||||
|
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
list = c->slcursor_list;
|
||||||
|
CHK_SLIST(list);
|
||||||
|
c->slcursor_pos = list->slist_head;
|
||||||
|
if (c->slcursor_pos == NULL)
|
||||||
|
{
|
||||||
|
succp = false;
|
||||||
|
}
|
||||||
|
return succp;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @node moves cursor to next node
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param c - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @return true in success, false is there is no next node on the list.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @details (write detailed description here)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
bool slcursor_step_ahead(slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
bool succp = false;
|
||||||
|
slist_node_t* node;
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
CHK_SLIST_NODE(c->slcursor_pos);
|
||||||
|
|
||||||
|
node = c->slcursor_pos->slnode_next;
|
||||||
|
|
||||||
|
if (node != NULL)
|
||||||
|
{
|
||||||
|
CHK_SLIST_NODE(node);
|
||||||
|
c->slcursor_pos = node;
|
||||||
|
succp = true;
|
||||||
|
}
|
||||||
|
return succp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void* slcursor_get_data(slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
slist_node_t* node;
|
||||||
|
void* data = NULL;
|
||||||
|
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
node = c->slcursor_pos;
|
||||||
|
|
||||||
|
if (node != NULL)
|
||||||
|
{
|
||||||
|
CHK_SLIST_NODE(node);
|
||||||
|
data = node->slnode_data;
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @node Add data to the list by using cursor.
|
||||||
|
*
|
||||||
|
* Parameters:
|
||||||
|
* @param c - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @param data - <usage>
|
||||||
|
* <description>
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @details (write detailed description here)
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void slcursor_add_data(slist_cursor_t* c, void* data)
|
||||||
|
{
|
||||||
|
slist_t* list;
|
||||||
|
slist_node_t* pos;
|
||||||
|
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
list = c->slcursor_list;
|
||||||
|
CHK_SLIST(list);
|
||||||
|
if (c->slcursor_pos != NULL)
|
||||||
|
{
|
||||||
|
CHK_SLIST_NODE(c->slcursor_pos);
|
||||||
|
}
|
||||||
|
ss_dassert(list->slist_tail->slnode_next == NULL);
|
||||||
|
pos = slist_node_init(data, c);
|
||||||
|
slist_add_node(list, pos);
|
||||||
|
CHK_SLIST(list);
|
||||||
|
CHK_SLIST_CURSOR(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the node currently pointed by the cursor from the slist. This does not delete the data in the
|
||||||
|
* node but will delete the structure pointing to that data. This is useful when
|
||||||
|
* the user wants to free the allocated memory. After node removal, the cursor
|
||||||
|
* will point to the node before the removed node.
|
||||||
|
* @param c Cursor pointing to the data node to be removed
|
||||||
|
*/
|
||||||
|
void slcursor_remove_data(slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
slist_node_t* node = c->slcursor_pos;
|
||||||
|
int havemore = slist_size(c);
|
||||||
|
slcursor_move_to_begin(c);
|
||||||
|
|
||||||
|
if (node == c->slcursor_pos)
|
||||||
|
{
|
||||||
|
c->slcursor_list->slist_head = c->slcursor_list->slist_head->slnode_next;
|
||||||
|
slcursor_move_to_begin(c);
|
||||||
|
atomic_add((int*) &node->slnode_list->slist_nelems, -1);
|
||||||
|
atomic_add((int*) &node->slnode_cursor_refcount, -1);
|
||||||
|
if (node->slnode_cursor_refcount == 0)
|
||||||
|
{
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (havemore)
|
||||||
|
{
|
||||||
|
if (c->slcursor_pos->slnode_next == node)
|
||||||
|
{
|
||||||
|
c->slcursor_pos->slnode_next = node->slnode_next;
|
||||||
|
atomic_add((int*) &node->slnode_list->slist_nelems, -1);
|
||||||
|
atomic_add((int*) &node->slnode_cursor_refcount, -1);
|
||||||
|
if (node->slnode_cursor_refcount == 0)
|
||||||
|
{
|
||||||
|
free(node);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
havemore = slcursor_step_ahead(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the size of the slist.
|
||||||
|
* @param c slist cursor which refers to a list
|
||||||
|
* @return nummber of elements in the list
|
||||||
|
*/
|
||||||
|
size_t slist_size(slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
return c->slcursor_list->slist_nelems;
|
||||||
|
}
|
||||||
|
|
||||||
|
void slist_done(slist_cursor_t* c)
|
||||||
|
{
|
||||||
|
bool succp;
|
||||||
|
void* data;
|
||||||
|
|
||||||
|
succp = slcursor_move_to_begin(c);
|
||||||
|
|
||||||
|
while (succp)
|
||||||
|
{
|
||||||
|
data = slcursor_get_data(c);
|
||||||
|
free(data);
|
||||||
|
succp = slcursor_step_ahead(c);
|
||||||
|
}
|
||||||
|
free(c->slcursor_list);
|
||||||
|
free(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** End of list implementation */
|
||||||
|
|
||||||
71
server/include/slist.h
Normal file
71
server/include/slist.h
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef _SLIST_H
|
||||||
|
#define _SLIST_H
|
||||||
|
/*
|
||||||
|
* This file is distributed as part of the MariaDB Corporation MaxScale. It is free
|
||||||
|
* software: you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation,
|
||||||
|
* version 2.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||||
|
* details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with
|
||||||
|
* this program; if not, write to the Free Software Foundation, Inc., 51
|
||||||
|
* Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Copyright MariaDB Corporation Ab 2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <skygw_utils.h>
|
||||||
|
|
||||||
|
EXTERN_C_BLOCK_BEGIN
|
||||||
|
|
||||||
|
typedef struct slist_node_st slist_node_t;
|
||||||
|
typedef struct slist_st slist_t;
|
||||||
|
typedef struct slist_cursor_st slist_cursor_t;
|
||||||
|
|
||||||
|
/** Single-linked list */
|
||||||
|
|
||||||
|
struct slist_node_st
|
||||||
|
{
|
||||||
|
skygw_chk_t slnode_chk_top;
|
||||||
|
slist_t* slnode_list;
|
||||||
|
slist_node_t* slnode_next;
|
||||||
|
void* slnode_data;
|
||||||
|
size_t slnode_cursor_refcount;
|
||||||
|
skygw_chk_t slnode_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slist_st
|
||||||
|
{
|
||||||
|
skygw_chk_t slist_chk_top;
|
||||||
|
slist_node_t* slist_head;
|
||||||
|
slist_node_t* slist_tail;
|
||||||
|
int slist_nelems;
|
||||||
|
slist_t* slist_cursors_list;
|
||||||
|
skygw_chk_t slist_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct slist_cursor_st
|
||||||
|
{
|
||||||
|
skygw_chk_t slcursor_chk_top;
|
||||||
|
slist_t* slcursor_list;
|
||||||
|
slist_node_t* slcursor_pos;
|
||||||
|
skygw_chk_t slcursor_chk_tail;
|
||||||
|
};
|
||||||
|
|
||||||
|
slist_cursor_t* slist_init(void);
|
||||||
|
void slist_done(slist_cursor_t* c);
|
||||||
|
size_t slist_size(slist_cursor_t* c);
|
||||||
|
|
||||||
|
void slcursor_add_data(slist_cursor_t* c, void* data);
|
||||||
|
void* slcursor_get_data(slist_cursor_t* c);
|
||||||
|
void slcursor_remove_data(slist_cursor_t* c);
|
||||||
|
bool slcursor_move_to_begin(slist_cursor_t* c);
|
||||||
|
bool slcursor_step_ahead(slist_cursor_t* c);
|
||||||
|
|
||||||
|
EXTERN_C_BLOCK_END
|
||||||
|
|
||||||
|
#endif
|
||||||
@ -46,17 +46,6 @@ static mlist_node_t* mlist_node_init(void* data, mlist_cursor_t* cursor);
|
|||||||
|
|
||||||
#endif /* MLIST */
|
#endif /* MLIST */
|
||||||
|
|
||||||
static slist_cursor_t* slist_cursor_init(slist_t* list);
|
|
||||||
static slist_t* slist_init_ex(bool create_cursors);
|
|
||||||
static slist_node_t* slist_node_init(void* data, slist_cursor_t* cursor);
|
|
||||||
static void slist_add_node(slist_t* list, slist_node_t* node);
|
|
||||||
|
|
||||||
#if defined(NOT_USED)
|
|
||||||
static slist_node_t* slist_node_get_next(slist_node_t* curr_node);
|
|
||||||
static slist_node_t* slist_get_first(slist_t* list);
|
|
||||||
static slist_cursor_t* slist_get_cursor(slist_t* list);
|
|
||||||
#endif /*< NOT_USED */
|
|
||||||
|
|
||||||
static bool file_write_header(skygw_file_t* file);
|
static bool file_write_header(skygw_file_t* file);
|
||||||
static void simple_mutex_free_memory(simple_mutex_t* sm);
|
static void simple_mutex_free_memory(simple_mutex_t* sm);
|
||||||
static void mlist_free_memory(mlist_t* ml, char* name);
|
static void mlist_free_memory(mlist_t* ml, char* name);
|
||||||
@ -671,337 +660,6 @@ retblock:
|
|||||||
return rval;
|
return rval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static slist_t* slist_init_ex(bool create_cursors)
|
|
||||||
{
|
|
||||||
slist_t* list;
|
|
||||||
|
|
||||||
list = (slist_t*) calloc(1, sizeof (slist_t));
|
|
||||||
list->slist_chk_top = CHK_NUM_SLIST;
|
|
||||||
list->slist_chk_tail = CHK_NUM_SLIST;
|
|
||||||
|
|
||||||
if (create_cursors)
|
|
||||||
{
|
|
||||||
list->slist_cursors_list = slist_init_ex(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
static slist_node_t* slist_node_init(void* data, slist_cursor_t* cursor)
|
|
||||||
{
|
|
||||||
slist_node_t* node;
|
|
||||||
|
|
||||||
node = (slist_node_t*) calloc(1, sizeof (slist_node_t));
|
|
||||||
node->slnode_chk_top = CHK_NUM_SLIST_NODE;
|
|
||||||
node->slnode_chk_tail = CHK_NUM_SLIST_NODE;
|
|
||||||
node->slnode_data = data;
|
|
||||||
CHK_SLIST_NODE(node);
|
|
||||||
|
|
||||||
if (cursor != NULL)
|
|
||||||
{
|
|
||||||
node->slnode_cursor_refcount += 1;
|
|
||||||
cursor->slcursor_pos = node;
|
|
||||||
}
|
|
||||||
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void slist_add_node(slist_t* list, slist_node_t* node)
|
|
||||||
{
|
|
||||||
CHK_SLIST(list);
|
|
||||||
CHK_SLIST_NODE(node);
|
|
||||||
|
|
||||||
if (list->slist_tail != NULL)
|
|
||||||
{
|
|
||||||
CHK_SLIST_NODE(list->slist_tail);
|
|
||||||
CHK_SLIST_NODE(list->slist_head);
|
|
||||||
ss_dassert(list->slist_tail->slnode_next == NULL);
|
|
||||||
list->slist_tail->slnode_next = node;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
list->slist_head = node;
|
|
||||||
}
|
|
||||||
list->slist_tail = node;
|
|
||||||
node->slnode_list = list;
|
|
||||||
list->slist_nelems += 1;
|
|
||||||
CHK_SLIST(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(NOT_USED)
|
|
||||||
|
|
||||||
static slist_node_t* slist_node_get_next(slist_node_t* curr_node)
|
|
||||||
{
|
|
||||||
CHK_SLIST_NODE(curr_node);
|
|
||||||
|
|
||||||
if (curr_node->slnode_next != NULL)
|
|
||||||
{
|
|
||||||
CHK_SLIST_NODE(curr_node->slnode_next);
|
|
||||||
return (curr_node->slnode_next);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static slist_node_t* slist_get_first(slist_t* list)
|
|
||||||
{
|
|
||||||
CHK_SLIST(list);
|
|
||||||
|
|
||||||
if (list->slist_head != NULL)
|
|
||||||
{
|
|
||||||
CHK_SLIST_NODE(list->slist_head);
|
|
||||||
return list->slist_head;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static slist_cursor_t* slist_get_cursor(slist_t* list)
|
|
||||||
{
|
|
||||||
CHK_SLIST(list);
|
|
||||||
|
|
||||||
slist_cursor_t* c;
|
|
||||||
|
|
||||||
c = slist_cursor_init(list);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
#endif /*< NOT_USED */
|
|
||||||
|
|
||||||
static slist_cursor_t* slist_cursor_init(slist_t* list)
|
|
||||||
{
|
|
||||||
CHK_SLIST(list);
|
|
||||||
slist_cursor_t* c;
|
|
||||||
|
|
||||||
c = (slist_cursor_t *) calloc(1, sizeof (slist_cursor_t));
|
|
||||||
c->slcursor_chk_top = CHK_NUM_SLIST_CURSOR;
|
|
||||||
c->slcursor_chk_tail = CHK_NUM_SLIST_CURSOR;
|
|
||||||
c->slcursor_list = list;
|
|
||||||
/** Set cursor position is list is not empty */
|
|
||||||
if (list->slist_head != NULL)
|
|
||||||
{
|
|
||||||
list->slist_head->slnode_cursor_refcount += 1;
|
|
||||||
c->slcursor_pos = list->slist_head;
|
|
||||||
}
|
|
||||||
/** Add cursor to cursor list */
|
|
||||||
slist_add_node(list->slist_cursors_list, slist_node_init(c, NULL));
|
|
||||||
|
|
||||||
CHK_SLIST_CURSOR(c);
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @node Create a cursor and a list with cursors supported. 19.6.2013 :
|
|
||||||
* supports only cursor per list.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* @param void - <usage>
|
|
||||||
* <description>
|
|
||||||
*
|
|
||||||
* @return returns a pointer to cursor, which is not positioned
|
|
||||||
* because the list is empty.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @details (write detailed description here)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
slist_cursor_t* slist_init(void)
|
|
||||||
{
|
|
||||||
slist_t* list;
|
|
||||||
slist_cursor_t* slc;
|
|
||||||
|
|
||||||
list = slist_init_ex(true);
|
|
||||||
CHK_SLIST(list);
|
|
||||||
slc = slist_cursor_init(list);
|
|
||||||
CHK_SLIST_CURSOR(slc);
|
|
||||||
|
|
||||||
return slc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @node moves cursor to the first node of list.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* @param c - <usage>
|
|
||||||
* <description>
|
|
||||||
*
|
|
||||||
* @return true if there is first node in the list
|
|
||||||
* false is the list is empty.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @details (write detailed description here)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool slcursor_move_to_begin(slist_cursor_t* c)
|
|
||||||
{
|
|
||||||
bool succp = true;
|
|
||||||
slist_t* list;
|
|
||||||
|
|
||||||
CHK_SLIST_CURSOR(c);
|
|
||||||
list = c->slcursor_list;
|
|
||||||
CHK_SLIST(list);
|
|
||||||
c->slcursor_pos = list->slist_head;
|
|
||||||
if (c->slcursor_pos == NULL)
|
|
||||||
{
|
|
||||||
succp = false;
|
|
||||||
}
|
|
||||||
return succp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @node moves cursor to next node
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* @param c - <usage>
|
|
||||||
* <description>
|
|
||||||
*
|
|
||||||
* @return true in success, false is there is no next node on the list.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @details (write detailed description here)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
bool slcursor_step_ahead(slist_cursor_t* c)
|
|
||||||
{
|
|
||||||
bool succp = false;
|
|
||||||
slist_node_t* node;
|
|
||||||
CHK_SLIST_CURSOR(c);
|
|
||||||
CHK_SLIST_NODE(c->slcursor_pos);
|
|
||||||
|
|
||||||
node = c->slcursor_pos->slnode_next;
|
|
||||||
|
|
||||||
if (node != NULL)
|
|
||||||
{
|
|
||||||
CHK_SLIST_NODE(node);
|
|
||||||
c->slcursor_pos = node;
|
|
||||||
succp = true;
|
|
||||||
}
|
|
||||||
return succp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* slcursor_get_data(slist_cursor_t* c)
|
|
||||||
{
|
|
||||||
slist_node_t* node;
|
|
||||||
void* data = NULL;
|
|
||||||
|
|
||||||
CHK_SLIST_CURSOR(c);
|
|
||||||
node = c->slcursor_pos;
|
|
||||||
|
|
||||||
if (node != NULL)
|
|
||||||
{
|
|
||||||
CHK_SLIST_NODE(node);
|
|
||||||
data = node->slnode_data;
|
|
||||||
}
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @node Add data to the list by using cursor.
|
|
||||||
*
|
|
||||||
* Parameters:
|
|
||||||
* @param c - <usage>
|
|
||||||
* <description>
|
|
||||||
*
|
|
||||||
* @param data - <usage>
|
|
||||||
* <description>
|
|
||||||
*
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* @details (write detailed description here)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
void slcursor_add_data(slist_cursor_t* c, void* data)
|
|
||||||
{
|
|
||||||
slist_t* list;
|
|
||||||
slist_node_t* pos;
|
|
||||||
|
|
||||||
CHK_SLIST_CURSOR(c);
|
|
||||||
list = c->slcursor_list;
|
|
||||||
CHK_SLIST(list);
|
|
||||||
if (c->slcursor_pos != NULL)
|
|
||||||
{
|
|
||||||
CHK_SLIST_NODE(c->slcursor_pos);
|
|
||||||
}
|
|
||||||
ss_dassert(list->slist_tail->slnode_next == NULL);
|
|
||||||
pos = slist_node_init(data, c);
|
|
||||||
slist_add_node(list, pos);
|
|
||||||
CHK_SLIST(list);
|
|
||||||
CHK_SLIST_CURSOR(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove the node currently pointed by the cursor from the slist. This does not delete the data in the
|
|
||||||
* node but will delete the structure pointing to that data. This is useful when
|
|
||||||
* the user wants to free the allocated memory. After node removal, the cursor
|
|
||||||
* will point to the node before the removed node.
|
|
||||||
* @param c Cursor pointing to the data node to be removed
|
|
||||||
*/
|
|
||||||
void slcursor_remove_data(slist_cursor_t* c)
|
|
||||||
{
|
|
||||||
slist_node_t* node = c->slcursor_pos;
|
|
||||||
int havemore = slist_size(c);
|
|
||||||
slcursor_move_to_begin(c);
|
|
||||||
|
|
||||||
if (node == c->slcursor_pos)
|
|
||||||
{
|
|
||||||
c->slcursor_list->slist_head = c->slcursor_list->slist_head->slnode_next;
|
|
||||||
slcursor_move_to_begin(c);
|
|
||||||
atomic_add((int*) &node->slnode_list->slist_nelems, -1);
|
|
||||||
atomic_add((int*) &node->slnode_cursor_refcount, -1);
|
|
||||||
if (node->slnode_cursor_refcount == 0)
|
|
||||||
{
|
|
||||||
free(node);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (havemore)
|
|
||||||
{
|
|
||||||
if (c->slcursor_pos->slnode_next == node)
|
|
||||||
{
|
|
||||||
c->slcursor_pos->slnode_next = node->slnode_next;
|
|
||||||
atomic_add((int*) &node->slnode_list->slist_nelems, -1);
|
|
||||||
atomic_add((int*) &node->slnode_cursor_refcount, -1);
|
|
||||||
if (node->slnode_cursor_refcount == 0)
|
|
||||||
{
|
|
||||||
free(node);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
havemore = slcursor_step_ahead(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the size of the slist.
|
|
||||||
* @param c slist cursor which refers to a list
|
|
||||||
* @return nummber of elements in the list
|
|
||||||
*/
|
|
||||||
size_t slist_size(slist_cursor_t* c)
|
|
||||||
{
|
|
||||||
return c->slcursor_list->slist_nelems;
|
|
||||||
}
|
|
||||||
|
|
||||||
void slist_done(slist_cursor_t* c)
|
|
||||||
{
|
|
||||||
bool succp;
|
|
||||||
void* data;
|
|
||||||
|
|
||||||
succp = slcursor_move_to_begin(c);
|
|
||||||
|
|
||||||
while (succp)
|
|
||||||
{
|
|
||||||
data = slcursor_get_data(c);
|
|
||||||
free(data);
|
|
||||||
succp = slcursor_step_ahead(c);
|
|
||||||
}
|
|
||||||
free(c->slcursor_list);
|
|
||||||
free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** End of list implementation */
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @node Initialize thread data structure
|
* @node Initialize thread data structure
|
||||||
*
|
*
|
||||||
|
|||||||
@ -22,9 +22,6 @@
|
|||||||
|
|
||||||
#define DISKWRITE_LATENCY (5*MSEC_USEC)
|
#define DISKWRITE_LATENCY (5*MSEC_USEC)
|
||||||
|
|
||||||
typedef struct slist_node_st slist_node_t;
|
|
||||||
typedef struct slist_st slist_t;
|
|
||||||
typedef struct slist_cursor_st slist_cursor_t;
|
|
||||||
typedef struct mlist_node_st mlist_node_t;
|
typedef struct mlist_node_st mlist_node_t;
|
||||||
typedef struct skygw_file_st skygw_file_t;
|
typedef struct skygw_file_st skygw_file_t;
|
||||||
typedef struct skygw_thread_st skygw_thread_t;
|
typedef struct skygw_thread_st skygw_thread_t;
|
||||||
@ -97,33 +94,6 @@ static const char* timestamp_formatstr_hp = "%04d-%02d-%02d %02d:%02d:%02d.%03d
|
|||||||
/** One for terminating '\0' */
|
/** One for terminating '\0' */
|
||||||
static const size_t timestamp_len_hp = (4+1 +2+1 +2+1 +2+1 +2+1 +2+1+3+3 +1) * sizeof(char);
|
static const size_t timestamp_len_hp = (4+1 +2+1 +2+1 +2+1 +2+1 +2+1+3+3 +1) * sizeof(char);
|
||||||
|
|
||||||
/** Single-linked list for storing test cases */
|
|
||||||
|
|
||||||
struct slist_node_st {
|
|
||||||
skygw_chk_t slnode_chk_top;
|
|
||||||
slist_t* slnode_list;
|
|
||||||
slist_node_t* slnode_next;
|
|
||||||
void* slnode_data;
|
|
||||||
size_t slnode_cursor_refcount;
|
|
||||||
skygw_chk_t slnode_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct slist_st {
|
|
||||||
skygw_chk_t slist_chk_top;
|
|
||||||
slist_node_t* slist_head;
|
|
||||||
slist_node_t* slist_tail;
|
|
||||||
int slist_nelems;
|
|
||||||
slist_t* slist_cursors_list;
|
|
||||||
skygw_chk_t slist_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct slist_cursor_st {
|
|
||||||
skygw_chk_t slcursor_chk_top;
|
|
||||||
slist_t* slcursor_list;
|
|
||||||
slist_node_t* slcursor_pos;
|
|
||||||
skygw_chk_t slcursor_chk_tail;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct skygw_thread_st {
|
struct skygw_thread_st {
|
||||||
skygw_chk_t sth_chk_top;
|
skygw_chk_t sth_chk_top;
|
||||||
bool sth_must_exit;
|
bool sth_must_exit;
|
||||||
@ -160,15 +130,6 @@ EXTERN_C_BLOCK_BEGIN
|
|||||||
|
|
||||||
bool utils_init(); /*< Call this first before using any other function */
|
bool utils_init(); /*< Call this first before using any other function */
|
||||||
void utils_end();
|
void utils_end();
|
||||||
slist_cursor_t* slist_init(void);
|
|
||||||
void slist_done(slist_cursor_t* c);
|
|
||||||
size_t slist_size(slist_cursor_t* c);
|
|
||||||
void slcursor_add_data(slist_cursor_t* c, void* data);
|
|
||||||
void slcursor_remove_data(slist_cursor_t* c);
|
|
||||||
void* slcursor_get_data(slist_cursor_t* c);
|
|
||||||
|
|
||||||
bool slcursor_move_to_begin(slist_cursor_t* c);
|
|
||||||
bool slcursor_step_ahead(slist_cursor_t* c);
|
|
||||||
|
|
||||||
EXTERN_C_BLOCK_END
|
EXTERN_C_BLOCK_END
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user