Few things --- there are:

- Fix bug within index allocator
 - Removed obsolete locking stuff from allocator
 - Stupid test added
master 0.2.4
Alexander Vdolainen 5 years ago
parent 459ca367a3
commit bb6a20313b

@ -1,6 +1,13 @@
## 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
libtdatadoc_DATA = \

@ -48,15 +48,18 @@ dnl *****************
dnl ***** options *****
dnl *****************
AC_ARG_ENABLE([build_examples],
AS_HELP_STRING([--enable-build-examples], [Enable examples build]))
AC_ARG_ENABLE([build_tests],
AS_HELP_STRING([--enable-build-tests], [Enable build tests]))
AS_IF([test "x$enable_build_examples" = "xyes"], [
AC_DEFINE([BUILD_EXAMPLES], 1, [build of examples enabled])
AS_IF([test "x$enable_build_tests" = "xyes"], [
AC_DEFINE([BUILD_TESTS], 1, [build of tests enabled])
])
AM_CONDITIONAL(BUILD_TESTS, test "x$enable_build_tests" = "xyes")
AC_OUTPUT([
Makefile
lib/libtdata.pc
lib/Makefile
tests/Makefile
include/Makefile])

@ -28,11 +28,10 @@
/* TODO: add arch deps */
//#include <arch/bitwise.h>
/* TODO: add linux headers tests */
#include <asm-generic/bitsperlong.h>
#ifdef __BITS_PER_LONG
#define BITS_PER_LONG __BITS_PER_LONG
#ifdef BUILD_HOST_32BIT
#define BITS_PER_LONG 32
#else
#define BITS_PER_LONG 64
#endif
#if BITS_PER_LONG == 64
@ -59,7 +58,7 @@ typedef struct __bitmap {
#ifndef ARCH_BIT_SET
static inline void bit_set(void *bitmap, int bit)
{
*(unsigned long *)bitmap |= (1 << bit);
*(unsigned long *)bitmap |= (1UL << bit);
}
#else
#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
static inline void bit_clear(void *bitmap, int bit)
{
*(unsigned long *)bitmap &= ~(1 << bit);
*(unsigned long *)bitmap &= ~(1UL << bit);
}
#else
#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
static inline void bit_toggle(void *bitmap, int bit)
{
*(unsigned long *)bitmap ^= (1 << bit);
*(unsigned long *)bitmap ^= (1UL << bit);
}
#else
#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
static inline int bit_test(void *bitmap, int bitno)
{
return ((*(unsigned long *)bitmap & (1 << bitno)) >> bitno);
return ((*(unsigned long *)bitmap & (1UL << bitno)) >> bitno);
}
#else
#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)
{
int val = (*(unsigned long *)bitmap & (1 << bitno));
*(unsigned long *)bitmap |= (1 << bitno);
*(unsigned long *)bitmap |= (1UL << bitno);
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)
{
int val = (*(unsigned long *)bitmap & (1 << bitno));
*(unsigned long *)bitmap &= ~(1 << bitno);
*(unsigned long *)bitmap &= ~(1UL << bitno);
return val;
}
@ -175,23 +174,21 @@ static inline int bit_test_and_reset(void *bitmap, int bitno)
#ifndef ARCH_BIT_FIND_LSF
static inline long bit_find_lsf(unsigned long word)
{
long c = -1;
long c = 0;
for (; word; c++, word >>= 1) {
if ((word & 0x01)) {
c++;
break;
}
while(c <= ((sizeof(unsigned long)*8) - 1)) {
if(word & (1UL << (unsigned long)c)) return c;
c++;
}
return c;
return -1;
}
#else
#define bit_find_lsf(word) arch_bit_find_lsf(word)
#endif /* ARCH_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
#define zero_bit_find_lsf(word) arch_zero_bit_find_lsf(word)
#endif

@ -43,7 +43,6 @@
#define __IDX_ALLOCATOR_H__
#include <sys/types.h>
#include <pthread.h>
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 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
@ -68,8 +60,6 @@ typedef struct __idx_allocator {
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 *ids_bmap; /**< Second-level bitmap whose each bit corresponds to particular unique identifier */
ida_lock_t lock;
int lck;
} idx_allocator_t;
#define idx_allocator_initialized(ida) (((idx_allocator_t*)(ida))->max_id)
@ -78,7 +68,8 @@ typedef struct __idx_allocator {
* @brief Initialize an index allocator.
* @param ida - A pointer to particular index allocator
* @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);

@ -52,7 +52,6 @@
*/
#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 */
#ifndef is_powerof2
@ -74,11 +73,9 @@ ulong_t idx_allocate(idx_allocator_t *ida)
{
ulong_t id = IDX_INVAL;
long fnfi = 0;
size_t i, main_offs = 0, main_sz;
int natm = 0; /* attempt number */
size_t i = 0, main_offs = 0, main_sz;
main_sz = __get_main_bmap_size(ida) / sizeof(ulong_t);
i = 0;
if (ida->ids_bmap != NULL) {
for (;;) {
@ -104,17 +101,12 @@ ulong_t idx_allocate(idx_allocator_t *ida)
continue;
}
if (ida_lockable(ida) /*&& atomic_test_and_set_bit(ida->ids_bmap + j, res_id)*/) {
natm++;
if (natm == MAX_UNLOCKED_ATTEMPTS)
ida_lock(ida);
} else {
bit_set(ida->ids_bmap + j, res_id);
}
bit_set(ida->ids_bmap + j, res_id);
id = res_id + j * BITS_PER_LONG;
if (id >= ida->max_id) {
bit_clear(ida->ids_bmap + j, res_id);
printf("%s:%d IDXINVAL\n", __FILE__, __LINE__);
id = IDX_INVAL;
}
@ -122,15 +114,14 @@ ulong_t idx_allocate(idx_allocator_t *ida)
}
bit_set(ida->main_bmap + main_offs,
(fnfi - (main_offs * WORDS_PER_ITEM * BITS_PER_LONG)) / WORDS_PER_ITEM);
if ((ida->main_bmap[i] & ~0UL) == ~0UL)
i++;
(fnfi - (main_offs * WORDS_PER_ITEM * BITS_PER_LONG)) /
WORDS_PER_ITEM);
if ((ida->main_bmap[i] & ~0UL) == ~0UL) i++;
}
else
break;
else break;
}
}
else {
} else {
while (i < main_sz) {
fnfi = zero_bit_find_lsf(ida->main_bmap[i]);
if (fnfi >= 0) {
@ -149,8 +140,6 @@ ulong_t idx_allocate(idx_allocator_t *ida)
}
out:
if (natm == MAX_UNLOCKED_ATTEMPTS)
ida_unlock(ida);
return id;
}
@ -219,12 +208,6 @@ int idx_allocator_init(idx_allocator_t *ida, ulong_t idx_max, int lockable)
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));
ida->max_id = idx_max;
return 0;
@ -247,7 +230,6 @@ void idx_allocator_destroy(idx_allocator_t *ida)
free(ida->main_bmap);
if (ida_lockable(ida))
ida_lock_destroy(&ida->lock);
return;
}

1
tests/.gitignore vendored

@ -0,0 +1 @@
idxatest

@ -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

@ -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…
Cancel
Save