From b41a847b9d2bc1516c4c3f7e1b192533bbe37a8f Mon Sep 17 00:00:00 2001 From: Shane Bryldt Date: Wed, 29 Mar 2017 17:22:17 -0600 Subject: [PATCH] FS-10167: Fixed bug in windows test_thread_pools test related to the thread pool itself and ks_q cleanup --- libs/libks/src/include/ks_time.h | 1 + libs/libks/src/include/simclist.h | 1448 ++++++++++++++------------- libs/libks/src/ks.c | 3 + libs/libks/src/ks_mutex.c | 3 +- libs/libks/src/ks_q.c | 7 +- libs/libks/src/ks_thread_pool.c | 16 +- libs/libks/src/ks_time.c | 15 +- libs/libks/src/simclist.c | 870 ++++++++-------- libs/libks/test/test_thread_pools.c | 3 +- 9 files changed, 1166 insertions(+), 1200 deletions(-) diff --git a/libs/libks/src/include/ks_time.h b/libs/libks/src/include/ks_time.h index af2c60c892..7b13f9b31b 100644 --- a/libs/libks/src/include/ks_time.h +++ b/libs/libks/src/include/ks_time.h @@ -44,6 +44,7 @@ KS_BEGIN_EXTERN_C #define ks_time_nsec(time) (((time) % KS_USEC_PER_SEC) * 1000) #define ks_sleep_ms(_t) ks_sleep(_t * 1000) +KS_DECLARE(void) ks_time_init(void); KS_DECLARE(ks_time_t) ks_time_now(void); KS_DECLARE(ks_time_t) ks_time_now_sec(void); KS_DECLARE(void) ks_sleep(ks_time_t microsec); diff --git a/libs/libks/src/include/simclist.h b/libs/libks/src/include/simclist.h index 90cdd0cead..73186a7f7f 100755 --- a/libs/libks/src/include/simclist.h +++ b/libs/libks/src/include/simclist.h @@ -1,23 +1,23 @@ /* - * Copyright (c) 2007,2008 Mij - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ +* Copyright (c) 2007,2008 Mij +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ /* - * SimCList library. See http://mij.oltrelinux.com/devel/simclist - */ +* SimCList library. See http://mij.oltrelinux.com/devel/simclist +*/ #ifndef SIMCLIST_H @@ -33,11 +33,11 @@ extern "C" { #include #ifndef SIMCLIST_NO_DUMPRESTORE -#ifndef _WIN32 -#include /* list_dump_info_t's struct timeval */ -#else -#include -#endif +# ifndef _WIN32 +# include /* list_dump_info_t's struct timeval */ +# else +# include +# endif #endif @@ -45,112 +45,112 @@ extern "C" { #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L /* "inline" and "restrict" are keywords */ #else -#define inline /* inline */ -#define restrict /* restrict */ +# define inline /* inline */ +# define restrict /* restrict */ #endif /** - * Type representing list hashes. - * - * This is a signed integer value. - */ + * Type representing list hashes. + * + * This is a signed integer value. + */ typedef int32_t list_hash_t; #ifndef SIMCLIST_NO_DUMPRESTORE typedef struct { - uint16_t version; /* dump version */ - struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */ + uint16_t version; /* dump version */ + struct timeval timestamp; /* when the list has been dumped, seconds since UNIX epoch */ uint32_t list_size; uint32_t list_numels; - list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */ + list_hash_t list_hash; /* hash of the list when dumped, or 0 if invalid */ uint32_t dumpsize; - int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */ + int consistent; /* 1 if the dump is verified complete/consistent; 0 otherwise */ } list_dump_info_t; #endif /** - * a comparator of elements. - * - * A comparator of elements is a function that: - * -# receives two references to elements a and b - * -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively - * - * It is responsability of the function to handle possible NULL values. - */ - typedef int (*element_comparator) (const void *a, const void *b); + * a comparator of elements. + * + * A comparator of elements is a function that: + * -# receives two references to elements a and b + * -# returns {<0, 0, >0} if (a > b), (a == b), (a < b) respectively + * + * It is responsability of the function to handle possible NULL values. + */ + typedef int(*element_comparator)(const void *a, const void *b); /** - * a seeker of elements. - * - * An element seeker is a function that: - * -# receives a reference to an element el - * -# receives a reference to some indicator data - * -# returns non-0 if the element matches the indicator, 0 otherwise - * - * It is responsability of the function to handle possible NULL values in any - * argument. - */ - typedef int (*element_seeker) (const void *el, const void *indicator); + * a seeker of elements. + * + * An element seeker is a function that: + * -# receives a reference to an element el + * -# receives a reference to some indicator data + * -# returns non-0 if the element matches the indicator, 0 otherwise + * + * It is responsability of the function to handle possible NULL values in any + * argument. + */ + typedef int(*element_seeker)(const void *el, const void *indicator); /** - * an element lenght meter. - * - * An element meter is a function that: - * -# receives the reference to an element el - * -# returns its size in bytes - * - * It is responsability of the function to handle possible NULL values. - */ - typedef size_t (*element_meter) (const void *el); + * an element lenght meter. + * + * An element meter is a function that: + * -# receives the reference to an element el + * -# returns its size in bytes + * + * It is responsability of the function to handle possible NULL values. + */ + typedef size_t(*element_meter)(const void *el); /** - * a function computing the hash of elements. - * - * An hash computing function is a function that: - * -# receives the reference to an element el - * -# returns a hash value for el - * - * It is responsability of the function to handle possible NULL values. - */ - typedef list_hash_t (*element_hash_computer) (const void *el); + * a function computing the hash of elements. + * + * An hash computing function is a function that: + * -# receives the reference to an element el + * -# returns a hash value for el + * + * It is responsability of the function to handle possible NULL values. + */ + typedef list_hash_t(*element_hash_computer)(const void *el); /** - * a function for serializing an element. - * - * A serializer function is one that gets a reference to an element, - * and returns a reference to a buffer that contains its serialization - * along with the length of this buffer. - * It is responsability of the function to handle possible NULL values, - * returning a NULL buffer and a 0 buffer length. - * - * These functions have 3 goals: - * -# "freeze" and "flatten" the memory representation of the element - * -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations - * -# possibly extract a compressed representation of the element - * - * @param el reference to the element data - * @param serialize_buffer reference to fill with the length of the buffer - * @return reference to the buffer with the serialized data - */ - typedef void *(*element_serializer) (const void *restrict el, uint32_t *restrict serializ_len); + * a function for serializing an element. + * + * A serializer function is one that gets a reference to an element, + * and returns a reference to a buffer that contains its serialization + * along with the length of this buffer. + * It is responsability of the function to handle possible NULL values, + * returning a NULL buffer and a 0 buffer length. + * + * These functions have 3 goals: + * -# "freeze" and "flatten" the memory representation of the element + * -# provide a portable (wrt byte order, or type size) representation of the element, if the dump can be used on different sw/hw combinations + * -# possibly extract a compressed representation of the element + * + * @param el reference to the element data + * @param serialize_buffer reference to fill with the length of the buffer + * @return reference to the buffer with the serialized data + */ + typedef void *(*element_serializer)(const void *restrict el, uint32_t *restrict serializ_len); /** - * a function for un-serializing an element. - * - * An unserializer function accomplishes the inverse operation of the - * serializer function. An unserializer function is one that gets a - * serialized representation of an element and turns it backe to the original - * element. The serialized representation is passed as a reference to a buffer - * with its data, and the function allocates and returns the buffer containing - * the original element, and it sets the length of this buffer into the - * integer passed by reference. - * - * @param data reference to the buffer with the serialized representation of the element - * @param data_len reference to the location where to store the length of the data in the buffer returned - * @return reference to a buffer with the original, unserialized representation of the element - */ - typedef void *(*element_unserializer) (const void *restrict data, uint32_t *restrict data_len); + * a function for un-serializing an element. + * + * An unserializer function accomplishes the inverse operation of the + * serializer function. An unserializer function is one that gets a + * serialized representation of an element and turns it backe to the original + * element. The serialized representation is passed as a reference to a buffer + * with its data, and the function allocates and returns the buffer containing + * the original element, and it sets the length of this buffer into the + * integer passed by reference. + * + * @param data reference to the buffer with the serialized representation of the element + * @param data_len reference to the location where to store the length of the data in the buffer returned + * @return reference to a buffer with the original, unserialized representation of the element + */ + typedef void *(*element_unserializer)(const void *restrict data, uint32_t *restrict data_len); /* [private-use] list entry -- olds actual user datum */ struct list_entry_s { @@ -205,778 +205,780 @@ extern "C" { } list_t; /** - * initialize a list object for use. - * - * @param l must point to a user-provided memory location - * @return 0 for success. -1 for failure - */ - KS_DECLARE(int) list_init(list_t *restrict l); + * initialize a list object for use. + * + * @param l must point to a user-provided memory location + * @return 0 for success. -1 for failure + */ + int list_init(list_t *restrict l); /** - * completely remove the list from memory. - * - * This function is the inverse of list_init(). It is meant to be called when - * the list is no longer going to be used. Elements and possible memory taken - * for internal use are freed. - * - * @param l list to destroy - */ - KS_DECLARE(void) list_destroy(list_t *restrict l); + * completely remove the list from memory. + * + * This function is the inverse of list_init(). It is meant to be called when + * the list is no longer going to be used. Elements and possible memory taken + * for internal use are freed. + * + * @param l list to destroy + */ + void list_destroy(list_t *restrict l); /** - * set the comparator function for list elements. - * - * Comparator functions are used for searching and sorting. If NULL is passed - * as reference to the function, the comparator is disabled. - * - * @param l list to operate - * @param comparator_fun pointer to the actual comparator function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_comparator() - */ - KS_DECLARE(int) list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun); + * set the comparator function for list elements. + * + * Comparator functions are used for searching and sorting. If NULL is passed + * as reference to the function, the comparator is disabled. + * + * @param l list to operate + * @param comparator_fun pointer to the actual comparator function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_comparator() + */ + int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun); /** - * set a seeker function for list elements. - * - * Seeker functions are used for finding elements. If NULL is passed as reference - * to the function, the seeker is disabled. - * - * @param l list to operate - * @param seeker_fun pointer to the actual seeker function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_seeker() - */ - KS_DECLARE(int) list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun); + * set a seeker function for list elements. + * + * Seeker functions are used for finding elements. If NULL is passed as reference + * to the function, the seeker is disabled. + * + * @param l list to operate + * @param seeker_fun pointer to the actual seeker function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_seeker() + */ + int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun); /** - * require to free element data when list entry is removed (default: don't free). - * - * [ advanced preference ] - * - * By default, when an element is removed from the list, it disappears from - * the list by its actual data is not free()d. With this option, every - * deletion causes element data to be freed. - * - * It is responsability of this function to correctly handle NULL values, if - * NULL elements are inserted into the list. - * - * @param l list to operate - * @param metric_fun pointer to the actual metric function - * @param copy_data 0: do not free element data (default); non-0: do free - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_meter() - * @see list_meter_int8_t() - * @see list_meter_int16_t() - * @see list_meter_int32_t() - * @see list_meter_int64_t() - * @see list_meter_uint8_t() - * @see list_meter_uint16_t() - * @see list_meter_uint32_t() - * @see list_meter_uint64_t() - * @see list_meter_float() - * @see list_meter_double() - * @see list_meter_string() - */ - KS_DECLARE(int) list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data); + * require to free element data when list entry is removed (default: don't free). + * + * [ advanced preference ] + * + * By default, when an element is removed from the list, it disappears from + * the list by its actual data is not free()d. With this option, every + * deletion causes element data to be freed. + * + * It is responsability of this function to correctly handle NULL values, if + * NULL elements are inserted into the list. + * + * @param l list to operate + * @param metric_fun pointer to the actual metric function + * @param copy_data 0: do not free element data (default); non-0: do free + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_meter() + * @see list_meter_int8_t() + * @see list_meter_int16_t() + * @see list_meter_int32_t() + * @see list_meter_int64_t() + * @see list_meter_uint8_t() + * @see list_meter_uint16_t() + * @see list_meter_uint32_t() + * @see list_meter_uint64_t() + * @see list_meter_float() + * @see list_meter_double() + * @see list_meter_string() + */ + int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data); /** - * set the element hash computing function for the list elements. - * - * [ advanced preference ] - * - * An hash can be requested depicting the list status at a given time. An hash - * only depends on the elements and their order. By default, the hash of an - * element is only computed on its reference. With this function, the user can - * set a custom function computing the hash of an element. If such function is - * provided, the list_hash() function automatically computes the list hash using - * the custom function instead of simply referring to element references. - * - * @param l list to operate - * @param hash_computer_fun pointer to the actual hash computing function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_hash_computer() - */ - KS_DECLARE(int) list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun); + * set the element hash computing function for the list elements. + * + * [ advanced preference ] + * + * An hash can be requested depicting the list status at a given time. An hash + * only depends on the elements and their order. By default, the hash of an + * element is only computed on its reference. With this function, the user can + * set a custom function computing the hash of an element. If such function is + * provided, the list_hash() function automatically computes the list hash using + * the custom function instead of simply referring to element references. + * + * @param l list to operate + * @param hash_computer_fun pointer to the actual hash computing function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_hash_computer() + */ + int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun); /** - * set the element serializer function for the list elements. - * - * [ advanced preference ] - * - * Serialize functions are used for dumping the list to some persistent - * storage. The serializer function is called for each element; it is passed - * a reference to the element and a reference to a size_t object. It will - * provide (and return) the buffer with the serialization of the element and - * fill the size_t object with the length of this serialization data. - * - * @param l list to operate - * @param serializer_fun pointer to the actual serializer function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_serializer() - * @see list_dump_filedescriptor() - * @see list_restore_filedescriptor() - */ - KS_DECLARE(int) list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun); + * set the element serializer function for the list elements. + * + * [ advanced preference ] + * + * Serialize functions are used for dumping the list to some persistent + * storage. The serializer function is called for each element; it is passed + * a reference to the element and a reference to a size_t object. It will + * provide (and return) the buffer with the serialization of the element and + * fill the size_t object with the length of this serialization data. + * + * @param l list to operate + * @param serializer_fun pointer to the actual serializer function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_serializer() + * @see list_dump_filedescriptor() + * @see list_restore_filedescriptor() + */ + int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun); /** - * set the element unserializer function for the list elements. - * - * [ advanced preference ] - * - * Unserialize functions are used for restoring the list from some persistent - * storage. The unserializer function is called for each element segment read - * from the storage; it is passed the segment and a reference to an integer. - * It shall allocate and return a buffer compiled with the resumed memory - * representation of the element, and set the integer value to the length of - * this buffer. - * - * @param l list to operate - * @param unserializer_fun pointer to the actual unserializer function - * @return 0 if the attribute was successfully set; -1 otherwise - * - * @see element_unserializer() - * @see list_dump_filedescriptor() - * @see list_restore_filedescriptor() - */ - KS_DECLARE(int) list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun); + * set the element unserializer function for the list elements. + * + * [ advanced preference ] + * + * Unserialize functions are used for restoring the list from some persistent + * storage. The unserializer function is called for each element segment read + * from the storage; it is passed the segment and a reference to an integer. + * It shall allocate and return a buffer compiled with the resumed memory + * representation of the element, and set the integer value to the length of + * this buffer. + * + * @param l list to operate + * @param unserializer_fun pointer to the actual unserializer function + * @return 0 if the attribute was successfully set; -1 otherwise + * + * @see element_unserializer() + * @see list_dump_filedescriptor() + * @see list_restore_filedescriptor() + */ + int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun); /** - * append data at the end of the list. - * - * This function is useful for adding elements with a FIFO/queue policy. - * - * @param l list to operate - * @param data pointer to user data to append - * - * @return 1 for success. < 0 for failure - */ - KS_DECLARE(int) list_append(list_t *restrict l, const void *data); + * append data at the end of the list. + * + * This function is useful for adding elements with a FIFO/queue policy. + * + * @param l list to operate + * @param data pointer to user data to append + * + * @return 1 for success. < 0 for failure + */ + int list_append(list_t *restrict l, const void *data); /** - * insert data in the head of the list. - * - * This function is useful for adding elements with a LIFO/Stack policy. - * - * @param l list to operate - * @param data pointer to user data to append - * - * @return 1 for success. < 0 for failure - */ - KS_DECLARE(int) list_prepend(list_t *restrict l, const void *restrict data); + * insert data in the head of the list. + * + * This function is useful for adding elements with a LIFO/Stack policy. + * + * @param l list to operate + * @param data pointer to user data to append + * + * @return 1 for success. < 0 for failure + */ + int list_prepend(list_t *restrict l, const void *restrict data); /** - * extract the element in the top of the list. - * - * This function is for using a list with a FIFO/queue policy. - * - * @param l list to operate - * @return reference to user datum, or NULL on errors - */ - KS_DECLARE(void *) list_fetch(list_t *restrict l); + * extract the element in the top of the list. + * + * This function is for using a list with a FIFO/queue policy. + * + * @param l list to operate + * @return reference to user datum, or NULL on errors + */ + void *list_fetch(list_t *restrict l); /** - * retrieve an element at a given position. - * - * @param l list to operate - * @param pos [0,size-1] position index of the element wanted - * @return reference to user datum, or NULL on errors - */ - KS_DECLARE(void *) list_get_at(const list_t *restrict l, unsigned int pos); + * retrieve an element at a given position. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element wanted + * @return reference to user datum, or NULL on errors + */ + void *list_get_at(const list_t *restrict l, unsigned int pos); /** - * return the maximum element of the list. - * - * @warning Requires a comparator function to be set for the list. - * - * Returns the maximum element with respect to the comparator function output. - * - * @see list_attributes_comparator() - * - * @param l list to operate - * @return the reference to the element, or NULL - */ - KS_DECLARE(void *) list_get_max(const list_t *restrict l); + * return the maximum element of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * Returns the maximum element with respect to the comparator function output. + * + * @see list_attributes_comparator() + * + * @param l list to operate + * @return the reference to the element, or NULL + */ + void *list_get_max(const list_t *restrict l); /** - * return the minimum element of the list. - * - * @warning Requires a comparator function to be set for the list. - * - * Returns the minimum element with respect to the comparator function output. - * - * @see list_attributes_comparator() - * - * @param l list to operate - * @return the reference to the element, or NULL - */ - KS_DECLARE(void *) list_get_min(const list_t *restrict l); + * return the minimum element of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * Returns the minimum element with respect to the comparator function output. + * + * @see list_attributes_comparator() + * + * @param l list to operate + * @return the reference to the element, or NULL + */ + void *list_get_min(const list_t *restrict l); /** - * retrieve and remove from list an element at a given position. - * - * @param l list to operate - * @param pos [0,size-1] position index of the element wanted - * @return reference to user datum, or NULL on errors - */ - KS_DECLARE(void *) list_extract_at(list_t *restrict l, unsigned int pos); + * retrieve and remove from list an element at a given position. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element wanted + * @return reference to user datum, or NULL on errors + */ + void *list_extract_at(list_t *restrict l, unsigned int pos); /** - * insert an element at a given position. - * - * @param l list to operate - * @param data reference to data to be inserted - * @param pos [0,size-1] position index to insert the element at - * @return positive value on success. Negative on failure - */ - KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned int pos); + * insert an element at a given position. + * + * @param l list to operate + * @param data reference to data to be inserted + * @param pos [0,size-1] position index to insert the element at + * @return positive value on success. Negative on failure + */ + int list_insert_at(list_t *restrict l, const void *data, unsigned int pos); /** - * expunge the first found given element from the list. - * - * Inspects the given list looking for the given element; if the element - * is found, it is removed. Only the first occurence is removed. - * If a comparator function was not set, elements are compared by reference. - * Otherwise, the comparator is used to match the element. - * - * @param l list to operate - * @param data reference of the element to search for - * @return 0 on success. Negative value on failure - * - * @see list_attributes_comparator() - * @see list_delete_at() - */ - KS_DECLARE(int) list_delete(list_t *restrict l, const void *data); + * expunge the first found given element from the list. + * + * Inspects the given list looking for the given element; if the element + * is found, it is removed. Only the first occurence is removed. + * If a comparator function was not set, elements are compared by reference. + * Otherwise, the comparator is used to match the element. + * + * @param l list to operate + * @param data reference of the element to search for + * @return 0 on success. Negative value on failure + * + * @see list_attributes_comparator() + * @see list_delete_at() + */ + int list_delete(list_t *restrict l, const void *data); /** - * expunge an element at a given position from the list. - * - * @param l list to operate - * @param pos [0,size-1] position index of the element to be deleted - * @return 0 on success. Negative value on failure - */ - KS_DECLARE(int) list_delete_at(list_t *restrict l, unsigned int pos); + * expunge an element at a given position from the list. + * + * @param l list to operate + * @param pos [0,size-1] position index of the element to be deleted + * @return 0 on success. Negative value on failure + */ + int list_delete_at(list_t *restrict l, unsigned int pos); /** - * expunge an array of elements from the list, given their position range. - * - * @param l list to operate - * @param posstart [0,size-1] position index of the first element to be deleted - * @param posend [posstart,size-1] position of the last element to be deleted - * @return the number of elements successfully removed on success, <0 on error - */ - KS_DECLARE(int) list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend); + * expunge an array of elements from the list, given their position range. + * + * @param l list to operate + * @param posstart [0,size-1] position index of the first element to be deleted + * @param posend [posstart,size-1] position of the last element to be deleted + * @return the number of elements successfully removed on success, <0 on error + */ + int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend); /** - * clear all the elements off of the list. - * - * The element datums will not be freed. - * - * @see list_delete_range() - * @see list_size() - * - * @param l list to operate - * @return the number of elements removed on success, <0 on error - */ - KS_DECLARE(int) list_clear(list_t *restrict l); + * clear all the elements off of the list. + * + * The element datums will not be freed. + * + * @see list_delete_range() + * @see list_size() + * + * @param l list to operate + * @return the number of elements removed on success, <0 on error + */ + int list_clear(list_t *restrict l); /** - * inspect the number of elements in the list. - * - * @param l list to operate - * @return number of elements currently held by the list - */ - KS_DECLARE(unsigned int) list_size(const list_t *restrict l); + * inspect the number of elements in the list. + * + * @param l list to operate + * @return number of elements currently held by the list + */ + unsigned int list_size(const list_t *restrict l); /** - * inspect whether the list is empty. - * - * @param l list to operate - * @return 0 iff the list is not empty - * - * @see list_size() - */ - KS_DECLARE(int) list_empty(const list_t *restrict l); + * inspect whether the list is empty. + * + * @param l list to operate + * @return 0 iff the list is not empty + * + * @see list_size() + */ + int list_empty(const list_t *restrict l); /** - * find the position of an element in a list. - * - * @warning Requires a comparator function to be set for the list. - * - * Inspects the given list looking for the given element; if the element - * is found, its position into the list is returned. - * Elements are inspected comparing references if a comparator has not been - * set. Otherwise, the comparator is used to find the element. - * - * @param l list to operate - * @param data reference of the element to search for - * @return position of element in the list, or <0 if not found - * - * @see list_attributes_comparator() - * @see list_get_at() - */ - KS_DECLARE(int) list_locate(const list_t *restrict l, const void *data); + * find the position of an element in a list. + * + * @warning Requires a comparator function to be set for the list. + * + * Inspects the given list looking for the given element; if the element + * is found, its position into the list is returned. + * Elements are inspected comparing references if a comparator has not been + * set. Otherwise, the comparator is used to find the element. + * + * @param l list to operate + * @param data reference of the element to search for + * @return position of element in the list, or <0 if not found + * + * @see list_attributes_comparator() + * @see list_get_at() + */ + int list_locate(const list_t *restrict l, const void *data); /** - * returns an element given an indicator. - * - * @warning Requires a seeker function to be set for the list. - * - * Inspect the given list looking with the seeker if an element matches - * an indicator. If such element is found, the reference to the element - * is returned. - * - * @param l list to operate - * @param indicator indicator data to pass to the seeker along with elements - * @return reference to the element accepted by the seeker, or NULL if none found - */ - KS_DECLARE(void *) list_seek(list_t *restrict l, const void *indicator); + * returns an element given an indicator. + * + * @warning Requires a seeker function to be set for the list. + * + * Inspect the given list looking with the seeker if an element matches + * an indicator. If such element is found, the reference to the element + * is returned. + * + * @param l list to operate + * @param indicator indicator data to pass to the seeker along with elements + * @return reference to the element accepted by the seeker, or NULL if none found + */ + void *list_seek(list_t *restrict l, const void *indicator); /** - * inspect whether some data is member of the list. - * - * @warning Requires a comparator function to be set for the list. - * - * By default, a per-reference comparison is accomplished. That is, - * the data is in list if any element of the list points to the same - * location of data. - * A "semantic" comparison is accomplished, otherwise, if a comparator - * function has been set previously, with list_attributes_comparator(); - * in which case, the given data reference is believed to be in list iff - * comparator_fun(elementdata, userdata) == 0 for any element in the list. - * - * @param l list to operate - * @param data reference to the data to search - * @return 0 iff the list does not contain data as an element - * - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_contains(const list_t *restrict l, const void *data); + * inspect whether some data is member of the list. + * + * @warning Requires a comparator function to be set for the list. + * + * By default, a per-reference comparison is accomplished. That is, + * the data is in list if any element of the list points to the same + * location of data. + * A "semantic" comparison is accomplished, otherwise, if a comparator + * function has been set previously, with list_attributes_comparator(); + * in which case, the given data reference is believed to be in list iff + * comparator_fun(elementdata, userdata) == 0 for any element in the list. + * + * @param l list to operate + * @param data reference to the data to search + * @return 0 iff the list does not contain data as an element + * + * @see list_attributes_comparator() + */ + int list_contains(const list_t *restrict l, const void *data); /** - * concatenate two lists - * - * Concatenates one list with another, and stores the result into a - * user-provided list object, which must be different from both the - * lists to concatenate. Attributes from the original lists are not - * cloned. - * The destination list referred is threated as virgin room: if it - * is an existing list containing elements, memory leaks will happen. - * It is OK to specify the same list twice as source, for "doubling" - * it in the destination. - * - * @param l1 base list - * @param l2 list to append to the base - * @param dest reference to the destination list - * @return 0 for success, -1 for errors - */ - KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest); + * concatenate two lists + * + * Concatenates one list with another, and stores the result into a + * user-provided list object, which must be different from both the + * lists to concatenate. Attributes from the original lists are not + * cloned. + * The destination list referred is threated as virgin room: if it + * is an existing list containing elements, memory leaks will happen. + * It is OK to specify the same list twice as source, for "doubling" + * it in the destination. + * + * @param l1 base list + * @param l2 list to append to the base + * @param dest reference to the destination list + * @return 0 for success, -1 for errors + */ + int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest); /** - * sort list elements. - * - * @warning Requires a comparator function to be set for the list. - * - * Sorts the list in ascending or descending order as specified by the versus - * flag. The algorithm chooses autonomously what algorithm is best suited for - * sorting the list wrt its current status. - * - * @param l list to operate - * @param versus positive: order small to big; negative: order big to small - * @return 0 iff sorting was successful - * - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_sort(list_t *restrict l, int versus); + * sort list elements. + * + * @warning Requires a comparator function to be set for the list. + * + * Sorts the list in ascending or descending order as specified by the versus + * flag. The algorithm chooses autonomously what algorithm is best suited for + * sorting the list wrt its current status. + * + * @param l list to operate + * @param versus positive: order small to big; negative: order big to small + * @return 0 iff sorting was successful + * + * @see list_attributes_comparator() + */ + int list_sort(list_t *restrict l, int versus); /** - * start an iteration session. - * - * This function prepares the list to be iterated. - * - * @param l list to operate - * @return 0 if the list cannot be currently iterated. >0 otherwise - * - * @see list_iterator_stop() - */ - KS_DECLARE(int) list_iterator_start(list_t *restrict l); + * start an iteration session. + * + * This function prepares the list to be iterated. + * + * @param l list to operate + * @return 0 if the list cannot be currently iterated. >0 otherwise + * + * @see list_iterator_stop() + */ + int list_iterator_start(list_t *restrict l); /** - * return the next element in the iteration session. - * - * @param l list to operate - * @return element datum, or NULL on errors - */ - KS_DECLARE(void *) list_iterator_next(list_t *restrict l); + * return the next element in the iteration session. + * + * @param l list to operate + * @return element datum, or NULL on errors + */ + void *list_iterator_next(list_t *restrict l); /** - * inspect whether more elements are available in the iteration session. - * - * @param l list to operate - * @return 0 iff no more elements are available. - */ - KS_DECLARE(int) list_iterator_hasnext(const list_t *restrict l); + * inspect whether more elements are available in the iteration session. + * + * @param l list to operate + * @return 0 iff no more elements are available. + */ + int list_iterator_hasnext(const list_t *restrict l); /** - * end an iteration session. - * - * @param l list to operate - * @return 0 iff the iteration session cannot be stopped - */ - KS_DECLARE(int) list_iterator_stop(list_t *restrict l); + * end an iteration session. + * + * @param l list to operate + * @return 0 iff the iteration session cannot be stopped + */ + int list_iterator_stop(list_t *restrict l); /** - * return the hash of the current status of the list. - * - * @param l list to operate - * @param hash where the resulting hash is put - * - * @return 0 for success; <0 for failure - */ - KS_DECLARE(int) list_hash(const list_t *restrict l, list_hash_t *restrict hash); + * return the hash of the current status of the list. + * + * @param l list to operate + * @param hash where the resulting hash is put + * + * @return 0 for success; <0 for failure + */ + int list_hash(const list_t *restrict l, list_hash_t *restrict hash); #ifndef SIMCLIST_NO_DUMPRESTORE /** - * get meta informations on a list dump on filedescriptor. - * - * [ advanced function ] - * - * Extracts the meta information from a SimCList dump located in a file - * descriptor. The file descriptor must be open and positioned at the - * beginning of the SimCList dump block. - * - * @param fd file descriptor to get metadata from - * @param info reference to a dump metainformation structure to fill - * @return 0 for success; <0 for failure - * - * @see list_dump_filedescriptor() - */ - KS_DECLARE(int) list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info); + * get meta informations on a list dump on filedescriptor. + * + * [ advanced function ] + * + * Extracts the meta information from a SimCList dump located in a file + * descriptor. The file descriptor must be open and positioned at the + * beginning of the SimCList dump block. + * + * @param fd file descriptor to get metadata from + * @param info reference to a dump metainformation structure to fill + * @return 0 for success; <0 for failure + * + * @see list_dump_filedescriptor() + */ + int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info); /** - * get meta informations on a list dump on file. - * - * [ advanced function ] - * - * Extracts the meta information from a SimCList dump located in a file. - * - * @param filename filename of the file to fetch from - * @param info reference to a dump metainformation structure to fill - * @return 0 for success; <0 for failure - * - * @see list_dump_filedescriptor() - */ - KS_DECLARE(int) list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info); + * get meta informations on a list dump on file. + * + * [ advanced function ] + * + * Extracts the meta information from a SimCList dump located in a file. + * + * @param filename filename of the file to fetch from + * @param info reference to a dump metainformation structure to fill + * @return 0 for success; <0 for failure + * + * @see list_dump_filedescriptor() + */ + int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info); /** - * dump the list into an open, writable file descriptor. - * - * This function "dumps" the list to a persistent storage so it can be - * preserved across process terminations. - * When called, the file descriptor must be open for writing and positioned - * where the serialized data must begin. It writes its serialization of the - * list in a form which is portable across different architectures. Dump can - * be safely performed on stream-only (non seekable) descriptors. The file - * descriptor is not closed at the end of the operations. - * - * To use dump functions, either of these conditions must be satisfied: - * -# a metric function has been specified with list_attributes_copy() - * -# a serializer function has been specified with list_attributes_serializer() - * - * If a metric function has been specified, each element of the list is dumped - * as-is from memory, copying it from its pointer for its length down to the - * file descriptor. This might have impacts on portability of the dump to - * different architectures. - * - * If a serializer function has been specified, its result for each element is - * dumped to the file descriptor. - * - * - * @param l list to operate - * @param fd file descriptor to write to - * @param len location to store the resulting length of the dump (bytes), or NULL - * - * @return 0 if successful; -1 otherwise - * - * @see element_serializer() - * @see list_attributes_copy() - * @see list_attributes_serializer() - */ - KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len); + * dump the list into an open, writable file descriptor. + * + * This function "dumps" the list to a persistent storage so it can be + * preserved across process terminations. + * When called, the file descriptor must be open for writing and positioned + * where the serialized data must begin. It writes its serialization of the + * list in a form which is portable across different architectures. Dump can + * be safely performed on stream-only (non seekable) descriptors. The file + * descriptor is not closed at the end of the operations. + * + * To use dump functions, either of these conditions must be satisfied: + * -# a metric function has been specified with list_attributes_copy() + * -# a serializer function has been specified with list_attributes_serializer() + * + * If a metric function has been specified, each element of the list is dumped + * as-is from memory, copying it from its pointer for its length down to the + * file descriptor. This might have impacts on portability of the dump to + * different architectures. + * + * If a serializer function has been specified, its result for each element is + * dumped to the file descriptor. + * + * + * @param l list to operate + * @param fd file descriptor to write to + * @param len location to store the resulting length of the dump (bytes), or NULL + * + * @return 0 if successful; -1 otherwise + * + * @see element_serializer() + * @see list_attributes_copy() + * @see list_attributes_serializer() + */ + int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len); /** - * dump the list to a file name. - * - * This function creates a filename and dumps the current content of the list - * to it. If the file exists it is overwritten. The number of bytes written to - * the file can be returned in a specified argument. - * - * @param l list to operate - * @param filename filename to write to - * @param len location to store the resulting length of the dump (bytes), or NULL - * - * @return 0 if successful; -1 otherwise - * - * @see list_attributes_copy() - * @see element_serializer() - * @see list_attributes_serializer() - * @see list_dump_filedescriptor() - * @see list_restore_file() - * - * This function stores a representation of the list - */ - KS_DECLARE(int) list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len); + * dump the list to a file name. + * + * This function creates a filename and dumps the current content of the list + * to it. If the file exists it is overwritten. The number of bytes written to + * the file can be returned in a specified argument. + * + * @param l list to operate + * @param filename filename to write to + * @param len location to store the resulting length of the dump (bytes), or NULL + * + * @return 0 if successful; -1 otherwise + * + * @see list_attributes_copy() + * @see element_serializer() + * @see list_attributes_serializer() + * @see list_dump_filedescriptor() + * @see list_restore_file() + * + * This function stores a representation of the list + */ + int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len); /** - * restore the list from an open, readable file descriptor to memory. - * - * This function is the "inverse" of list_dump_filedescriptor(). It restores - * the list content from a (open, read-ready) file descriptor to memory. An - * unserializer might be needed to restore elements from the persistent - * representation back into memory-consistent format. List attributes can not - * be restored and must be set manually. - * - * @see list_dump_filedescriptor() - * @see list_attributes_serializer() - * @see list_attributes_unserializer() - * - * @param l list to restore to - * @param fd file descriptor to read from. - * @param len location to store the length of the dump read (bytes), or NULL - * @return 0 if successful; -1 otherwise - */ - KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len); + * restore the list from an open, readable file descriptor to memory. + * + * This function is the "inverse" of list_dump_filedescriptor(). It restores + * the list content from a (open, read-ready) file descriptor to memory. An + * unserializer might be needed to restore elements from the persistent + * representation back into memory-consistent format. List attributes can not + * be restored and must be set manually. + * + * @see list_dump_filedescriptor() + * @see list_attributes_serializer() + * @see list_attributes_unserializer() + * + * @param l list to restore to + * @param fd file descriptor to read from. + * @param len location to store the length of the dump read (bytes), or NULL + * @return 0 if successful; -1 otherwise + */ + int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len); /** - * restore the list from a file name. - * - * This function restores the content of a list from a file into memory. It is - * the inverse of list_dump_file(). - * - * @see element_unserializer() - * @see list_attributes_unserializer() - * @see list_dump_file() - * @see list_restore_filedescriptor() - * - * @param l list to restore to - * @param filename filename to read data from - * @param len location to store the length of the dump read (bytes), or NULL - * @return 0 if successful; -1 otherwise - */ - KS_DECLARE(int) list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len); + * restore the list from a file name. + * + * This function restores the content of a list from a file into memory. It is + * the inverse of list_dump_file(). + * + * @see element_unserializer() + * @see list_attributes_unserializer() + * @see list_dump_file() + * @see list_restore_filedescriptor() + * + * @param l list to restore to + * @param filename filename to read data from + * @param len location to store the length of the dump read (bytes), or NULL + * @return 0 if successful; -1 otherwise + */ + int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *len); #endif /* ready-made comparators, meters and hash computers */ /* comparator functions */ /** - * ready-made comparator for int8_t elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_int8_t (const void *a, const void *b); + * ready-made comparator for int8_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_int8_t(const void *a, const void *b); /** - * ready-made comparator for int16_t elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_int16_t (const void *a, const void *b); + * ready-made comparator for int16_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_int16_t(const void *a, const void *b); /** - * ready-made comparator for int32_t elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_int32_t (const void *a, const void *b); + * ready-made comparator for int32_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_int32_t(const void *a, const void *b); /** - * ready-made comparator for int64_t elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_int64_t (const void *a, const void *b); + * ready-made comparator for int64_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_int64_t(const void *a, const void *b); /** - * ready-made comparator for uint8_t elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_uint8_t (const void *a, const void *b); + * ready-made comparator for uint8_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_uint8_t(const void *a, const void *b); /** - * ready-made comparator for uint16_t elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_uint16_t (const void *a, const void *b); + * ready-made comparator for uint16_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_uint16_t(const void *a, const void *b); /** - * ready-made comparator for uint32_t elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_uint32_t (const void *a, const void *b); + * ready-made comparator for uint32_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_uint32_t(const void *a, const void *b); /** - * ready-made comparator for uint64_t elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_uint64_t (const void *a, const void *b); + * ready-made comparator for uint64_t elements. + * @see list_attributes_comparator() + */ + int list_comparator_uint64_t(const void *a, const void *b); /** - * ready-made comparator for float elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_float(const void *a, const void *b); + * ready-made comparator for float elements. + * @see list_attributes_comparator() + */ + int list_comparator_float(const void *a, const void *b); /** - * ready-made comparator for double elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_double(const void *a, const void *b); + * ready-made comparator for double elements. + * @see list_attributes_comparator() + */ + int list_comparator_double(const void *a, const void *b); /** - * ready-made comparator for string elements. - * @see list_attributes_comparator() - */ - KS_DECLARE(int) list_comparator_string(const void *a, const void *b); + * ready-made comparator for string elements. + * @see list_attributes_comparator() + */ + int list_comparator_string(const void *a, const void *b); /* metric functions */ /** - * ready-made metric function for int8_t elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_int8_t (const void *el); + * ready-made metric function for int8_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_int8_t(const void *el); /** - * ready-made metric function for int16_t elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_int16_t (const void *el); + * ready-made metric function for int16_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_int16_t(const void *el); /** - * ready-made metric function for int32_t elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_int32_t (const void *el); + * ready-made metric function for int32_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_int32_t(const void *el); /** - * ready-made metric function for int64_t elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_int64_t (const void *el); + * ready-made metric function for int64_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_int64_t(const void *el); /** - * ready-made metric function for uint8_t elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_uint8_t (const void *el); + * ready-made metric function for uint8_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_uint8_t(const void *el); /** - * ready-made metric function for uint16_t elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_uint16_t (const void *el); + * ready-made metric function for uint16_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_uint16_t(const void *el); /** - * ready-made metric function for uint32_t elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_uint32_t (const void *el); + * ready-made metric function for uint32_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_uint32_t(const void *el); /** - * ready-made metric function for uint64_t elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_uint64_t (const void *el); + * ready-made metric function for uint64_t elements. + * @see list_attributes_copy() + */ + size_t list_meter_uint64_t(const void *el); /** - * ready-made metric function for float elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_float(const void *el); + * ready-made metric function for float elements. + * @see list_attributes_copy() + */ + size_t list_meter_float(const void *el); /** - * ready-made metric function for double elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_double(const void *el); + * ready-made metric function for double elements. + * @see list_attributes_copy() + */ + size_t list_meter_double(const void *el); /** - * ready-made metric function for string elements. - * @see list_attributes_copy() - */ - KS_DECLARE(size_t) list_meter_string(const void *el); + * ready-made metric function for string elements. + * @see list_attributes_copy() + */ + size_t list_meter_string(const void *el); /* hash functions */ /** - * ready-made hash function for int8_t elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_int8_t(const void *el); + * ready-made hash function for int8_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_int8_t(const void *el); /** - * ready-made hash function for int16_t elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_int16_t(const void *el); + * ready-made hash function for int16_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_int16_t(const void *el); /** - * ready-made hash function for int32_t elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_int32_t(const void *el); + * ready-made hash function for int32_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_int32_t(const void *el); /** - * ready-made hash function for int64_t elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_int64_t(const void *el); + * ready-made hash function for int64_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_int64_t(const void *el); /** - * ready-made hash function for uint8_t elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_uint8_t(const void *el); + * ready-made hash function for uint8_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_uint8_t(const void *el); /** - * ready-made hash function for uint16_t elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_uint16_t(const void *el); + * ready-made hash function for uint16_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_uint16_t(const void *el); /** - * ready-made hash function for uint32_t elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_uint32_t(const void *el); + * ready-made hash function for uint32_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_uint32_t(const void *el); /** - * ready-made hash function for uint64_t elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_uint64_t(const void *el); + * ready-made hash function for uint64_t elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_uint64_t(const void *el); /** - * ready-made hash function for float elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_float(const void *el); + * ready-made hash function for float elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_float(const void *el); /** - * ready-made hash function for double elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_double(const void *el); + * ready-made hash function for double elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_double(const void *el); /** - * ready-made hash function for string elements. - * @see list_attributes_hash_computer() - */ - KS_DECLARE(list_hash_t) list_hashcomputer_string(const void *el); + * ready-made hash function for string elements. + * @see list_attributes_hash_computer() + */ + list_hash_t list_hashcomputer_string(const void *el); #ifdef __cplusplus } #endif + #endif + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/libks/src/ks.c b/libs/libks/src/ks.c index f0bace305a..6f493cceae 100644 --- a/libs/libks/src/ks.c +++ b/libs/libks/src/ks.c @@ -64,6 +64,9 @@ KS_DECLARE(ks_status_t) ks_global_set_cleanup(ks_pool_cleanup_fn_t fn, void *arg KS_DECLARE(ks_status_t) ks_init(void) { unsigned int pid = 0; + + ks_time_init(); + #ifdef __WINDOWS__ pid = _getpid(); #else diff --git a/libs/libks/src/ks_mutex.c b/libs/libks/src/ks_mutex.c index cea52e6f2e..14d84e3e84 100644 --- a/libs/libks/src/ks_mutex.c +++ b/libs/libks/src/ks_mutex.c @@ -383,7 +383,8 @@ KS_DECLARE(ks_status_t) ks_cond_wait(ks_cond_t *cond) KS_DECLARE(ks_status_t) ks_cond_timedwait(ks_cond_t *cond, ks_time_t ms) { #ifdef WIN32 - if(!SleepConditionVariableCS(&cond->cond, &cond->mutex->mutex, (DWORD)ms)) { + BOOL res = SleepConditionVariableCS(&cond->cond, &cond->mutex->mutex, (DWORD)ms); + if (!res) { if (GetLastError() == ERROR_TIMEOUT) { return KS_STATUS_TIMEOUT; } else { diff --git a/libs/libks/src/ks_q.c b/libs/libks/src/ks_q.c index 05e962a56a..c34c0692cd 100644 --- a/libs/libks/src/ks_q.c +++ b/libs/libks/src/ks_q.c @@ -67,6 +67,10 @@ static void ks_q_cleanup(ks_pool_t *mpool, void *ptr, void *arg, int type, ks_po switch(action) { case KS_MPCL_ANNOUNCE: + if (q->active) { + ks_q_flush(q); + ks_q_term(q); + } break; case KS_MPCL_TEARDOWN: np = q->head; @@ -133,7 +137,7 @@ KS_DECLARE(ks_size_t) ks_q_term(ks_q_t *q) active = q->active; q->active = 0; ks_mutex_unlock(q->list_mutex); - + if (active) { ks_q_wake(q); } @@ -227,6 +231,7 @@ static ks_status_t do_push(ks_q_t *q, void *ptr) ks_qnode_t *node; ks_mutex_lock(q->list_mutex); + if (!q->active) { ks_mutex_unlock(q->list_mutex); return KS_STATUS_INACTIVE; diff --git a/libs/libks/src/ks_thread_pool.c b/libs/libks/src/ks_thread_pool.c index 9c5be83236..a68280730d 100644 --- a/libs/libks/src/ks_thread_pool.c +++ b/libs/libks/src/ks_thread_pool.c @@ -129,13 +129,20 @@ static void *worker_thread(ks_thread_t *thread, void *data) ks_status_t status; status = ks_q_pop_timeout(tp->q, &pop, 1000); + if (status == KS_STATUS_BREAK) { + if (tp->state != TP_STATE_RUNNING) { + break; + } + continue; + } + /* ks_log(KS_LOG_DEBUG, "WORKER %d idle_sec %d running %d dying %d total %d max %d\n", my_id, idle_sec, tp->running_thread_count, tp->dying_thread_count, tp->thread_count, tp->max); */ check_queue(tp, KS_FALSE); - - if (status == KS_STATUS_TIMEOUT || status == KS_STATUS_BREAK) { + + if (status == KS_STATUS_TIMEOUT) { // || status == KS_STATUS_BREAK) { idle_sec++; if (idle_sec >= tp->idle_sec) { @@ -148,7 +155,6 @@ static void *worker_thread(ks_thread_t *thread, void *data) ks_mutex_unlock(tp->mutex); if (die) { - ks_log(KS_LOG_DEBUG, "WORKER %d IDLE TIMEOUT\n", my_id); break; } } @@ -156,8 +162,8 @@ static void *worker_thread(ks_thread_t *thread, void *data) continue; } - if ((status != KS_STATUS_SUCCESS && status != KS_STATUS_BREAK) || !pop) { - ks_log(KS_LOG_DEBUG, "WORKER %d POP FAIL %d %p\n", my_id, status, (void *)pop); + if ((status != KS_STATUS_SUCCESS && status != KS_STATUS_BREAK)) { + ks_log(KS_LOG_ERROR, "WORKER %d POP FAIL %d %p\n", my_id, status, (void *)pop); break; } diff --git a/libs/libks/src/ks_time.c b/libs/libks/src/ks_time.c index 6e7c0ec18b..a11eccf927 100644 --- a/libs/libks/src/ks_time.c +++ b/libs/libks/src/ks_time.c @@ -40,7 +40,7 @@ static DWORD win32_last_get_time_tick = 0; static uint8_t win32_use_qpc = 0; static uint64_t win32_qpc_freq = 0; -static int timer_init; + static inline void win32_init_timers(void) { OSVERSIONINFOEX version_info; /* Used to fetch current OS version from Windows */ @@ -86,18 +86,17 @@ static inline void win32_init_timers(void) } LeaveCriticalSection(&timer_section); +} - timer_init = 1; +KS_DECLARE(void) ks_time_init(void) +{ + win32_init_timers(); } KS_DECLARE(ks_time_t) ks_time_now(void) { ks_time_t now; - if (!timer_init) { - win32_init_timers(); - } - if (win32_use_qpc) { /* Use QueryPerformanceCounter */ uint64_t count = 0; @@ -133,10 +132,6 @@ KS_DECLARE(ks_time_t) ks_time_now_sec(void) { ks_time_t now; - if (!timer_init) { - win32_init_timers(); - } - if (win32_use_qpc) { /* Use QueryPerformanceCounter */ uint64_t count = 0; diff --git a/libs/libks/src/simclist.c b/libs/libks/src/simclist.c index f7e797aa35..4726c78648 100755 --- a/libs/libks/src/simclist.c +++ b/libs/libks/src/simclist.c @@ -1,61 +1,57 @@ /* - * Copyright (c) 2007,2008,2009,2010,2011 Mij - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ +* Copyright (c) 2007,2008,2009,2010,2011 Mij +* +* Permission to use, copy, modify, and distribute this software for any +* purpose with or without fee is hereby granted, provided that the above +* copyright notice and this permission notice appear in all copies. +* +* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ /* - * SimCList library. See http://mij.oltrelinux.com/devel/simclist - */ +* SimCList library. See http://mij.oltrelinux.com/devel/simclist +*/ /* SimCList implementation, version 1.6 */ #include #include #include -#include /* for setting errno */ +#include /* for setting errno */ #include #ifndef _WIN32 /* not in Windows! */ -#include -#include -#else -//#include +# include +# include #endif #ifndef SIMCLIST_NO_DUMPRESTORE /* includes for dump/restore */ -#include -#include /* for READ_ERRCHECK() and write() */ -#include /* for open() etc */ -#ifndef _WIN32 -#include /* for htons() on UNIX */ -#else -#include /* for htons() on Windows */ -#endif +# include +# include /* for READ_ERRCHECK() and write() */ +# include /* for open() etc */ +# ifndef _WIN32 +# include /* for htons() on UNIX */ +# else +# include /* for htons() on Windows */ +# endif #endif /* disable asserts */ #ifndef SIMCLIST_DEBUG -#ifndef NDEBUG #define NDEBUG #endif -#endif #include -#include /* for open()'s access modes S_IRUSR etc */ +#include /* for open()'s access modes S_IRUSR etc */ #include #if defined(_MSC_VER) || defined(__MINGW32__) @@ -63,8 +59,7 @@ #ifdef _MSC_VER #pragma comment(lib, "Winmm.lib") #endif -int gettimeofday(struct timeval *tp, void *tzp) -{ +int gettimeofday(struct timeval *tp, void *tzp) { DWORD t; /* XSI says: "If tzp is not a null pointer, the behavior is unspecified" */ @@ -80,48 +75,48 @@ int gettimeofday(struct timeval *tp, void *tzp) /* work around lack of inttypes.h support in broken Microsoft Visual Studio compilers */ #if !defined(_WIN32) || !defined(_MSC_VER) -#include /* (u)int*_t */ +# include /* (u)int*_t */ #else -#include -typedef UINT8 uint8_t; -typedef UINT16 uint16_t; +# include +typedef UINT8 uint8_t; +typedef UINT16 uint16_t; typedef ULONG32 uint32_t; -typedef UINT64 uint64_t; -typedef INT8 int8_t; -typedef INT16 int16_t; -typedef LONG32 int32_t; -typedef INT64 int64_t; +typedef UINT64 uint64_t; +typedef INT8 int8_t; +typedef INT16 int16_t; +typedef LONG32 int32_t; +typedef INT64 int64_t; #endif /* define some commodity macros for Dump/Restore functionality */ #ifndef SIMCLIST_NO_DUMPRESTORE /* write() decorated with error checking logic */ -#define WRITE_ERRCHECK(fd, msgbuf, msglen) do { \ - if (write(fd, msgbuf, msglen) < 0) return -1; \ - } while (0); +#define WRITE_ERRCHECK(fd, msgbuf, msglen) do { \ + if (write(fd, msgbuf, msglen) < 0) return -1; \ + } while (0); /* READ_ERRCHECK() decorated with error checking logic */ -#define READ_ERRCHECK(fd, msgbuf, msglen) do { \ - if (read(fd, msgbuf, msglen) != msglen) { \ - /*errno = EPROTO;*/ \ - return -1; \ - } \ - } while (0); +#define READ_ERRCHECK(fd, msgbuf, msglen) do { \ + if (read(fd, msgbuf, msglen) != msglen) { \ + /*errno = EPROTO;*/ \ + return -1; \ + } \ + } while (0); /* convert 64bit integers from host to network format */ -#define hton64(x) ( \ - htons(1) == 1 ? \ - (uint64_t)x /* big endian */ \ - : /* little endian */ \ - ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \ - (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \ - (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \ - (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \ - (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \ - (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \ - (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \ - (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) \ - ) +#define hton64(x) (\ + htons(1) == 1 ? \ + (uint64_t)x /* big endian */ \ + : /* little endian */ \ + ((uint64_t)((((uint64_t)(x) & 0xff00000000000000ULL) >> 56) | \ + (((uint64_t)(x) & 0x00ff000000000000ULL) >> 40) | \ + (((uint64_t)(x) & 0x0000ff0000000000ULL) >> 24) | \ + (((uint64_t)(x) & 0x000000ff00000000ULL) >> 8) | \ + (((uint64_t)(x) & 0x00000000ff000000ULL) << 8) | \ + (((uint64_t)(x) & 0x0000000000ff0000ULL) << 24) | \ + (((uint64_t)(x) & 0x000000000000ff00ULL) << 40) | \ + (((uint64_t)(x) & 0x00000000000000ffULL) << 56))) \ + ) /* convert 64bit integers from network to host format */ #define ntoh64(x) (hton64(x)) @@ -134,35 +129,35 @@ typedef INT64 int64_t; #ifdef SIMCLIST_WITH_THREADS /* limit (approx) to the number of threads running - * for threaded operations. Only meant when - * SIMCLIST_WITH_THREADS is defined */ +* for threaded operations. Only meant when +* SIMCLIST_WITH_THREADS is defined */ #define SIMCLIST_MAXTHREADS 2 #endif /* - * how many elems to keep as spare. During a deletion, an element - * can be saved in a "free-list", not free()d immediately. When - * latter insertions are performed, spare elems can be used instead - * of malloc()ing new elems. - * - * about this param, some values for appending - * 10 million elems into an empty list: - * (#, time[sec], gain[%], gain/no[%]) - * 0 2,164 0,00 0,00 <-- feature disabled - * 1 1,815 34,9 34,9 - * 2 1,446 71,8 35,9 <-- MAX gain/no - * 3 1,347 81,7 27,23 - * 5 1,213 95,1 19,02 - * 8 1,064 110,0 13,75 - * 10 1,015 114,9 11,49 <-- MAX gain w/ likely sol - * 15 1,019 114,5 7,63 - * 25 0,985 117,9 4,72 - * 50 1,088 107,6 2,15 - * 75 1,016 114,8 1,53 - * 100 0,988 117,6 1,18 - * 150 1,022 114,2 0,76 - * 200 0,939 122,5 0,61 <-- MIN time - */ +* how many elems to keep as spare. During a deletion, an element +* can be saved in a "free-list", not free()d immediately. When +* latter insertions are performed, spare elems can be used instead +* of malloc()ing new elems. +* +* about this param, some values for appending +* 10 million elems into an empty list: +* (#, time[sec], gain[%], gain/no[%]) +* 0 2,164 0,00 0,00 <-- feature disabled +* 1 1,815 34,9 34,9 +* 2 1,446 71,8 35,9 <-- MAX gain/no +* 3 1,347 81,7 27,23 +* 5 1,213 95,1 19,02 +* 8 1,064 110,0 13,75 +* 10 1,015 114,9 11,49 <-- MAX gain w/ likely sol +* 15 1,019 114,5 7,63 +* 25 0,985 117,9 4,72 +* 50 1,088 107,6 2,15 +* 75 1,016 114,8 1,53 +* 100 0,988 117,6 1,18 +* 150 1,022 114,2 0,76 +* 200 0,939 122,5 0,61 <-- MIN time +*/ #ifndef SIMCLIST_MAX_SPARE_ELEMS #define SIMCLIST_MAX_SPARE_ELEMS 5 #endif @@ -180,21 +175,21 @@ typedef INT64 int64_t; /* list dump declarations */ -#define SIMCLIST_DUMPFORMAT_VERSION 1 /* (short integer) version of fileformat managed by _dump* and _restore* functions */ +#define SIMCLIST_DUMPFORMAT_VERSION 1 /* (short integer) version of fileformat managed by _dump* and _restore* functions */ -#define SIMCLIST_DUMPFORMAT_HEADERLEN 30 /* length of the header */ +#define SIMCLIST_DUMPFORMAT_HEADERLEN 30 /* length of the header */ /* header for a list dump */ struct list_dump_header_s { - uint16_t ver; /* version */ - int32_t timestamp_sec; /* dump timestamp, seconds since UNIX Epoch */ - int32_t timestamp_usec; /* dump timestamp, microseconds since timestamp_sec */ - int32_t rndterm; /* random value terminator -- terminates the data sequence */ + uint16_t ver; /* version */ + int32_t timestamp_sec; /* dump timestamp, seconds since UNIX Epoch */ + int32_t timestamp_usec; /* dump timestamp, microseconds since timestamp_sec */ + int32_t rndterm; /* random value terminator -- terminates the data sequence */ - uint32_t totlistlen; /* sum of every element' size, bytes */ - uint32_t numels; /* number of elements */ - uint32_t elemlen; /* bytes length of an element, for constant-size lists, <= 0 otherwise */ - int32_t listhash; /* hash of the list at the time of dumping, or 0 if to be ignored */ + uint32_t totlistlen; /* sum of every element' size, bytes */ + uint32_t numels; /* number of elements */ + uint32_t elemlen; /* bytes length of an element, for constant-size lists, <= 0 otherwise */ + int32_t listhash; /* hash of the list at the time of dumping, or 0 if to be ignored */ }; @@ -214,73 +209,72 @@ static int list_attrOk(const list_t *restrict l); #endif /* do not inline, this is recursive */ -static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int first, struct list_entry_s *fel, unsigned int last, struct list_entry_s *lel); +static void list_sort_quicksort(list_t *restrict l, int versus, + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel); static inline void list_sort_selectionsort(list_t *restrict l, int versus, - unsigned int first, struct list_entry_s *fel, unsigned int last, struct list_entry_s *lel); + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel); static void *list_get_minmax(const list_t *restrict l, int versus); static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart); /* - * Random Number Generator - * - * The user is expected to seed the RNG (ie call srand()) if - * SIMCLIST_SYSTEM_RNG is defined. - * - * Otherwise, a self-contained RNG based on LCG is used; see - * http://en.wikipedia.org/wiki/Linear_congruential_generator . - * - * Facts pro local RNG: - * 1. no need for the user to call srand() on his own - * 2. very fast, possibly faster than OS - * 3. avoid interference with user's RNG - * - * Facts pro system RNG: - * 1. may be more accurate (irrelevant for SimCList randno purposes) - * 2. why reinvent the wheel - * - * Default to local RNG for user's ease of use. - */ +* Random Number Generator +* +* The user is expected to seed the RNG (ie call srand()) if +* SIMCLIST_SYSTEM_RNG is defined. +* +* Otherwise, a self-contained RNG based on LCG is used; see +* http://en.wikipedia.org/wiki/Linear_congruential_generator . +* +* Facts pro local RNG: +* 1. no need for the user to call srand() on his own +* 2. very fast, possibly faster than OS +* 3. avoid interference with user's RNG +* +* Facts pro system RNG: +* 1. may be more accurate (irrelevant for SimCList randno purposes) +* 2. why reinvent the wheel +* +* Default to local RNG for user's ease of use. +*/ #ifdef SIMCLIST_SYSTEM_RNG /* keep track whether we initialized already (non-0) or not (0) */ static unsigned random_seed = 0; /* use local RNG */ -static inline void seed_random(void) -{ +static inline void seed_random(void) { if (random_seed == 0) - random_seed = (unsigned) getpid() ^ (unsigned) time(NULL); + random_seed = (unsigned)getpid() ^ (unsigned)time(NULL); } -static inline long get_random(void) -{ +static inline long get_random(void) { random_seed = (1664525 * random_seed + 1013904223); return random_seed; } #else /* use OS's random generator */ -#define seed_random() -#define get_random() (rand()) +# define seed_random() +# define get_random() (rand()) #endif /* list initialization */ -KS_DECLARE(int) list_init(list_t *restrict l) -{ - if (l == NULL) - return -1; +int list_init(list_t *restrict l) { + if (l == NULL) return -1; seed_random(); l->numels = 0; /* head/tail sentinels and mid pointer */ - l->head_sentinel = (struct list_entry_s *) malloc(sizeof(struct list_entry_s)); - l->tail_sentinel = (struct list_entry_s *) malloc(sizeof(struct list_entry_s)); + l->head_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); + l->tail_sentinel = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); l->head_sentinel->next = l->tail_sentinel; l->tail_sentinel->prev = l->head_sentinel; l->head_sentinel->prev = l->tail_sentinel->next = l->mid = NULL; @@ -292,7 +286,7 @@ KS_DECLARE(int) list_init(list_t *restrict l) l->iter_curentry = NULL; /* free-list attributes */ - l->spareels = (struct list_entry_s **) malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *)); + l->spareels = (struct list_entry_s **)malloc(SIMCLIST_MAX_SPARE_ELEMS * sizeof(struct list_entry_s *)); l->spareelsnum = 0; #ifdef SIMCLIST_WITH_THREADS @@ -307,8 +301,7 @@ KS_DECLARE(int) list_init(list_t *restrict l) return 0; } -KS_DECLARE(void) list_destroy(list_t *restrict l) -{ +void list_destroy(list_t *restrict l) { unsigned int i; list_clear(l); @@ -320,8 +313,7 @@ KS_DECLARE(void) list_destroy(list_t *restrict l) free(l->tail_sentinel); } -int list_attributes_setdefaults(list_t *restrict l) -{ +int list_attributes_setdefaults(list_t *restrict l) { l->attrs.comparator = NULL; l->attrs.seeker = NULL; @@ -341,10 +333,8 @@ int list_attributes_setdefaults(list_t *restrict l) } /* setting list properties */ -KS_DECLARE(int) list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun) -{ - if (l == NULL) - return -1; +int list_attributes_comparator(list_t *restrict l, element_comparator comparator_fun) { + if (l == NULL) return -1; l->attrs.comparator = comparator_fun; @@ -353,10 +343,8 @@ KS_DECLARE(int) list_attributes_comparator(list_t *restrict l, element_comparato return 0; } -KS_DECLARE(int) list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) -{ - if (l == NULL) - return -1; +int list_attributes_seeker(list_t *restrict l, element_seeker seeker_fun) { + if (l == NULL) return -1; l->attrs.seeker = seeker_fun; assert(list_attrOk(l)); @@ -364,10 +352,8 @@ KS_DECLARE(int) list_attributes_seeker(list_t *restrict l, element_seeker seeker return 0; } -KS_DECLARE(int) list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data) -{ - if (l == NULL || (metric_fun == NULL && copy_data != 0)) - return -1; +int list_attributes_copy(list_t *restrict l, element_meter metric_fun, int copy_data) { + if (l == NULL || (metric_fun == NULL && copy_data != 0)) return -1; l->attrs.meter = metric_fun; l->attrs.copy_data = copy_data; @@ -377,53 +363,43 @@ KS_DECLARE(int) list_attributes_copy(list_t *restrict l, element_meter metric_fu return 0; } -KS_DECLARE(int) list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun) -{ - if (l == NULL) - return -1; +int list_attributes_hash_computer(list_t *restrict l, element_hash_computer hash_computer_fun) { + if (l == NULL) return -1; l->attrs.hasher = hash_computer_fun; assert(list_attrOk(l)); return 0; } -KS_DECLARE(int) list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun) -{ - if (l == NULL) - return -1; +int list_attributes_serializer(list_t *restrict l, element_serializer serializer_fun) { + if (l == NULL) return -1; l->attrs.serializer = serializer_fun; assert(list_attrOk(l)); return 0; } -KS_DECLARE(int) list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun) -{ - if (l == NULL) - return -1; +int list_attributes_unserializer(list_t *restrict l, element_unserializer unserializer_fun) { + if (l == NULL) return -1; l->attrs.unserializer = unserializer_fun; assert(list_attrOk(l)); return 0; } -KS_DECLARE(int) list_append(list_t *restrict l, const void *data) -{ +int list_append(list_t *restrict l, const void *data) { return list_insert_at(l, data, l->numels); } -KS_DECLARE(int) list_prepend(list_t *restrict l, const void *data) -{ +int list_prepend(list_t *restrict l, const void *data) { return list_insert_at(l, data, 0); } -KS_DECLARE(void *) list_fetch(list_t *restrict l) -{ +void *list_fetch(list_t *restrict l) { return list_extract_at(l, 0); } -KS_DECLARE(void *) list_get_at(const list_t *restrict l, unsigned int pos) -{ +void *list_get_at(const list_t *restrict l, unsigned int pos) { struct list_entry_s *tmp; tmp = list_findpos(l, pos); @@ -431,20 +407,17 @@ KS_DECLARE(void *) list_get_at(const list_t *restrict l, unsigned int pos) return (tmp != NULL ? tmp->data : NULL); } -KS_DECLARE(void *) list_get_max(const list_t *restrict l) -{ +void *list_get_max(const list_t *restrict l) { return list_get_minmax(l, +1); } -KS_DECLARE(void *) list_get_min(const list_t *restrict l) -{ +void *list_get_min(const list_t *restrict l) { return list_get_minmax(l, -1); } /* REQUIRES {list->numels >= 1} - * return the min (versus < 0) or max value (v > 0) in l */ -static void *list_get_minmax(const list_t *restrict l, int versus) -{ +* return the min (versus < 0) or max value (v > 0) in l */ +static void *list_get_minmax(const list_t *restrict l, int versus) { void *curminmax; struct list_entry_s *s; @@ -461,27 +434,28 @@ static void *list_get_minmax(const list_t *restrict l, int versus) } /* set tmp to point to element at index posstart in l */ -static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart) -{ +static inline struct list_entry_s *list_findpos(const list_t *restrict l, int posstart) { struct list_entry_s *ptr; float x; int i; /* accept 1 slot overflow for fetching head and tail sentinels */ - if (posstart < -1 || posstart > (int) l->numels) - return NULL; + if (posstart < -1 || posstart >(int)l->numels) return NULL; - x = (float) (posstart + 1) / l->numels; + x = (float)(posstart + 1) / l->numels; if (x <= 0.25) { /* first quarter: get to posstart from head */ for (i = -1, ptr = l->head_sentinel; i < posstart; ptr = ptr->next, i++); - } else if (x < 0.5) { + } + else if (x < 0.5) { /* second quarter: get to posstart from mid */ for (i = (l->numels - 1) / 2, ptr = l->mid; i > posstart; ptr = ptr->prev, i--); - } else if (x <= 0.75) { + } + else if (x <= 0.75) { /* third quarter: get to posstart from mid */ for (i = (l->numels - 1) / 2, ptr = l->mid; i < posstart; ptr = ptr->next, i++); - } else { + } + else { /* fourth quarter: get to posstart from tail */ for (i = l->numels, ptr = l->tail_sentinel; i > posstart; ptr = ptr->prev, i--); } @@ -489,18 +463,16 @@ static inline struct list_entry_s *list_findpos(const list_t *restrict l, int po return ptr; } -KS_DECLARE(void *) list_extract_at(list_t *restrict l, unsigned int pos) -{ +void *list_extract_at(list_t *restrict l, unsigned int pos) { struct list_entry_s *tmp; void *data; - if (l->iter_active || pos >= l->numels) - return NULL; + if (l->iter_active || pos >= l->numels) return NULL; tmp = list_findpos(l, pos); data = tmp->data; - tmp->data = NULL; /* save data from list_drop_elem() free() */ + tmp->data = NULL; /* save data from list_drop_elem() free() */ list_drop_elem(l, tmp, pos); l->numels--; @@ -509,19 +481,18 @@ KS_DECLARE(void *) list_extract_at(list_t *restrict l, unsigned int pos) return data; } -KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned int pos) -{ +int list_insert_at(list_t *restrict l, const void *data, unsigned int pos) { struct list_entry_s *lent, *succ, *prec; - if (l->iter_active || pos > l->numels) - return -1; + if (l->iter_active || pos > l->numels) return -1; /* this code optimizes malloc() with a free-list */ if (l->spareelsnum > 0) { lent = l->spareels[l->spareelsnum - 1]; l->spareelsnum--; - } else { - lent = (struct list_entry_s *) malloc(sizeof(struct list_entry_s)); + } + else { + lent = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); if (lent == NULL) return -1; } @@ -529,10 +500,11 @@ KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned in if (l->attrs.copy_data) { /* make room for user' data (has to be copied) */ size_t datalen = l->attrs.meter(data); - lent->data = (struct list_entry_s *) malloc(datalen); + lent->data = (struct list_entry_s *)malloc(datalen); memcpy(lent->data, data, datalen); - } else { - lent->data = (void *) data; + } + else { + lent->data = (void*)data; } /* actually append element */ @@ -547,14 +519,14 @@ KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned in l->numels++; /* fix mid pointer */ - if (l->numels == 1) { /* first element, set pointer */ + if (l->numels == 1) { /* first element, set pointer */ l->mid = lent; - } else if (l->numels % 2) { /* now odd */ - if (pos >= (l->numels - 1) / 2) - l->mid = l->mid->next; - } else { /* now even */ - if (pos <= (l->numels - 1) / 2) - l->mid = l->mid->prev; + } + else if (l->numels % 2) { /* now odd */ + if (pos >= (l->numels - 1) / 2) l->mid = l->mid->next; + } + else { /* now even */ + if (pos <= (l->numels - 1) / 2) l->mid = l->mid->prev; } assert(list_repOk(l)); @@ -562,8 +534,7 @@ KS_DECLARE(int) list_insert_at(list_t *restrict l, const void *data, unsigned in return 1; } -KS_DECLARE(int) list_delete(list_t *restrict l, const void *data) -{ +int list_delete(list_t *restrict l, const void *data) { int pos, r; pos = list_locate(l, data); @@ -579,13 +550,11 @@ KS_DECLARE(int) list_delete(list_t *restrict l, const void *data) return 0; } -KS_DECLARE(int) list_delete_at(list_t *restrict l, unsigned int pos) -{ +int list_delete_at(list_t *restrict l, unsigned int pos) { struct list_entry_s *delendo; - if (l->iter_active || pos >= l->numels) - return -1; + if (l->iter_active || pos >= l->numels) return -1; delendo = list_findpos(l, pos); @@ -596,35 +565,33 @@ KS_DECLARE(int) list_delete_at(list_t *restrict l, unsigned int pos) assert(list_repOk(l)); - return 0; + return 0; } -KS_DECLARE(int) list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend) -{ +int list_delete_range(list_t *restrict l, unsigned int posstart, unsigned int posend) { struct list_entry_s *lastvalid, *tmp, *tmp2; unsigned int numdel, midposafter, i; int movedx; - if (l->iter_active || posend < posstart || posend >= l->numels) - return -1; + if (l->iter_active || posend < posstart || posend >= l->numels) return -1; numdel = posend - posstart + 1; - if (numdel == l->numels) - return list_clear(l); + if (numdel == l->numels) return list_clear(l); - tmp = list_findpos(l, posstart); /* first el to be deleted */ - lastvalid = tmp->prev; /* last valid element */ + tmp = list_findpos(l, posstart); /* first el to be deleted */ + lastvalid = tmp->prev; /* last valid element */ midposafter = (l->numels - 1 - numdel) / 2; midposafter = midposafter < posstart ? midposafter : midposafter + numdel; movedx = midposafter - (l->numels - 1) / 2; - if (movedx > 0) { /* move right */ - for (i = 0; i < (unsigned int) movedx; l->mid = l->mid->next, i++); - } else { /* move left */ + if (movedx > 0) { /* move right */ + for (i = 0; i < (unsigned int)movedx; l->mid = l->mid->next, i++); + } + else { /* move left */ movedx = -movedx; - for (i = 0; i < (unsigned int) movedx; l->mid = l->mid->prev, i++); + for (i = 0; i < (unsigned int)movedx; l->mid = l->mid->prev, i++); } assert(posstart == 0 || lastvalid != l->head_sentinel); @@ -634,22 +601,24 @@ KS_DECLARE(int) list_delete_range(list_t *restrict l, unsigned int posstart, uns for (; i <= posend; i++) { tmp2 = tmp; tmp = tmp->next; - if (tmp2->data != NULL) - free(tmp2->data); + if (tmp2->data != NULL) free(tmp2->data); if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) { l->spareels[l->spareelsnum++] = tmp2; - } else { + } + else { free(tmp2); } } - } else { + } + else { /* only free containers */ for (; i <= posend; i++) { tmp2 = tmp; tmp = tmp->next; if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) { l->spareels[l->spareelsnum++] = tmp2; - } else { + } + else { free(tmp2); } } @@ -666,36 +635,33 @@ KS_DECLARE(int) list_delete_range(list_t *restrict l, unsigned int posstart, uns return numdel; } -KS_DECLARE(int) list_clear(list_t *restrict l) -{ +int list_clear(list_t *restrict l) { struct list_entry_s *s; unsigned int numels; /* will be returned */ numels = l->numels; - if (l->iter_active) - return -1; + if (l->iter_active) return -1; - if (l->attrs.copy_data) { /* also free user data */ - /* spare a loop conditional with two loops: spareing elems and freeing elems */ + if (l->attrs.copy_data) { /* also free user data */ + /* spare a loop conditional with two loops: spareing elems and freeing elems */ for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) { /* move elements as spares as long as there is room */ - if (s->data != NULL) - free(s->data); + if (s->data != NULL) free(s->data); l->spareels[l->spareelsnum++] = s; } while (s != l->tail_sentinel) { /* free the remaining elems */ - if (s->data != NULL) - free(s->data); + if (s->data != NULL) free(s->data); s = s->next; free(s->prev); } l->head_sentinel->next = l->tail_sentinel; l->tail_sentinel->prev = l->head_sentinel; - } else { /* only free element containers */ - /* spare a loop conditional with two loops: spareing elems and freeing elems */ + } + else { /* only free element containers */ + /* spare a loop conditional with two loops: spareing elems and freeing elems */ for (s = l->head_sentinel->next; l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS && s != l->tail_sentinel; s = s->next) { /* move elements as spares as long as there is room */ l->spareels[l->spareelsnum++] = s; @@ -716,62 +682,52 @@ KS_DECLARE(int) list_clear(list_t *restrict l) return numels; } -KS_DECLARE(unsigned int) list_size(const list_t *restrict l) -{ +unsigned int list_size(const list_t *restrict l) { return l->numels; } -KS_DECLARE(int) list_empty(const list_t *restrict l) -{ +int list_empty(const list_t *restrict l) { return (l->numels == 0); } -KS_DECLARE(int) list_locate(const list_t *restrict l, const void *data) -{ +int list_locate(const list_t *restrict l, const void *data) { struct list_entry_s *el; int pos = 0; if (l->attrs.comparator != NULL) { /* use comparator */ for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) { - if (l->attrs.comparator(data, el->data) == 0) - break; - } - } else { - /* compare references */ - for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) { - if (el->data == data) - break; + if (l->attrs.comparator(data, el->data) == 0) break; } } - if (el == l->tail_sentinel) - return -1; + else { + /* compare references */ + for (el = l->head_sentinel->next; el != l->tail_sentinel; el = el->next, pos++) { + if (el->data == data) break; + } + } + if (el == l->tail_sentinel) return -1; return pos; } -KS_DECLARE(void *) list_seek(list_t *restrict l, const void *indicator) -{ +void *list_seek(list_t *restrict l, const void *indicator) { const struct list_entry_s *iter; - if (l->attrs.seeker == NULL) - return NULL; + if (l->attrs.seeker == NULL) return NULL; for (iter = l->head_sentinel->next; iter != l->tail_sentinel; iter = iter->next) { - if (l->attrs.seeker(iter->data, indicator) != 0) - return iter->data; + if (l->attrs.seeker(iter->data, indicator) != 0) return iter->data; } return NULL; } -KS_DECLARE(int) list_contains(const list_t *restrict l, const void *data) -{ +int list_contains(const list_t *restrict l, const void *data) { return (list_locate(l, data) >= 0); } -KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) -{ +int list_concat(const list_t *l1, const list_t *l2, list_t *restrict dest) { struct list_entry_s *el, *srcel; unsigned int cnt; int err; @@ -790,17 +746,17 @@ KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict srcel = l1->head_sentinel->next; el = dest->head_sentinel; while (srcel != l1->tail_sentinel) { - el->next = (struct list_entry_s *) malloc(sizeof(struct list_entry_s)); + el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); el->next->prev = el; el = el->next; el->data = srcel->data; srcel = srcel->next; } - dest->mid = el; /* approximate position (adjust later) */ - /* copy list 2 */ + dest->mid = el; /* approximate position (adjust later) */ + /* copy list 2 */ srcel = l2->head_sentinel->next; while (srcel != l2->tail_sentinel) { - el->next = (struct list_entry_s *) malloc(sizeof(struct list_entry_s)); + el->next = (struct list_entry_s *)malloc(sizeof(struct list_entry_s)); el->next->prev = el; el = el->next; el->data = srcel->data; @@ -811,14 +767,13 @@ KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict /* fix mid pointer */ err = l2->numels - l1->numels; - if ((err + 1) / 2 > 0) { /* correct pos RIGHT (err-1)/2 moves */ + if ((err + 1) / 2 > 0) { /* correct pos RIGHT (err-1)/2 moves */ err = (err + 1) / 2; - for (cnt = 0; cnt < (unsigned int) err; cnt++) - dest->mid = dest->mid->next; - } else if (err / 2 < 0) { /* correct pos LEFT (err/2)-1 moves */ + for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->next; + } + else if (err / 2 < 0) { /* correct pos LEFT (err/2)-1 moves */ err = -err / 2; - for (cnt = 0; cnt < (unsigned int) err; cnt++) - dest->mid = dest->mid->prev; + for (cnt = 0; cnt < (unsigned int)err; cnt++) dest->mid = dest->mid->prev; } assert(!(list_repOk(l1) && list_repOk(l2)) || list_repOk(dest)); @@ -826,9 +781,8 @@ KS_DECLARE(int) list_concat(const list_t *l1, const list_t *l2, list_t *restrict return 0; } -KS_DECLARE(int) list_sort(list_t *restrict l, int versus) -{ - if (l->iter_active || l->attrs.comparator == NULL) /* cannot modify list in the middle of an iteration */ +int list_sort(list_t *restrict l, int versus) { + if (l->iter_active || l->attrs.comparator == NULL) /* cannot modify list in the middle of an iteration */ return -1; if (l->numels <= 1) @@ -846,9 +800,8 @@ struct list_sort_wrappedparams { struct list_entry_s *fel, *lel; }; -static void *list_sort_quicksort_threadwrapper(void *wrapped_params) -{ - struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *) wrapped_params; +static void *list_sort_quicksort_threadwrapper(void *wrapped_params) { + struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)wrapped_params; list_sort_quicksort(wp->l, wp->versus, wp->first, wp->fel, wp->last, wp->lel); free(wp); pthread_exit(NULL); @@ -857,20 +810,19 @@ static void *list_sort_quicksort_threadwrapper(void *wrapped_params) #endif static inline void list_sort_selectionsort(list_t *restrict l, int versus, - unsigned int first, struct list_entry_s *fel, unsigned int last, struct list_entry_s *lel) -{ + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel) { struct list_entry_s *cursor, *toswap, *firstunsorted; void *tmpdata; - if (last <= first) /* <= 1-element lists are always sorted */ + if (last <= first) /* <= 1-element lists are always sorted */ return; for (firstunsorted = fel; firstunsorted != lel; firstunsorted = firstunsorted->next) { /* find min or max in the remainder of the list */ for (toswap = firstunsorted, cursor = firstunsorted->next; cursor != lel->next; cursor = cursor->next) - if (l->attrs.comparator(toswap->data, cursor->data) * -versus > 0) - toswap = cursor; - if (toswap != firstunsorted) { /* swap firstunsorted with toswap */ + if (l->attrs.comparator(toswap->data, cursor->data) * -versus > 0) toswap = cursor; + if (toswap != firstunsorted) { /* swap firstunsorted with toswap */ tmpdata = firstunsorted->data; firstunsorted->data = toswap->data; toswap->data = tmpdata; @@ -878,8 +830,9 @@ static inline void list_sort_selectionsort(list_t *restrict l, int versus, } } -static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int first, struct list_entry_s *fel, unsigned int last, struct list_entry_s *lel) -{ +static void list_sort_quicksort(list_t *restrict l, int versus, + unsigned int first, struct list_entry_s *fel, + unsigned int last, struct list_entry_s *lel) { unsigned int pivotid; unsigned int i; register struct list_entry_s *pivot; @@ -891,7 +844,7 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir #endif - if (last <= first) /* <= 1-element lists are always sorted */ + if (last <= first) /* <= 1-element lists are always sorted */ return; if (last - first + 1 <= SIMCLIST_MINQUICKSORTELS) { @@ -900,8 +853,7 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir } /* base of iteration: one element list */ - if (!(last > first)) - return; + if (!(last > first)) return; pivotid = (get_random() % (last - first + 1)); /* pivotid = (last - first + 1) / 2; */ @@ -909,7 +861,8 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir /* find pivot */ if (pivotid < (last - first + 1) / 2) { for (i = 0, pivot = fel; i < pivotid; pivot = pivot->next, i++); - } else { + } + else { for (i = last - first, pivot = lel; i > pivotid; pivot = pivot->prev, i--); } @@ -934,7 +887,7 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir } /* now either left points to pivot (end run), or right */ - if (right == pivot) { /* left part longer */ + if (right == pivot) { /* left part longer */ while (left != pivot) { if (l->attrs.comparator(left->data, pivot->data) * -versus > 0) { tmpdata = left->data; @@ -943,13 +896,14 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir pivot->data = tmpdata; pivot = pivot->prev; pivotid--; - if (pivot == left) - break; - } else { + if (pivot == left) break; + } + else { left = left->next; } } - } else { /* right part longer */ + } + else { /* right part longer */ while (right != pivot) { if (l->attrs.comparator(right->data, pivot->data) * -versus < 0) { /* move current right before pivot */ @@ -959,9 +913,9 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir pivot->data = tmpdata; pivot = pivot->next; pivotid++; - if (pivot == right) - break; - } else { + if (pivot == right) break; + } + else { right = right->prev; } } @@ -974,7 +928,7 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir if (pivotid > 0) { /* prepare wrapped args, then start thread */ if (l->threadcount < SIMCLIST_MAXTHREADS - 1) { - struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *) malloc(sizeof(struct list_sort_wrappedparams)); + struct list_sort_wrappedparams *wp = (struct list_sort_wrappedparams *)malloc(sizeof(struct list_sort_wrappedparams)); l->threadcount++; traised = 1; wp->l = l; @@ -988,40 +942,34 @@ static void list_sort_quicksort(list_t *restrict l, int versus, unsigned int fir traised = 0; list_sort_quicksort(l, versus, first, fel, first + pivotid - 1, pivot->prev); } - } else { + } + else { list_sort_quicksort(l, versus, first, fel, first + pivotid - 1, pivot->prev); } } - if (first + pivotid < last) - list_sort_quicksort(l, versus, first + pivotid + 1, pivot->next, last, lel); + if (first + pivotid < last) list_sort_quicksort(l, versus, first + pivotid + 1, pivot->next, last, lel); if (traised) { - pthread_join(tid, (void **) NULL); + pthread_join(tid, (void **)NULL); l->threadcount--; } #else - if (pivotid > 0) - list_sort_quicksort(l, versus, first, fel, first + pivotid - 1, pivot->prev); - if (first + pivotid < last) - list_sort_quicksort(l, versus, first + pivotid + 1, pivot->next, last, lel); + if (pivotid > 0) list_sort_quicksort(l, versus, first, fel, first + pivotid - 1, pivot->prev); + if (first + pivotid < last) list_sort_quicksort(l, versus, first + pivotid + 1, pivot->next, last, lel); #endif } -KS_DECLARE(int) list_iterator_start(list_t *restrict l) -{ - if (l->iter_active) - return 0; +int list_iterator_start(list_t *restrict l) { + if (l->iter_active) return 0; l->iter_pos = 0; l->iter_active = 1; l->iter_curentry = l->head_sentinel->next; return 1; } -KS_DECLARE(void *) list_iterator_next(list_t *restrict l) -{ +void *list_iterator_next(list_t *restrict l) { void *toret; - if (!l->iter_active) - return NULL; + if (!l->iter_active) return NULL; toret = l->iter_curentry->data; l->iter_curentry = l->iter_curentry->next; @@ -1030,24 +978,19 @@ KS_DECLARE(void *) list_iterator_next(list_t *restrict l) return toret; } -KS_DECLARE(int) list_iterator_hasnext(const list_t *restrict l) -{ - if (!l->iter_active) - return 0; +int list_iterator_hasnext(const list_t *restrict l) { + if (!l->iter_active) return 0; return (l->iter_pos < l->numels); } -KS_DECLARE(int) list_iterator_stop(list_t *restrict l) -{ - if (!l->iter_active) - return 0; +int list_iterator_stop(list_t *restrict l) { + if (!l->iter_active) return 0; l->iter_pos = 0; l->iter_active = 0; return 1; } -KS_DECLARE(int) list_hash(const list_t *restrict l, list_hash_t *restrict hash) -{ +int list_hash(const list_t *restrict l, list_hash_t *restrict hash) { struct list_entry_s *x; list_hash_t tmphash; @@ -1057,20 +1000,21 @@ KS_DECLARE(int) list_hash(const list_t *restrict l, list_hash_t *restrict hash) if (l->attrs.hasher == NULL) { #ifdef SIMCLIST_ALLOW_LOCATIONBASED_HASHES /* ENABLE WITH CARE !! */ -#warning "Memlocation-based hash is consistent only for testing modification in the same program run." - int i; + #warning "Memlocation-based hash is consistent only for testing modification in the same program run." + int i; /* only use element references */ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { for (i = 0; i < sizeof(x->data); i++) { - tmphash += (tmphash ^ (uintptr_t) x->data); + tmphash += (tmphash ^ (uintptr_t)x->data); } tmphash += tmphash % l->numels; } #else return -1; #endif - } else { + } + else { /* hash each element with the user-given function */ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { tmphash += tmphash ^ l->attrs.hasher(x->data); @@ -1084,8 +1028,7 @@ KS_DECLARE(int) list_hash(const list_t *restrict l, list_hash_t *restrict hash) } #ifndef SIMCLIST_NO_DUMPRESTORE -KS_DECLARE(int) list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) -{ +int list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restrict info) { int32_t terminator_head, terminator_tail; uint32_t elemlen; off_t hop; @@ -1129,9 +1072,10 @@ KS_DECLARE(int) list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restr if (elemlen > 0) { /* constant length, hop by size only */ hop = info->list_size; - } else { + } + else { /* non-constant length, hop by size + all element length blocks */ - hop = info->list_size + elemlen * info->list_numels; + hop = info->list_size + elemlen*info->list_numels; } if (lseek(fd, hop, SEEK_CUR) == -1) { return -1; @@ -1149,13 +1093,11 @@ KS_DECLARE(int) list_dump_getinfo_filedescriptor(int fd, list_dump_info_t *restr return 0; } -KS_DECLARE(int) list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info) -{ +int list_dump_getinfo_file(const char *restrict filename, list_dump_info_t *restrict info) { int fd, ret; fd = open(filename, O_RDONLY, 0); - if (fd < 0) - return -1; + if (fd < 0) return -1; ret = list_dump_getinfo_filedescriptor(fd, info); close(fd); @@ -1163,8 +1105,7 @@ KS_DECLARE(int) list_dump_getinfo_file(const char *restrict filename, list_dump_ return ret; } -KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len) -{ +int list_dump_filedescriptor(const list_t *restrict l, int fd, size_t *restrict len) { struct list_entry_s *x; void *ser_buf; uint32_t bufsize; @@ -1178,16 +1119,16 @@ KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_ /**** DUMP FORMAT **** - [ ver timestamp | totlen numels elemlen hash | DATA ] + [ ver timestamp | totlen numels elemlen hash | DATA ] - where DATA can be: - @ for constant-size list (element size is constant; elemlen > 0) - [ elem elem ... elem ] - @ for other lists (element size dictated by element_meter each time; elemlen <= 0) - [ size elem size elem ... size elem ] + where DATA can be: + @ for constant-size list (element size is constant; elemlen > 0) + [ elem elem ... elem ] + @ for other lists (element size dictated by element_meter each time; elemlen <= 0) + [ size elem size elem ... size elem ] - all integers are encoded in NETWORK BYTE FORMAT - *****/ + all integers are encoded in NETWORK BYTE FORMAT + *****/ /* prepare HEADER */ @@ -1199,7 +1140,7 @@ KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_ header.timestamp_sec = htonl(timeofday.tv_sec); header.timestamp_usec = htonl(timeofday.tv_usec); - header.rndterm = htonl((int32_t) get_random()); + header.rndterm = htonl((int32_t)get_random()); /* total list size is postprocessed afterwards */ @@ -1212,7 +1153,8 @@ KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_ /* could not compute list hash! */ return -1; } - } else { + } + else { header.listhash = htonl(0); } @@ -1228,15 +1170,15 @@ KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_ if (l->numels > 0) { /* SPECULATE that the list has constant element size */ - if (l->attrs.serializer != NULL) { /* user user-specified serializer */ - /* get preliminary length of serialized element in header.elemlen */ + if (l->attrs.serializer != NULL) { /* user user-specified serializer */ + /* get preliminary length of serialized element in header.elemlen */ ser_buf = l->attrs.serializer(l->head_sentinel->next->data, &header.elemlen); free(ser_buf); /* request custom serialization of each element */ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { ser_buf = l->attrs.serializer(x->data, &bufsize); header.totlistlen += bufsize; - if (header.elemlen != 0) { /* continue on speculation */ + if (header.elemlen != 0) { /* continue on speculation */ if (header.elemlen != bufsize) { free(ser_buf); /* constant element length speculation broken! */ @@ -1252,14 +1194,16 @@ KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_ } /* speculation confirmed */ WRITE_ERRCHECK(fd, ser_buf, bufsize); - } else { /* speculation found broken */ + } + else { /* speculation found broken */ WRITE_ERRCHECK(fd, &bufsize, sizeof(size_t)); WRITE_ERRCHECK(fd, ser_buf, bufsize); } free(ser_buf); } - } else if (l->attrs.meter != NULL) { - header.elemlen = (uint32_t) l->attrs.meter(l->head_sentinel->next->data); + } + else if (l->attrs.meter != NULL) { + header.elemlen = (uint32_t)l->attrs.meter(l->head_sentinel->next->data); /* serialize the element straight from its data */ for (x = l->head_sentinel->next; x != l->tail_sentinel; x = x->next) { @@ -1275,7 +1219,8 @@ KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_ continue; } WRITE_ERRCHECK(fd, x->data, bufsize); - } else { + } + else { WRITE_ERRCHECK(fd, &bufsize, sizeof(size_t)); WRITE_ERRCHECK(fd, x->data, bufsize); } @@ -1287,24 +1232,24 @@ KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_ } /* write random terminator */ - WRITE_ERRCHECK(fd, &header.rndterm, sizeof(header.rndterm)); /* list terminator */ + WRITE_ERRCHECK(fd, &header.rndterm, sizeof(header.rndterm)); /* list terminator */ - /* write header */ + /* write header */ lseek(fd, 0, SEEK_SET); - WRITE_ERRCHECK(fd, &header.ver, sizeof(header.ver)); /* version */ - WRITE_ERRCHECK(fd, &header.timestamp_sec, sizeof(header.timestamp_sec)); /* timestamp seconds */ - WRITE_ERRCHECK(fd, &header.timestamp_usec, sizeof(header.timestamp_usec)); /* timestamp microseconds */ - WRITE_ERRCHECK(fd, &header.rndterm, sizeof(header.rndterm)); /* random terminator */ + WRITE_ERRCHECK(fd, &header.ver, sizeof(header.ver)); /* version */ + WRITE_ERRCHECK(fd, &header.timestamp_sec, sizeof(header.timestamp_sec)); /* timestamp seconds */ + WRITE_ERRCHECK(fd, &header.timestamp_usec, sizeof(header.timestamp_usec)); /* timestamp microseconds */ + WRITE_ERRCHECK(fd, &header.rndterm, sizeof(header.rndterm)); /* random terminator */ - WRITE_ERRCHECK(fd, &header.totlistlen, sizeof(header.totlistlen)); /* total length of elements */ - WRITE_ERRCHECK(fd, &header.numels, sizeof(header.numels)); /* number of elements */ - WRITE_ERRCHECK(fd, &header.elemlen, sizeof(header.elemlen)); /* size of each element, or 0 for independent */ - WRITE_ERRCHECK(fd, &header.listhash, sizeof(header.listhash)); /* list hash, or 0 for "ignore" */ + WRITE_ERRCHECK(fd, &header.totlistlen, sizeof(header.totlistlen)); /* total length of elements */ + WRITE_ERRCHECK(fd, &header.numels, sizeof(header.numels)); /* number of elements */ + WRITE_ERRCHECK(fd, &header.elemlen, sizeof(header.elemlen)); /* size of each element, or 0 for independent */ + WRITE_ERRCHECK(fd, &header.listhash, sizeof(header.listhash)); /* list hash, or 0 for "ignore" */ - /* possibly store total written length in "len" */ + /* possibly store total written length in "len" */ if (len != NULL) { *len = sizeof(header) + ntohl(header.totlistlen); } @@ -1312,8 +1257,7 @@ KS_DECLARE(int) list_dump_filedescriptor(const list_t *restrict l, int fd, size_ return 0; } -KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len) -{ +int list_restore_filedescriptor(list_t *restrict l, int fd, size_t *restrict len) { struct list_dump_header_s header; unsigned long cnt; void *buf; @@ -1371,7 +1315,8 @@ KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t * list_append(l, l->attrs.unserializer(buf, &elsize)); totmemorylen += elsize; } - } else { + } + else { /* copy verbatim into memory */ for (cnt = 0; cnt < header.numels; cnt++) { buf = malloc(header.elemlen); @@ -1381,19 +1326,21 @@ KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t * totmemorylen = header.numels * header.elemlen; } totreadlen = header.numels * header.elemlen; - } else { + } + else { /* elements have variable size. Each element is preceded by its size */ if (l->attrs.unserializer != NULL) { /* use unserializer */ for (cnt = 0; cnt < header.numels; cnt++) { READ_ERRCHECK(fd, &elsize, sizeof(elsize)); - buf = malloc((size_t) elsize); + buf = malloc((size_t)elsize); READ_ERRCHECK(fd, buf, elsize); totreadlen += elsize; list_append(l, l->attrs.unserializer(buf, &elsize)); totmemorylen += elsize; } - } else { + } + else { /* copy verbatim into memory */ for (cnt = 0; cnt < header.numels; cnt++) { READ_ERRCHECK(fd, &elsize, sizeof(elsize)); @@ -1406,20 +1353,20 @@ KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t * } } - READ_ERRCHECK(fd, &elsize, sizeof(elsize)); /* read list terminator */ + READ_ERRCHECK(fd, &elsize, sizeof(elsize)); /* read list terminator */ elsize = ntohl(elsize); /* possibly verify the list consistency */ /* wrt hash */ /* don't do that - if (header.listhash != 0 && header.listhash != list_hash(l)) { - errno = ECANCELED; - return -1; - } - */ + if (header.listhash != 0 && header.listhash != list_hash(l)) { + errno = ECANCELED; + return -1; + } + */ /* wrt header */ - if (totreadlen != header.totlistlen && (int32_t) elsize == header.rndterm) { + if (totreadlen != header.totlistlen && (int32_t)elsize == header.rndterm) { errno = EPROTO; return -1; } @@ -1437,8 +1384,7 @@ KS_DECLARE(int) list_restore_filedescriptor(list_t *restrict l, int fd, size_t * return 0; } -KS_DECLARE(int) list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len) -{ +int list_dump_file(const list_t *restrict l, const char *restrict filename, size_t *restrict len) { int fd, oflag, mode; #ifndef _WIN32 @@ -1449,8 +1395,7 @@ KS_DECLARE(int) list_dump_file(const list_t *restrict l, const char *restrict fi mode = _S_IRUSR | _S_IWUSR | _S_IRGRP | _S_IROTH; #endif fd = open(filename, oflag, mode); - if (fd < 0) - return -1; + if (fd < 0) return -1; list_dump_filedescriptor(l, fd, len); close(fd); @@ -1458,13 +1403,11 @@ KS_DECLARE(int) list_dump_file(const list_t *restrict l, const char *restrict fi return 0; } -KS_DECLARE(int) list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len) -{ +int list_restore_file(list_t *restrict l, const char *restrict filename, size_t *restrict len) { int fd; fd = open(filename, O_RDONLY, 0); - if (fd < 0) - return -1; + if (fd < 0) return -1; list_restore_filedescriptor(l, fd, len); close(fd); @@ -1474,21 +1417,17 @@ KS_DECLARE(int) list_restore_file(list_t *restrict l, const char *restrict filen #endif /* ifndef SIMCLIST_NO_DUMPRESTORE */ -static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned int pos) -{ - if (tmp == NULL) - return -1; +static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned int pos) { + if (tmp == NULL) return -1; /* fix mid pointer. This is wrt the PRE situation */ - if (l->numels % 2) { /* now odd */ - /* sort out the base case by hand */ - if (l->numels == 1) - l->mid = NULL; - else if (pos >= l->numels / 2) - l->mid = l->mid->prev; - } else { /* now even */ - if (pos < l->numels / 2) - l->mid = l->mid->next; + if (l->numels % 2) { /* now odd */ + /* sort out the base case by hand */ + if (l->numels == 1) l->mid = NULL; + else if (pos >= l->numels / 2) l->mid = l->mid->prev; + } + else { /* now even */ + if (pos < l->numels / 2) l->mid = l->mid->next; } tmp->prev->next = tmp->next; @@ -1500,7 +1439,8 @@ static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned if (l->spareelsnum < SIMCLIST_MAX_SPARE_ELEMS) { l->spareels[l->spareelsnum++] = tmp; - } else { + } + else { free(tmp); } @@ -1508,49 +1448,66 @@ static int list_drop_elem(list_t *restrict l, struct list_entry_s *tmp, unsigned } /* ready-made comparators and meters */ -#define SIMCLIST_NUMBER_COMPARATOR(type) KS_DECLARE(int) list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); } +#define SIMCLIST_NUMBER_COMPARATOR(type) int list_comparator_##type(const void *a, const void *b) { return( *(type *)a < *(type *)b) - (*(type *)a > *(type *)b); } SIMCLIST_NUMBER_COMPARATOR(int8_t) -SIMCLIST_NUMBER_COMPARATOR(int16_t) SIMCLIST_NUMBER_COMPARATOR(int32_t) SIMCLIST_NUMBER_COMPARATOR(int64_t) - SIMCLIST_NUMBER_COMPARATOR(uint8_t) SIMCLIST_NUMBER_COMPARATOR(uint16_t) SIMCLIST_NUMBER_COMPARATOR(uint32_t) SIMCLIST_NUMBER_COMPARATOR(uint64_t) - SIMCLIST_NUMBER_COMPARATOR(float) SIMCLIST_NUMBER_COMPARATOR(double) +SIMCLIST_NUMBER_COMPARATOR(int16_t) +SIMCLIST_NUMBER_COMPARATOR(int32_t) +SIMCLIST_NUMBER_COMPARATOR(int64_t) -KS_DECLARE(int) list_comparator_string(const void *a, const void *b) -{ - return strcmp((const char *) b, (const char *) a); -} +SIMCLIST_NUMBER_COMPARATOR(uint8_t) +SIMCLIST_NUMBER_COMPARATOR(uint16_t) +SIMCLIST_NUMBER_COMPARATOR(uint32_t) +SIMCLIST_NUMBER_COMPARATOR(uint64_t) + +SIMCLIST_NUMBER_COMPARATOR(float) +SIMCLIST_NUMBER_COMPARATOR(double) + +int list_comparator_string(const void *a, const void *b) { return strcmp((const char *)b, (const char *)a); } /* ready-made metric functions */ -#define SIMCLIST_METER(type) KS_DECLARE(size_t) list_meter_##type(const void *el) { if (el) { /* kill compiler whinge */ } return sizeof(type); } +#define SIMCLIST_METER(type) size_t list_meter_##type(const void *el) { if (el) { /* kill compiler whinge */ } return sizeof(type); } -SIMCLIST_METER(int8_t) SIMCLIST_METER(int16_t) SIMCLIST_METER(int32_t) SIMCLIST_METER(int64_t) - SIMCLIST_METER(uint8_t) SIMCLIST_METER(uint16_t) SIMCLIST_METER(uint32_t) SIMCLIST_METER(uint64_t) - SIMCLIST_METER(float) SIMCLIST_METER(double) +SIMCLIST_METER(int8_t) +SIMCLIST_METER(int16_t) +SIMCLIST_METER(int32_t) +SIMCLIST_METER(int64_t) -KS_DECLARE(size_t) list_meter_string(const void *el) -{ - return strlen((const char *) el) + 1; -} +SIMCLIST_METER(uint8_t) +SIMCLIST_METER(uint16_t) +SIMCLIST_METER(uint32_t) +SIMCLIST_METER(uint64_t) + +SIMCLIST_METER(float) +SIMCLIST_METER(double) + +size_t list_meter_string(const void *el) { return strlen((const char *)el) + 1; } /* ready-made hashing functions */ -#define SIMCLIST_HASHCOMPUTER(type) KS_DECLARE(list_hash_t) list_hashcomputer_##type(const void *el) { return (list_hash_t)(*(type *)el); } +#define SIMCLIST_HASHCOMPUTER(type) list_hash_t list_hashcomputer_##type(const void *el) { return (list_hash_t)(*(type *)el); } -SIMCLIST_HASHCOMPUTER(int8_t) SIMCLIST_HASHCOMPUTER(int16_t) SIMCLIST_HASHCOMPUTER(int32_t) SIMCLIST_HASHCOMPUTER(int64_t) - SIMCLIST_HASHCOMPUTER(uint8_t) SIMCLIST_HASHCOMPUTER(uint16_t) SIMCLIST_HASHCOMPUTER(uint32_t) SIMCLIST_HASHCOMPUTER(uint64_t) - SIMCLIST_HASHCOMPUTER(float) SIMCLIST_HASHCOMPUTER(double) +SIMCLIST_HASHCOMPUTER(int8_t) +SIMCLIST_HASHCOMPUTER(int16_t) +SIMCLIST_HASHCOMPUTER(int32_t) +SIMCLIST_HASHCOMPUTER(int64_t) -KS_DECLARE(list_hash_t) list_hashcomputer_string(const void *el) -{ +SIMCLIST_HASHCOMPUTER(uint8_t) +SIMCLIST_HASHCOMPUTER(uint16_t) +SIMCLIST_HASHCOMPUTER(uint32_t) +SIMCLIST_HASHCOMPUTER(uint64_t) + +SIMCLIST_HASHCOMPUTER(float) +SIMCLIST_HASHCOMPUTER(double) + +list_hash_t list_hashcomputer_string(const void *el) { size_t l; list_hash_t hash = 123; - const char *str = (const char *) el; + const char *str = (const char *)el; char plus; for (l = 0; str[l] != '\0'; l++) { - if (l) - plus = (char)(hash ^ str[l]); - else - plus = (char)(hash ^ (str[l] - str[0])); + if (l) plus = (char)(hash ^ str[l]); + else plus = (char)(hash ^ (str[l] - str[0])); hash += (plus << (CHAR_BIT * (l % sizeof(list_hash_t)))); } @@ -1559,45 +1516,39 @@ KS_DECLARE(list_hash_t) list_hashcomputer_string(const void *el) #ifndef NDEBUG -static int list_repOk(const list_t *restrict l) -{ +static int list_repOk(const list_t *restrict l) { int ok, i; struct list_entry_s *s; ok = (l != NULL) && ( - /* head/tail checks */ - (l->head_sentinel != NULL && l->tail_sentinel != NULL) && - (l->head_sentinel != l->tail_sentinel) && (l->head_sentinel->prev == NULL && l->tail_sentinel->next == NULL) && - /* empty list */ - (l->numels > 0 || (l->mid == NULL && l->head_sentinel->next == l->tail_sentinel && l->tail_sentinel->prev == l->head_sentinel)) - && - /* spare elements checks */ - l->spareelsnum <= SIMCLIST_MAX_SPARE_ELEMS); + /* head/tail checks */ + (l->head_sentinel != NULL && l->tail_sentinel != NULL) && + (l->head_sentinel != l->tail_sentinel) && (l->head_sentinel->prev == NULL && l->tail_sentinel->next == NULL) && + /* empty list */ + (l->numels > 0 || (l->mid == NULL && l->head_sentinel->next == l->tail_sentinel && l->tail_sentinel->prev == l->head_sentinel)) && + /* spare elements checks */ + l->spareelsnum <= SIMCLIST_MAX_SPARE_ELEMS + ); - if (!ok) - return 0; + if (!ok) return 0; if (l->numels >= 1) { /* correct referencing */ - for (i = -1, s = l->head_sentinel; i < (int) (l->numels - 1) / 2 && s->next != NULL; i++, s = s->next) { - if (s->next->prev != s) - break; + for (i = -1, s = l->head_sentinel; i < (int)(l->numels - 1) / 2 && s->next != NULL; i++, s = s->next) { + if (s->next->prev != s) break; } - ok = (i == (int) (l->numels - 1) / 2 && l->mid == s); - if (!ok) - return 0; + ok = (i == (int)(l->numels - 1) / 2 && l->mid == s); + if (!ok) return 0; for (; s->next != NULL; i++, s = s->next) { - if (s->next->prev != s) - break; + if (s->next->prev != s) break; } - ok = (i == (int) l->numels && s == l->tail_sentinel); + ok = (i == (int)l->numels && s == l->tail_sentinel); } return ok; } -static int list_attrOk(const list_t *restrict l) -{ +static int list_attrOk(const list_t *restrict l) { int ok; ok = (l->attrs.copy_data == 0 || l->attrs.meter != NULL); @@ -1606,6 +1557,7 @@ static int list_attrOk(const list_t *restrict l) #endif + /* For Emacs: * Local Variables: * mode:c diff --git a/libs/libks/test/test_thread_pools.c b/libs/libks/test/test_thread_pools.c index 4934357139..d984466777 100644 --- a/libs/libks/test/test_thread_pools.c +++ b/libs/libks/test/test_thread_pools.c @@ -16,7 +16,7 @@ static void *test1_thread(ks_thread_t *thread, void *data) { struct x *mydata = (struct x *) data; - ks_log(KS_LOG_DEBUG, "Thread %d\n", mydata->i); + //ks_log(KS_LOG_DEBUG, "Thread %d\n", mydata->i); ks_sleep(100000); ks_pool_free(mydata->pool, &mydata); return NULL; @@ -37,6 +37,7 @@ static int test1() struct x *data = ks_pool_alloc(pool, sizeof(*data)); data->i = i; data->pool = pool; + ks_sleep(1); ks_thread_pool_add_job(tp, test1_thread, data); }