Few things --- there are:
- Fix bug within index allocator - Removed obsolete locking stuff from allocator - Stupid test added
This commit is contained in:
parent
459ca367a3
commit
d28315dd75
@ -1,6 +1,13 @@
|
|||||||
## Process this file with automake to produce Makefile.in
|
## Process this file with automake to produce Makefile.in
|
||||||
|
|
||||||
SUBDIRS = include lib
|
## options
|
||||||
|
EXTRA =
|
||||||
|
|
||||||
|
if BUILD_TESTS
|
||||||
|
EXTRA += tests
|
||||||
|
endif
|
||||||
|
|
||||||
|
SUBDIRS = include lib $(EXTRA)
|
||||||
|
|
||||||
libtdatadocdir = ${prefix}/doc/libtdata
|
libtdatadocdir = ${prefix}/doc/libtdata
|
||||||
libtdatadoc_DATA = \
|
libtdatadoc_DATA = \
|
||||||
|
11
configure.ac
11
configure.ac
@ -48,15 +48,18 @@ dnl *****************
|
|||||||
dnl ***** options *****
|
dnl ***** options *****
|
||||||
dnl *****************
|
dnl *****************
|
||||||
|
|
||||||
AC_ARG_ENABLE([build_examples],
|
AC_ARG_ENABLE([build_tests],
|
||||||
AS_HELP_STRING([--enable-build-examples], [Enable examples build]))
|
AS_HELP_STRING([--enable-build-tests], [Enable build tests]))
|
||||||
|
|
||||||
AS_IF([test "x$enable_build_examples" = "xyes"], [
|
AS_IF([test "x$enable_build_tests" = "xyes"], [
|
||||||
AC_DEFINE([BUILD_EXAMPLES], 1, [build of examples enabled])
|
AC_DEFINE([BUILD_TESTS], 1, [build of tests enabled])
|
||||||
])
|
])
|
||||||
|
|
||||||
|
AM_CONDITIONAL(BUILD_TESTS, test "x$enable_build_tests" = "xyes")
|
||||||
|
|
||||||
AC_OUTPUT([
|
AC_OUTPUT([
|
||||||
Makefile
|
Makefile
|
||||||
lib/libtdata.pc
|
lib/libtdata.pc
|
||||||
lib/Makefile
|
lib/Makefile
|
||||||
|
tests/Makefile
|
||||||
include/Makefile])
|
include/Makefile])
|
||||||
|
@ -28,11 +28,10 @@
|
|||||||
/* TODO: add arch deps */
|
/* TODO: add arch deps */
|
||||||
//#include <arch/bitwise.h>
|
//#include <arch/bitwise.h>
|
||||||
|
|
||||||
/* TODO: add linux headers tests */
|
#ifdef BUILD_HOST_32BIT
|
||||||
#include <asm-generic/bitsperlong.h>
|
#define BITS_PER_LONG 32
|
||||||
|
#else
|
||||||
#ifdef __BITS_PER_LONG
|
#define BITS_PER_LONG 64
|
||||||
#define BITS_PER_LONG __BITS_PER_LONG
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BITS_PER_LONG == 64
|
#if BITS_PER_LONG == 64
|
||||||
@ -59,7 +58,7 @@ typedef struct __bitmap {
|
|||||||
#ifndef ARCH_BIT_SET
|
#ifndef ARCH_BIT_SET
|
||||||
static inline void bit_set(void *bitmap, int bit)
|
static inline void bit_set(void *bitmap, int bit)
|
||||||
{
|
{
|
||||||
*(unsigned long *)bitmap |= (1 << bit);
|
*(unsigned long *)bitmap |= (1UL << bit);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define bit_set(bitmap, bit) arch_bit_set(bitmap, bit)
|
#define bit_set(bitmap, bit) arch_bit_set(bitmap, bit)
|
||||||
@ -76,7 +75,7 @@ static inline void bit_set(void *bitmap, int bit)
|
|||||||
#ifndef ARCH_BIT_CLEAR
|
#ifndef ARCH_BIT_CLEAR
|
||||||
static inline void bit_clear(void *bitmap, int bit)
|
static inline void bit_clear(void *bitmap, int bit)
|
||||||
{
|
{
|
||||||
*(unsigned long *)bitmap &= ~(1 << bit);
|
*(unsigned long *)bitmap &= ~(1UL << bit);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define bit_clear(bitmap, bit) arch_bit_clear(bitmap, bit)
|
#define bit_clear(bitmap, bit) arch_bit_clear(bitmap, bit)
|
||||||
@ -93,7 +92,7 @@ static inline void bit_clear(void *bitmap, int bit)
|
|||||||
#ifndef ARCH_BIT_TOGGLE
|
#ifndef ARCH_BIT_TOGGLE
|
||||||
static inline void bit_toggle(void *bitmap, int bit)
|
static inline void bit_toggle(void *bitmap, int bit)
|
||||||
{
|
{
|
||||||
*(unsigned long *)bitmap ^= (1 << bit);
|
*(unsigned long *)bitmap ^= (1UL << bit);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define bit_toggle(bitmap, bit) arch_bit_toggle(bitmap, bit)
|
#define bit_toggle(bitmap, bit) arch_bit_toggle(bitmap, bit)
|
||||||
@ -111,7 +110,7 @@ static inline void bit_toggle(void *bitmap, int bit)
|
|||||||
#ifndef ARCH_BIT_TEST
|
#ifndef ARCH_BIT_TEST
|
||||||
static inline int bit_test(void *bitmap, int bitno)
|
static inline int bit_test(void *bitmap, int bitno)
|
||||||
{
|
{
|
||||||
return ((*(unsigned long *)bitmap & (1 << bitno)) >> bitno);
|
return ((*(unsigned long *)bitmap & (1UL << bitno)) >> bitno);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define bit_test(bitmap, bitno) arch_bit_test(bitmap, bitno)
|
#define bit_test(bitmap, bitno) arch_bit_test(bitmap, bitno)
|
||||||
@ -133,7 +132,7 @@ static inline int bit_test(void *bitmap, int bitno)
|
|||||||
static inline int bit_test_and_set(void *bitmap, int bitno)
|
static inline int bit_test_and_set(void *bitmap, int bitno)
|
||||||
{
|
{
|
||||||
int val = (*(unsigned long *)bitmap & (1 << bitno));
|
int val = (*(unsigned long *)bitmap & (1 << bitno));
|
||||||
*(unsigned long *)bitmap |= (1 << bitno);
|
*(unsigned long *)bitmap |= (1UL << bitno);
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -157,7 +156,7 @@ static inline int bit_test_and_set(void *bitmap, int bitno)
|
|||||||
static inline int bit_test_and_reset(void *bitmap, int bitno)
|
static inline int bit_test_and_reset(void *bitmap, int bitno)
|
||||||
{
|
{
|
||||||
int val = (*(unsigned long *)bitmap & (1 << bitno));
|
int val = (*(unsigned long *)bitmap & (1 << bitno));
|
||||||
*(unsigned long *)bitmap &= ~(1 << bitno);
|
*(unsigned long *)bitmap &= ~(1UL << bitno);
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -175,23 +174,21 @@ static inline int bit_test_and_reset(void *bitmap, int bitno)
|
|||||||
#ifndef ARCH_BIT_FIND_LSF
|
#ifndef ARCH_BIT_FIND_LSF
|
||||||
static inline long bit_find_lsf(unsigned long word)
|
static inline long bit_find_lsf(unsigned long word)
|
||||||
{
|
{
|
||||||
long c = -1;
|
long c = 0;
|
||||||
|
|
||||||
for (; word; c++, word >>= 1) {
|
while(c <= ((sizeof(unsigned long)*8) - 1)) {
|
||||||
if ((word & 0x01)) {
|
if(word & (1UL << (unsigned long)c)) return c;
|
||||||
c++;
|
c++;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return c;
|
return -1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
#define bit_find_lsf(word) arch_bit_find_lsf(word)
|
#define bit_find_lsf(word) arch_bit_find_lsf(word)
|
||||||
#endif /* ARCH_BIT_FIND_LSF */
|
#endif /* ARCH_BIT_FIND_LSF */
|
||||||
|
|
||||||
#ifndef ARCH_ZERO_BIT_FIND_LSF
|
#ifndef ARCH_ZERO_BIT_FIND_LSF
|
||||||
#define zero_bit_find_lsf(word) bit_find_lsf(~(word))
|
#define zero_bit_find_lsf(word) bit_find_lsf(~(unsigned long)(word))
|
||||||
#else
|
#else
|
||||||
#define zero_bit_find_lsf(word) arch_zero_bit_find_lsf(word)
|
#define zero_bit_find_lsf(word) arch_zero_bit_find_lsf(word)
|
||||||
#endif
|
#endif
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
#define __IDX_ALLOCATOR_H__
|
#define __IDX_ALLOCATOR_H__
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
typedef unsigned long ulong_t;
|
typedef unsigned long ulong_t;
|
||||||
|
|
||||||
@ -51,13 +50,6 @@ typedef unsigned long ulong_t;
|
|||||||
#define WORDS_PER_ITEM (BYTES_PER_ITEM / sizeof(ulong_t)) /**< Number of machine words(ulong_t) per second-level bitmap item */
|
#define WORDS_PER_ITEM (BYTES_PER_ITEM / sizeof(ulong_t)) /**< Number of machine words(ulong_t) per second-level bitmap item */
|
||||||
#define IDX_INVAL ~0UL /**< Invalid index value */
|
#define IDX_INVAL ~0UL /**< Invalid index value */
|
||||||
|
|
||||||
#define ida_lock_init(lock) pthread_mutex_init(lock, NULL)
|
|
||||||
#define ida_lock_destroy(lock) pthread_mutex_destroy(lock);
|
|
||||||
#define ida_lock(a) pthread_mutex_lock(&a->lock)
|
|
||||||
#define ida_unlock(a) pthread_mutex_unlock(&a->lock)
|
|
||||||
#define ida_lockable(a) (a->lck)
|
|
||||||
|
|
||||||
typedef pthread_mutex_t ida_lock_t;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct idx_allocator_t
|
* @struct idx_allocator_t
|
||||||
@ -68,8 +60,6 @@ typedef struct __idx_allocator {
|
|||||||
ulong_t max_id; /**< Maximum index value(exclusive) */
|
ulong_t max_id; /**< Maximum index value(exclusive) */
|
||||||
ulong_t *main_bmap; /**< First-level(main) bitmap that splits second-level bitmap on several parts */
|
ulong_t *main_bmap; /**< First-level(main) bitmap that splits second-level bitmap on several parts */
|
||||||
ulong_t *ids_bmap; /**< Second-level bitmap whose each bit corresponds to particular unique identifier */
|
ulong_t *ids_bmap; /**< Second-level bitmap whose each bit corresponds to particular unique identifier */
|
||||||
ida_lock_t lock;
|
|
||||||
int lck;
|
|
||||||
} idx_allocator_t;
|
} idx_allocator_t;
|
||||||
|
|
||||||
#define idx_allocator_initialized(ida) (((idx_allocator_t*)(ida))->max_id)
|
#define idx_allocator_initialized(ida) (((idx_allocator_t*)(ida))->max_id)
|
||||||
@ -78,7 +68,8 @@ typedef struct __idx_allocator {
|
|||||||
* @brief Initialize an index allocator.
|
* @brief Initialize an index allocator.
|
||||||
* @param ida - A pointer to particular index allocator
|
* @param ida - A pointer to particular index allocator
|
||||||
* @param idx_max - Maximum index value.
|
* @param idx_max - Maximum index value.
|
||||||
* @lockable - flag to indicate the allocator must support locking itself
|
* @lockable - flag to indicate the allocator must support locking itself,
|
||||||
|
* deprecated and will be removed within next major version bump
|
||||||
*/
|
*/
|
||||||
int idx_allocator_init(idx_allocator_t *ida, ulong_t idx_max, int lockable);
|
int idx_allocator_init(idx_allocator_t *ida, ulong_t idx_max, int lockable);
|
||||||
|
|
||||||
|
@ -52,7 +52,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define MIN_IDA_SIZE (WORDS_PER_ITEM * sizeof(ulong_t))
|
#define MIN_IDA_SIZE (WORDS_PER_ITEM * sizeof(ulong_t))
|
||||||
#define MAX_UNLOCKED_ATTEMPTS 3
|
|
||||||
|
|
||||||
/* there macros defined only on new glibc (from 12-jul-2013), let's use our own */
|
/* there macros defined only on new glibc (from 12-jul-2013), let's use our own */
|
||||||
#ifndef is_powerof2
|
#ifndef is_powerof2
|
||||||
@ -74,11 +73,9 @@ ulong_t idx_allocate(idx_allocator_t *ida)
|
|||||||
{
|
{
|
||||||
ulong_t id = IDX_INVAL;
|
ulong_t id = IDX_INVAL;
|
||||||
long fnfi = 0;
|
long fnfi = 0;
|
||||||
size_t i, main_offs = 0, main_sz;
|
size_t i = 0, main_offs = 0, main_sz;
|
||||||
int natm = 0; /* attempt number */
|
|
||||||
|
|
||||||
main_sz = __get_main_bmap_size(ida) / sizeof(ulong_t);
|
main_sz = __get_main_bmap_size(ida) / sizeof(ulong_t);
|
||||||
i = 0;
|
|
||||||
|
|
||||||
if (ida->ids_bmap != NULL) {
|
if (ida->ids_bmap != NULL) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
@ -104,17 +101,12 @@ ulong_t idx_allocate(idx_allocator_t *ida)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ida_lockable(ida) /*&& atomic_test_and_set_bit(ida->ids_bmap + j, res_id)*/) {
|
bit_set(ida->ids_bmap + j, res_id);
|
||||||
natm++;
|
|
||||||
if (natm == MAX_UNLOCKED_ATTEMPTS)
|
|
||||||
ida_lock(ida);
|
|
||||||
} else {
|
|
||||||
bit_set(ida->ids_bmap + j, res_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
id = res_id + j * BITS_PER_LONG;
|
id = res_id + j * BITS_PER_LONG;
|
||||||
if (id >= ida->max_id) {
|
if (id >= ida->max_id) {
|
||||||
bit_clear(ida->ids_bmap + j, res_id);
|
bit_clear(ida->ids_bmap + j, res_id);
|
||||||
|
printf("%s:%d IDXINVAL\n", __FILE__, __LINE__);
|
||||||
id = IDX_INVAL;
|
id = IDX_INVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,15 +114,14 @@ ulong_t idx_allocate(idx_allocator_t *ida)
|
|||||||
}
|
}
|
||||||
|
|
||||||
bit_set(ida->main_bmap + main_offs,
|
bit_set(ida->main_bmap + main_offs,
|
||||||
(fnfi - (main_offs * WORDS_PER_ITEM * BITS_PER_LONG)) / WORDS_PER_ITEM);
|
(fnfi - (main_offs * WORDS_PER_ITEM * BITS_PER_LONG)) /
|
||||||
if ((ida->main_bmap[i] & ~0UL) == ~0UL)
|
WORDS_PER_ITEM);
|
||||||
i++;
|
if ((ida->main_bmap[i] & ~0UL) == ~0UL) i++;
|
||||||
}
|
}
|
||||||
else
|
else break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
while (i < main_sz) {
|
while (i < main_sz) {
|
||||||
fnfi = zero_bit_find_lsf(ida->main_bmap[i]);
|
fnfi = zero_bit_find_lsf(ida->main_bmap[i]);
|
||||||
if (fnfi >= 0) {
|
if (fnfi >= 0) {
|
||||||
@ -149,8 +140,6 @@ ulong_t idx_allocate(idx_allocator_t *ida)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
if (natm == MAX_UNLOCKED_ATTEMPTS)
|
|
||||||
ida_unlock(ida);
|
|
||||||
|
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
@ -219,12 +208,6 @@ int idx_allocator_init(idx_allocator_t *ida, ulong_t idx_max, int lockable)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (lockable && ida_lock_init(&ida->lock))
|
|
||||||
goto error;
|
|
||||||
#endif
|
|
||||||
ida->lck = 0; /* cutty, we don't use the lockable due to the very arch specifics */
|
|
||||||
|
|
||||||
memset(ida->main_bmap, 0, __get_main_bmap_size(ida));
|
memset(ida->main_bmap, 0, __get_main_bmap_size(ida));
|
||||||
ida->max_id = idx_max;
|
ida->max_id = idx_max;
|
||||||
return 0;
|
return 0;
|
||||||
@ -247,7 +230,6 @@ void idx_allocator_destroy(idx_allocator_t *ida)
|
|||||||
|
|
||||||
free(ida->main_bmap);
|
free(ida->main_bmap);
|
||||||
|
|
||||||
if (ida_lockable(ida))
|
return;
|
||||||
ida_lock_destroy(&ida->lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
tests/.gitignore
vendored
Normal file
1
tests/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
idxatest
|
19
tests/Makefile.am
Normal file
19
tests/Makefile.am
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
## AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
|
AM_CPPFLAGS = \
|
||||||
|
-DPACKAGE_LOCALE_DIR=\""$(localedir)"\" \
|
||||||
|
-DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
|
||||||
|
-DPACKAGE_DATA_DIR=\""$(pkgdatadir)"\" \
|
||||||
|
-DCNFPATH=\""$(prefix)/etc"\" \
|
||||||
|
-I$(top_srcdir)/include
|
||||||
|
|
||||||
|
AM_CFLAGS = -Wall -g
|
||||||
|
|
||||||
|
# where to find libsxmp
|
||||||
|
libtdata = $(top_builddir)/lib/.libs/libtdata.la
|
||||||
|
|
||||||
|
bin_PROGRAMS = idxatest
|
||||||
|
|
||||||
|
idxatest_SOURCES = idxa.c
|
||||||
|
idxatest_LDADD = $(libtdata) -lpthread
|
||||||
|
|
79
tests/idxa.c
Normal file
79
tests/idxa.c
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2.1 of
|
||||||
|
* the License.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
* (c) Copyright 2014 Alexander Vdolainen <avdolainen@zoho.com>
|
||||||
|
*
|
||||||
|
* Index allocator tests
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <tdata/bitwise.h>
|
||||||
|
#include <tdata/idx_allocator.h>
|
||||||
|
|
||||||
|
#define IDXMAX 131072
|
||||||
|
|
||||||
|
int main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
idx_allocator_t idxa;
|
||||||
|
ulong_t r = 0, i = 0;
|
||||||
|
|
||||||
|
memset(&idxa, 0, sizeof(idxa));
|
||||||
|
|
||||||
|
if((r = idx_allocator_init(&idxa, IDXMAX, 0))) {
|
||||||
|
fprintf(stderr, "%d:(%s): IDX init failed with %lu\n", __LINE__,
|
||||||
|
__FUNCTION__, r);
|
||||||
|
goto __finiv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* one thread */
|
||||||
|
/* (1) use the half of pool and free it */
|
||||||
|
for(i = 0; i < IDXMAX/2; i++) {
|
||||||
|
r = idx_allocate(&idxa);
|
||||||
|
if(r != i) {
|
||||||
|
fprintf(stderr, "%d:(%s):error: expected %lu instead of %lu\n",
|
||||||
|
__LINE__, __FUNCTION__, i, r);
|
||||||
|
r = -1;
|
||||||
|
goto __finiv1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (2) use all pool and free the second part */
|
||||||
|
for(i = IDXMAX/2; i < IDXMAX; i++) {
|
||||||
|
r = idx_allocate(&idxa);
|
||||||
|
if(r != i) {
|
||||||
|
fprintf(stderr, "%d:(%s):error: expected %lu instead of %lu\n",
|
||||||
|
__LINE__, __FUNCTION__, i, r);
|
||||||
|
r = -1;
|
||||||
|
goto __finiv1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* (3) fill second part and free all and try to allocate 1/4 */
|
||||||
|
/* (4) free all */
|
||||||
|
|
||||||
|
__finiv1:
|
||||||
|
|
||||||
|
idx_allocator_destroy(&idxa);
|
||||||
|
|
||||||
|
__finiv:
|
||||||
|
return r;
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user