Remove listmanager

The file wasn't used, so any traces of listmanager.h or .c have been
erased.
This commit is contained in:
Esa Korhonen 2017-01-25 14:57:02 +02:00
parent 7d51864402
commit aa8851fbe1
5 changed files with 0 additions and 581 deletions

View File

@ -1,120 +0,0 @@
#pragma once
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
*
* Change Date: 2019-07-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
/**
* @file listmanager.h The List Manager header file
*
*
* @verbatim
* Revision History
*
* Date Who Description
* 20/04/2016 Martin Brampton Initial implementation
*
* @endverbatim
*/
#include <maxscale/cdefs.h>
#include <maxscale/spinlock.h>
#include <maxscale/debug.h>
MXS_BEGIN_DECLS
struct dcb;
/*
* The possible types of list that could be supported. At present, only
* LIST_TYPE_RECYCLABLE is fully tested.
*/
typedef enum
{
LIST_TYPE_SIMPLE, /* A simple linked list with pointer to last entry */
LIST_TYPE_RECYCLABLE, /* A simple linked list, entries are recycled */
LIST_TYPE_DOUBLE, /* A doubly linked list, next and previous */
} list_type_t;
/*
* The list entry structure
*
* Each list entry must have this format, but will typically be extended
* well beyond these items. The "previous" field is only required for
* a doubly linked list, LIST_TYPE_DOUBLE.
*
* The first data to be used with the list manager is the DCB. Note that
* the first few fields in the DCB structure correspond exactly to the
* fields in the list entry structure. The pointers used need to be cast
* as appropriate in order to be able to use the same data as either a DCB
* or a list entry.
*
*/
#define LIST_ENTRY_FIELDS \
skygw_chk_t list_entry_chk_top; \
struct list_entry *next; \
struct list_entry *previous; \
bool entry_is_in_use; \
bool entry_is_ready; \
skygw_chk_t list_entry_chk_tail;
typedef struct list_entry
{
LIST_ENTRY_FIELDS
} list_entry_t;
/*
* The list configuration structure
*
* This provides the basis for a list. It can be declared and initialised
* statically, for example in server/core/dcb.c. It includes an anchor
* pointer for the list, a pointer to the last entry in the list and the
* last entry that was found to be free and reused.
*
* The count tells us the current number of entries in live use, and maximum
* is the highest number ever observed in live use. The freecount is the
* number of entries currently free and ready for reuse. The entry_size is
* the actual size of the real entries, e.g. the DCB structure (NOT the size
* of the list entry structure).
*
* A spinlock is declared for use during list manipulation operations.
*/
typedef struct
{
list_type_t list_type;
size_t entry_size;
SPINLOCK list_lock;
list_entry_t *all_entries;
list_entry_t *last_entry;
list_entry_t *last_free;
int count;
int maximum;
int freecount;
int num_malloc;
} LIST_CONFIG;
void list_initialise(LIST_CONFIG *list_config, list_type_t type_of_list, size_t entry_size);
bool list_pre_alloc(LIST_CONFIG *list_config, int num_entries, void (*init_struct)(void *));
list_entry_t *list_find_free(LIST_CONFIG *list_config, void (*init_struct)(void *));
void dprintListStats(struct dcb *pdcb, LIST_CONFIG *list_config, const char *listname);
void list_free_entry (LIST_CONFIG *list_config, list_entry_t *to_be_freed);
list_entry_t *list_start_iteration(LIST_CONFIG *list_config);
list_entry_t *list_iterate(LIST_CONFIG *list_config, list_entry_t *current_entry);
void list_terminate_iteration_early(LIST_CONFIG *list_config, list_entry_t *current_entry);
bool list_is_entry_in_use(LIST_CONFIG *list_config, list_entry_t *to_be_found);
void list_add_to_end(LIST_CONFIG *list_config, list_entry_t *new_entry);
void list_map(LIST_CONFIG *list_config, bool (*callback)(void *, ...));
/* The following UNTESTED! */
list_entry_t *list_remove_first(LIST_CONFIG *list_config);
list_entry_t *list_remove_last(LIST_CONFIG *list_config);
MXS_END_DECLS

View File

@ -379,8 +379,6 @@ void
dcb_free_all_memory(DCB *dcb)
{
DCB_CALLBACK *cb_dcb;
// TODO: Uncomment once listmanager code is in use
//ss_dassert(dcb->entry_is_in_use);
if (dcb->protocol && (!DCB_IS_CLONE(dcb)))
{
@ -1842,12 +1840,6 @@ void printAllDCBs()
void
dprintOneDCB(DCB *pdcb, DCB *dcb)
{
/* TODO: Uncomment once listmanager code is in use
if (false == dcb->entry_is_in_use)
{
return;
}
*/
dcb_printf(pdcb, "DCB: %p\n", (void *)dcb);
dcb_printf(pdcb, "\tDCB state: %s\n",
gw_dcb_state2string(dcb->state));

View File

@ -1,451 +0,0 @@
/*
* Copyright (c) 2016 MariaDB Corporation Ab
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file and at www.mariadb.com/bsl.
*
* Change Date: 2019-07-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2 or later of the General
* Public License.
*/
/**
* @file listmanager.c - Logic for list handling
*
* MaxScale contains a number of linked lists. This code attempts to provide
* standard functions for handling them. Initially, the main work has been
* on recyclable lists - lists of entries that use dynamically allocated
* memory but are reused rather than freed. Some functions are not fully
* tested - see comments.
*
* @verbatim
* Revision History
*
* Date Who Description
* 20/04/16 Martin Brampton Initial implementation
*
* @endverbatim
*/
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <maxscale/listmanager.h>
#include <maxscale/spinlock.h>
#include <maxscale/dcb.h>
#include <maxscale/log_manager.h>
#include <maxscale/alloc.h>
/**
* Initialise a list configuration.
*
* @param list_config Pointer to the configuration of the list to be initialised
* @param type_of_list Type of list to be initialised.
* @param entry_size The size of each list entry (typically from sizeof).
*
* @note This is only required if a list is configured at execution time
* rather than being declared and statically initialized.
*/
void
list_initialise(LIST_CONFIG *list_config, list_type_t type_of_list, size_t entry_size)
{
list_config->list_type = type_of_list;
list_config->all_entries = NULL;
list_config->last_entry = NULL;
list_config->last_free = NULL;
list_config->count = 0;
list_config->maximum = 0;
list_config->freecount = 0;
list_config->num_malloc = 0;
list_config->entry_size = entry_size;
spinlock_init(&list_config->list_lock);
}
/**
* Allocate memory for some initial list entries
*
* The caller must check the return value. If it is false, this most likely
* indicates a memory allocation failure, and the caller should act
* accordingly. (It could indicate that the requested number of entries
* was less than 1, but this is fairly unlikely).
*
* @param list_config Pointer to the configuration of the list to be initialised
* @param num_entries Number of list entries to be allocated
* @return true if memory was allocated, false if not (or num_entries < 1)
*
*/
bool
list_pre_alloc(LIST_CONFIG *list_config, int num_entries, void (*init_struct)(void *))
{
uint8_t *entry_space;
bool result;
spinlock_acquire(&list_config->list_lock);
if (num_entries <= 0)
{
MXS_ERROR("Attempt to preallocate space for recyclable list asked for no entries");
result = false;
}
else if ((entry_space = (uint8_t *)MXS_CALLOC(num_entries, list_config->entry_size)) == NULL)
{
result = false;
}
else
{
list_entry_t *first_new_entry = (list_entry_t *)entry_space;
list_entry_t *previous = first_new_entry;
for (int i = 1; i <= num_entries; i++)
{
if (init_struct)
{
init_struct((void *)previous);
}
previous->list_entry_chk_top = CHK_NUM_MANAGED_LIST;
previous->list_entry_chk_tail = CHK_NUM_MANAGED_LIST;
list_entry_t *next_entry = (list_entry_t *)((uint8_t *)previous + list_config->entry_size);
if (i < num_entries)
{
previous->next = next_entry;
previous = next_entry;
}
else
{
previous->next = NULL;
}
}
list_config->freecount += num_entries;
list_add_to_end(list_config, first_new_entry);
list_config->last_entry = previous;
list_config->last_free = first_new_entry;
result = true;
}
spinlock_release(&list_config->list_lock);
return result;
}
/**
* @brief Find a free list entry or allocate memory for a new one.
*
* This routine looks to see whether there are free entries.
* If not, new memory is allocated, if possible, and the new entry is added to
* the list of all entries.
*
* @param Pointer to the list configuration structure
* @return An available entry or NULL if none could be found or created.
*/
list_entry_t *
list_find_free(LIST_CONFIG *list_config, void (*init_struct)(void *))
{
list_entry_t *available_entry;
spinlock_acquire(&list_config->list_lock);
if (list_config->freecount <= 0)
{
/* No free entries, need to allocate a new one */
if ((available_entry = MXS_CALLOC(1, list_config->entry_size)) == NULL)
{
spinlock_release(&list_config->list_lock);
return NULL;
}
list_config->num_malloc++;
if (init_struct)
{
init_struct((void *)available_entry);
}
available_entry->list_entry_chk_top = CHK_NUM_MANAGED_LIST;
available_entry->list_entry_chk_tail = CHK_NUM_MANAGED_LIST;
available_entry->next = NULL;
list_add_to_end(list_config, available_entry);
}
/* Starting at the last place a free DCB was found, loop through the */
/* list of DCBs searching for one that is not in use. */
else
{
list_entry_t *next_in_list;
int loopcount = 0;
while (list_config->last_free->entry_is_in_use)
{
list_config->last_free = list_config->last_free->next;
if (NULL == list_config->last_free)
{
loopcount++;
ss_dassert(loopcount == 1);
if (loopcount > 1)
{
/* Shouldn't need to loop round more than once */
MXS_ERROR("Find free list entry failed to find when count positive");
spinlock_release(&list_config->list_lock);
return NULL;
}
list_config->last_free = list_config->all_entries;
}
}
list_config->freecount--;
available_entry = list_config->last_free;
/* Clear the old data, then reset the list forward link */
next_in_list = available_entry->next;
if (init_struct)
{
init_struct((void *)available_entry);
}
else
{
memset(available_entry, 0, list_config->entry_size);
}
available_entry->list_entry_chk_top = CHK_NUM_MANAGED_LIST;
available_entry->list_entry_chk_tail = CHK_NUM_MANAGED_LIST;
available_entry->next = next_in_list;
}
list_config->count++;
if (list_config->count > list_config->maximum)
{
list_config->maximum = list_config->count;
}
available_entry->entry_is_in_use = true;
spinlock_release(&list_config->list_lock);
return available_entry;
}
/**
* @brief Display information about a recyclable list
*
* Should be called from a module that handles one specific list, passing
* the name for the list as well as the print DCB and the list config.
*
* @param Pointer to the print DCB
* @param List configuration pointer, the list to be displayed
* @param Name for the list
*/
void
dprintListStats(DCB *pdcb, LIST_CONFIG *list_config, const char *listname)
{
dcb_printf(pdcb, "Recyclable list statistics\n");
dcb_printf(pdcb, "--------------------------\n");
dcb_printf(pdcb, "Name of list: %s\n", listname);
dcb_printf(pdcb, "Size of entries: %zu\n", list_config->entry_size);
dcb_printf(pdcb, "Currently in use: %d\n", list_config->count);
dcb_printf(pdcb, "Maximum ever used at once: %d\n", list_config->maximum);
dcb_printf(pdcb, "Currently free for reuse: %d\n", list_config->freecount);
dcb_printf(pdcb, "Total in use + free: %d\n",
list_config->freecount + list_config->count);
dcb_printf(pdcb, "Number of memory allocations: %d\n", list_config->num_malloc);
}
/**
* @brief Dispose of a list entry by making it available for reuse.
*
* Within spinlock control, the entry is marked not in use and the
* counts are adjusted.
*
* @param Pointer to the list configuration structure
* @param List entry pointer, the item to be "freed"
*/
void
list_free_entry(LIST_CONFIG *list_config, list_entry_t *to_be_freed)
{
spinlock_acquire(&list_config->list_lock);
to_be_freed->entry_is_in_use = false;
list_config->freecount++;
list_config->count--;
spinlock_release(&list_config->list_lock);
}
/**
* @brief Find out whether a pointer points to a valid list entry
*
* Search the list for the given entry, under spinlock control.
*
* @param Pointer to the list configuration structure
* @param Pointer to be searched for
* @return True if the pointer is in the list and it is in use
*/
bool
list_is_entry_in_use(LIST_CONFIG *list_config, list_entry_t *to_be_found)
{
list_entry_t *entry;
spinlock_acquire(&list_config->list_lock);
entry = list_config->all_entries;
while (entry && to_be_found != entry)
{
entry = entry->next;
}
spinlock_release(&list_config->list_lock);
return (entry && entry->entry_is_in_use);
}
/**
* @brief Invoke a callback for every active member of list
*
* The list is locked, list entries that are in use are successively
* submitted to the callback function. The list entry is supplied to the
* callback function as the first parameters, followed by whatever other
* parameters have been passed to list_map. The process will continue so
* long as the callback function returns true, and will terminate either
* at the end of the list or when the callback function returns false.
*
* Code to be developed.
*
* @param Pointer to the list configuration structure
* @param Pointer to the callback function
*/
void
list_map(LIST_CONFIG *list_config, bool (*callback)(void *, ...))
{
}
/**
* @brief Start to iterate over a list
*
* The list is locked, and the first entry returned to the caller
*
* @param Pointer to the list configuration structure
* @return Pointer to the first entry in the list
*/
list_entry_t *
list_start_iteration(LIST_CONFIG *list_config)
{
spinlock_acquire(&list_config->list_lock);
return list_config->all_entries;
}
/**
* @brief Iterate over a list from a given point
*
* The list is assumed locked through list_start_iteration having been
* called. The next entry that is currently in use is returned to the caller.
* If the end of the list is reached, the spinlock is freed.
*
* @param Pointer to the list configuration structure
* @param Pointer to the entry to move forward from
* @return The next item in the list, or NULL if reached the end
*/
list_entry_t *
list_iterate(LIST_CONFIG *list_config, list_entry_t *current_entry)
{
list_entry_t *next_entry = current_entry->next;
while (next_entry && !(next_entry->entry_is_in_use && next_entry->entry_is_ready))
{
next_entry = next_entry->next;
}
if (NULL == next_entry)
{
spinlock_release(&list_config->list_lock);
}
return next_entry;
}
/**
* @brief Terminate list iteration before reaching the end
*
* The list is assumed locked through list_start_iteration having been
* called, unless the last item is NULL, in which case it is assumed that
* the iteration had already reached the end of the list. If this is not
* the case, then the spinlock is released.
*
* @param Pointer to the list configuration structure
* @param Pointer to the entry last reached in the iteration
*/
void
list_terminate_iteration_early(LIST_CONFIG *list_config, list_entry_t *current_entry)
{
if (current_entry)
{
spinlock_release(&list_config->list_lock);
}
}
/**
* Add a new item to the end of a list.
*
* Must be called with the list lock held.
*
* A pointer, last_entry, is held to find the end of the list, and the new entry
* is linked to the end of the list. The pointer, last_free, that is used to
* search for a free entry is initialised if not already set. There cannot be
* any free entries until this routine has been called at least once.
*
* @param list_config The configuration of the list.
* @param new_entry The new entry to be added to the end of the list
*
* @note UNTESTED for simple or doubly linked lists, currently used
* internally for recyclable lists.
*/
void
list_add_to_end(LIST_CONFIG *list_config, list_entry_t *new_entry)
{
if (NULL == list_config->all_entries)
{
list_config->all_entries = new_entry;
if (LIST_TYPE_DOUBLE == list_config->list_type)
{
new_entry->previous = NULL;
}
}
else
{
list_config->last_entry->next = new_entry;
if (LIST_TYPE_DOUBLE == list_config->list_type)
{
new_entry->previous = list_config->last_entry;
}
}
list_config->last_entry = new_entry;
if (NULL == list_config->last_free)
{
list_config->last_free = new_entry;
}
}
/**
* @brief the list entry removed from the start of the list
*
* Must be called with the list lock held.
*
* @return The first list entry or NULL if the list is empty.
*
* @note UNTESTED! Intended for use on simple or doubly linked lists.
*/
list_entry_t *
list_remove_first(LIST_CONFIG *list_config)
{
list_entry_t *first_in_list = NULL;
if (list_config->all_entries)
{
first_in_list = list_config->all_entries;
list_config->all_entries = first_in_list->next;
}
return first_in_list;
}
/**
* @brief Return the list entry removed from the end of the list
*
* Must be called with the list lock held.
*
* @return The last list entry or NULL if the list is empty.
*
* @note UNTESTED! Intended for use only with doubly linked lists.
*/
list_entry_t *
list_remove_last(LIST_CONFIG *list_config)
{
list_entry_t *last_in_list = NULL;
if (list_config->list_type != LIST_TYPE_DOUBLE)
{
MXS_ERROR("Attempt to remove the last entry in a list that is not doubly linked");
return NULL;
}
if (list_config->all_entries)
{
last_in_list = list_config->last_entry;
list_config->last_entry = last_in_list->previous;
}
return last_in_list;
}

View File

@ -60,7 +60,6 @@
#include <maxscale/protocol/mysql.h>
#include <maxscale/housekeeper.h>
#include <maxscale/alloc.h>
#include <maxscale/listmanager.h>
#define MYSQL_COM_QUIT 0x01
#define MYSQL_COM_INITDB 0x02

View File

@ -70,7 +70,6 @@
#include <maxscale/adminusers.h>
#include <debugcli.h>
#include <maxscale/housekeeper.h>
#include <maxscale/listmanager.h>
#include <maxscale/maxscale.h>
#include <maxscale/version.h>
#include <maxscale/log_manager.h>