Merge ct/devel to see if there are any problems...
This commit is contained in:
commit
6310e9789b
62 changed files with 4258 additions and 411 deletions
|
|
@ -33,6 +33,8 @@ SUBDIRS =
|
|||
include $(top_srcdir)/admin/Makefile.am
|
||||
|
||||
# core
|
||||
include $(top_srcdir)/src/proc/Makefile.am
|
||||
include $(top_srcdir)/src/common/Makefile.am
|
||||
include $(top_srcdir)/src/lib/Makefile.am
|
||||
include $(top_srcdir)/src/backend/Makefile.am
|
||||
|
||||
|
|
@ -40,6 +42,8 @@ include $(top_srcdir)/src/backend/Makefile.am
|
|||
#include $(top_srcdir)/src...
|
||||
|
||||
# tests
|
||||
include $(top_srcdir)/tests/common/Makefile.am
|
||||
include $(top_srcdir)/tests/components/Makefile.am
|
||||
include $(top_srcdir)/tests/Makefile.am
|
||||
include $(top_srcdir)/tests/plugin/Makefile.am
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
/*
|
||||
just place any problematic calls where valgrind whines about in main (with comments please)
|
||||
|
|
|
|||
64
configure.ac
64
configure.ac
|
|
@ -23,6 +23,8 @@ AC_COPYRIGHT([
|
|||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
])
|
||||
|
||||
AC_GNU_SOURCE
|
||||
|
||||
#
|
||||
# Required programs
|
||||
#
|
||||
|
|
@ -37,11 +39,12 @@ AC_PROG_LIBTOOL
|
|||
# test for headers
|
||||
#
|
||||
AC_STDC_HEADERS
|
||||
AC_CHECK_HEADER([nobug.h], AC_DEFINE(HAVE_NOBUG_H))
|
||||
AC_CHECK_HEADER([execinfo.h], AC_DEFINE(HAVE_EXECINFO_H))
|
||||
# there is a warning in nobug, disabled til fixed AC_CHECK_HEADER([valgrind/valgrind.h], AC_DEFINE(HAVE_VALGRIND_VALGRIND_H))
|
||||
|
||||
ACX_PTHREAD
|
||||
LIBS="$PTHREAD_LIBS $LIBS"
|
||||
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
|
||||
CC="$PTHREAD_CC"
|
||||
|
||||
##AM_CONDITIONAL([HAVE_THREADING], [test x"$acx_pthread_ok" = xyes])
|
||||
|
||||
|
||||
|
|
@ -71,9 +74,62 @@ AC_ARG_ENABLE(release, AC_HELP_STRING([--enable-release], [select NoBug RELEASE
|
|||
nobug_level=alpha
|
||||
AC_DEFINE(EBUG_ALPHA)
|
||||
)])])
|
||||
AC_MSG_RESULT([NoBug build level: $nobug_level])
|
||||
# END NoBug
|
||||
|
||||
# C headers and libraries
|
||||
AC_LANG_PUSH([C])
|
||||
|
||||
AC_CHECK_HEADER([nobug.h],
|
||||
AC_DEFINE(HAVE_NOBUG_H),
|
||||
AC_MSG_ERROR([NoBug header missing (http://www.pipapo.org/pipawiki/NoBug)])
|
||||
)
|
||||
AC_CHECK_LIB([nobugmt], nobug_thread_id_get,
|
||||
,
|
||||
AC_MSG_ERROR([NoBug multithreading library missing (http://www.pipapo.org/pipawiki/NoBug)])
|
||||
)
|
||||
|
||||
AC_CHECK_HEADER([execinfo.h], AC_DEFINE(HAVE_EXECINFO_H))
|
||||
# there is a warning in nobug, disabled til fixed AC_CHECK_HEADER([valgrind/valgrind.h], AC_DEFINE(HAVE_VALGRIND_VALGRIND_H))
|
||||
|
||||
AC_LANG_POP([C])
|
||||
|
||||
|
||||
# C++ headers and libraries
|
||||
AC_LANG_PUSH([C++])
|
||||
|
||||
AC_CHECK_HEADER([tr1/memory],
|
||||
,
|
||||
AC_MSG_ERROR([std::tr1 proposed standard extension for shared_ptr missing])
|
||||
)
|
||||
|
||||
AC_CHECK_HEADER([boost/shared_ptr.hpp],
|
||||
,
|
||||
AC_MSG_ERROR([boost::shared_ptr missing (http://www.boost.org/)])
|
||||
)
|
||||
|
||||
AC_CHECK_HEADER([boost/program_options.hpp],
|
||||
,
|
||||
AC_MSG_ERROR([boost::program_options missing (http://www.boost.org/)])
|
||||
)
|
||||
# checking for library left out, name contains compiler version here (libboost_program_options-gcc42-mt-1_34_1.so.1.34.1) any ides how to use that?
|
||||
|
||||
AC_CHECK_HEADER([boost/regex.hpp],
|
||||
,
|
||||
AC_MSG_ERROR([boost::regex missing (http://www.boost.org/)])
|
||||
)
|
||||
|
||||
AC_LANG_POP([C++])
|
||||
|
||||
|
||||
# Print a summary
|
||||
AC_MSG_RESULT([
|
||||
Configuration Summary:])
|
||||
AC_MSG_RESULT([ NoBug build level: $nobug_level])
|
||||
# Add more summary results here
|
||||
|
||||
AC_MSG_RESULT([
|
||||
Configuration complete, you can now build Lumiera with 'make'
|
||||
])
|
||||
|
||||
AC_CONFIG_FILES(Makefile)
|
||||
AC_OUTPUT
|
||||
|
|
|
|||
|
|
@ -21,17 +21,20 @@ noinst_LIBRARIES += liblumibackend.a
|
|||
liblumibackend_a_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror
|
||||
liblumibackend_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumibackend_a_SOURCES = \
|
||||
$(liblumibackend_a_srcdir)/backend.c \
|
||||
$(liblumibackend_a_srcdir)/file.c \
|
||||
$(liblumibackend_a_srcdir)/filehandle.c \
|
||||
$(liblumibackend_a_srcdir)/filedescriptor.c \
|
||||
liblumibackend_a_SOURCES = \
|
||||
$(liblumibackend_a_srcdir)/mediaaccessfacade.cpp \
|
||||
$(liblumibackend_a_srcdir)/backend.c \
|
||||
$(liblumibackend_a_srcdir)/file.c \
|
||||
$(liblumibackend_a_srcdir)/filehandle.c \
|
||||
$(liblumibackend_a_srcdir)/filedescriptor.c \
|
||||
$(liblumibackend_a_srcdir)/filehandlecache.c
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(liblumibackend_a_srcdir)/backend.h \
|
||||
$(liblumibackend_a_srcdir)/file.h \
|
||||
$(liblumibackend_a_srcdir)/filehandle.h \
|
||||
$(liblumibackend_a_srcdir)/filedescriptor.h \
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(liblumibackend_a_srcdir)/mediaaccessfacade.cpp \
|
||||
$(liblumibackend_a_srcdir)/backend.h \
|
||||
$(liblumibackend_a_srcdir)/file.h \
|
||||
$(liblumibackend_a_srcdir)/filehandle.h \
|
||||
$(liblumibackend_a_srcdir)/filedescriptor.h \
|
||||
$(liblumibackend_a_srcdir)/filehandlecache.h
|
||||
|
||||
|
|
|
|||
53
src/backend/backend.c
Normal file
53
src/backend/backend.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
backend - common lumiera backend things
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "backend/backend.h"
|
||||
#include "backend/filehandlecache.h"
|
||||
#include "backend/filedescriptor.h"
|
||||
|
||||
//NOBUG_DEFINE_FLAG_PARENT (backend, lumiera); TODO
|
||||
NOBUG_DEFINE_FLAG (backend);
|
||||
NOBUG_DEFINE_FLAG_PARENT (file_all, backend);
|
||||
|
||||
int
|
||||
lumiera_backend_init (void)
|
||||
{
|
||||
NOBUG_INIT_FLAG (backend);
|
||||
NOBUG_INIT_FLAG (file_all);
|
||||
NOBUG_INIT_FLAG (file);
|
||||
TRACE (backend);
|
||||
lumiera_filedescriptor_registry_init ();
|
||||
|
||||
int max_entries = 10; TODO("determine by sysconf (_SC_OPEN_MAX) minus some (big) safety margin "
|
||||
"add some override to run tests with few filehandles");
|
||||
|
||||
lumiera_filehandlecache_new (max_entries);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
lumiera_backend_destroy (void)
|
||||
{
|
||||
TRACE (backend);
|
||||
lumiera_filedescriptor_registry_destroy ();
|
||||
lumiera_filehandlecache_delete ();
|
||||
}
|
||||
36
src/backend/backend.h
Normal file
36
src/backend/backend.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
backend - common lumiera backend things
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef LUMIERA_BACKEND_H
|
||||
#define LUMIERA_BACKEND_H
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
NOBUG_DECLARE_FLAG (backend);
|
||||
NOBUG_DECLARE_FLAG (file_all);
|
||||
NOBUG_DECLARE_FLAG (file);
|
||||
|
||||
int
|
||||
lumiera_backend_init (void);
|
||||
|
||||
void
|
||||
lumiera_backend_destroy (void);
|
||||
|
||||
#endif
|
||||
130
src/backend/file.c
Normal file
130
src/backend/file.c
Normal file
|
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
file.c - file handling
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "lib/mutex.h"
|
||||
#include "lib/safeclib.h"
|
||||
|
||||
#include "backend/file.h"
|
||||
#include "backend/filehandlecache.h"
|
||||
#include "backend/filedescriptor.h"
|
||||
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
NOBUG_DEFINE_FLAG_PARENT (file, file_all);
|
||||
|
||||
LUMIERA_ERROR_DEFINE(FILE_CHANGED, "File changed unexpected");
|
||||
|
||||
|
||||
LumieraFile
|
||||
lumiera_file_init (LumieraFile self, const char* name, int flags)
|
||||
{
|
||||
TRACE (file);
|
||||
if (!(self->descriptor = lumiera_filedescriptor_acquire (name, flags)))
|
||||
return NULL;
|
||||
self->name = lumiera_strndup (name, PATH_MAX);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
LumieraFile
|
||||
lumiera_file_destroy (LumieraFile self)
|
||||
{
|
||||
TRACE (file);
|
||||
lumiera_filedescriptor_release (self->descriptor);
|
||||
free ((void*)self->name);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
LumieraFile
|
||||
lumiera_file_new (const char* name, int flags)
|
||||
{
|
||||
TRACE (file);
|
||||
LumieraFile self = lumiera_malloc (sizeof (lumiera_file));
|
||||
return lumiera_file_init (self, name, flags);
|
||||
}
|
||||
|
||||
void
|
||||
lumiera_file_delete (LumieraFile self)
|
||||
{
|
||||
TRACE (file);
|
||||
free (lumiera_file_destroy (self));
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lumiera_file_handle_acquire (LumieraFile self)
|
||||
{
|
||||
TRACE (file);
|
||||
REQUIRE (self);
|
||||
REQUIRE (self->descriptor);
|
||||
REQUIRE (lumiera_fhcache);
|
||||
|
||||
LUMIERA_MUTEX_SECTION (file, self->descriptor->rh, &self->descriptor->lock)
|
||||
{
|
||||
if (!self->descriptor->handle)
|
||||
/* no handle yet, get a new one */
|
||||
lumiera_filehandlecache_handle_acquire (lumiera_fhcache, self->descriptor);
|
||||
else
|
||||
lumiera_filehandlecache_checkout (lumiera_fhcache, self->descriptor->handle);
|
||||
|
||||
if (self->descriptor->handle->fd == -1)
|
||||
{
|
||||
int fd;
|
||||
fd = open (self->name, self->descriptor->flags & LUMIERA_FILE_MASK);
|
||||
if (fd == -1)
|
||||
{
|
||||
LUMIERA_ERROR_SET (file, ERRNO);
|
||||
}
|
||||
else
|
||||
{
|
||||
struct stat st;
|
||||
if (fstat (fd, &st) == -1)
|
||||
{
|
||||
close (fd);
|
||||
LUMIERA_ERROR_SET (file, ERRNO);
|
||||
}
|
||||
else if (self->descriptor->stat.st_dev != st.st_dev || self->descriptor->stat.st_ino != st.st_ino)
|
||||
{
|
||||
close (fd);
|
||||
/* Woops this is not the file we expected to use */
|
||||
LUMIERA_ERROR_SET (file, FILE_CHANGED);
|
||||
}
|
||||
}
|
||||
self->descriptor->handle->fd = fd;
|
||||
}
|
||||
}
|
||||
|
||||
return self->descriptor->handle->fd;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_file_handle_release (LumieraFile self)
|
||||
{
|
||||
TRACE (file);
|
||||
|
||||
LUMIERA_MUTEX_SECTION (file, self->descriptor->rh, &self->descriptor->lock)
|
||||
{
|
||||
lumiera_filehandlecache_checkin (lumiera_fhcache, self->descriptor->handle);
|
||||
}
|
||||
}
|
||||
123
src/backend/file.h
Normal file
123
src/backend/file.h
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
file.h - interface to files by filename
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef LUMIERA_FILE_H
|
||||
#define LUMIERA_FILE_H
|
||||
|
||||
|
||||
#include "lib/mutex.h"
|
||||
#include "lib/llist.h"
|
||||
#include "lib/error.h"
|
||||
|
||||
NOBUG_DECLARE_FLAG (file);
|
||||
|
||||
LUMIERA_ERROR_DECLARE(FILE_CHANGED);
|
||||
|
||||
/**
|
||||
* @file
|
||||
* File management
|
||||
* Handling Files is splitted into different classes:
|
||||
* 1. The 'lumiera_file' class which acts as interface to the outside for managing files.
|
||||
* 'lumiera_file' is addressed by the name of the file. Since files can have more than one name (hardlinks)
|
||||
* many 'lumiera_file' can point to a single 'lumiera_filedescriptor'
|
||||
* 2. The 'lumiera_filedescriptor' class which does the real work managing the file in the back.
|
||||
* 3. Since OS-filehandles are a limited resource we access the lazily as 'lumiera_filehandle' which are
|
||||
* managed in a 'lumiera_filehandlecache'
|
||||
*/
|
||||
|
||||
typedef struct lumiera_file_struct lumiera_file;
|
||||
typedef lumiera_file* LumieraFile;
|
||||
|
||||
|
||||
#include "backend/filehandle.h"
|
||||
#include "backend/filedescriptor.h"
|
||||
|
||||
#define LUMIERA_FILE_READONLY (O_RDONLY | O_LARGEFILE | O_NOATIME)
|
||||
#define LUMIERA_FILE_READWRITE (O_RDWR | O_LARGEFILE | O_NOATIME)
|
||||
#define LUMIERA_FILE_CREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_EXCL)
|
||||
#define LUMIERA_FILE_RECREATE (O_RDWR | O_LARGEFILE | O_NOATIME | O_CREAT | O_TRUNC)
|
||||
|
||||
/* creat and excl flags will be masked out for descriptor lookup */
|
||||
#define LUMIERA_FILE_MASK ~(O_CREAT | O_EXCL | O_TRUNC)
|
||||
|
||||
struct lumiera_file_struct
|
||||
{
|
||||
const char* name;
|
||||
LumieraFiledescriptor descriptor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize a file structure.
|
||||
* @param self pointer to the file structure
|
||||
* @param name filename
|
||||
* @param flags open flags
|
||||
* @return self
|
||||
*/
|
||||
LumieraFile
|
||||
lumiera_file_init (LumieraFile self, const char* name, int flags);
|
||||
|
||||
/**
|
||||
* Destroy a file structure.
|
||||
* frees all associated resources, releases the filedescriptor etc.
|
||||
* @param self file structure to be destroyed
|
||||
* @return self
|
||||
*/
|
||||
LumieraFile
|
||||
lumiera_file_destroy (LumieraFile self);
|
||||
|
||||
/**
|
||||
* Allocate a new file structure.
|
||||
* @param name filename
|
||||
* @param flags open flags
|
||||
* @return new file structure
|
||||
*/
|
||||
LumieraFile
|
||||
lumiera_file_new (const char* name, int flags);
|
||||
|
||||
/**
|
||||
* Frees a file structure.
|
||||
* @param self file structure to be freed
|
||||
*/
|
||||
void
|
||||
lumiera_file_delete (LumieraFile self);
|
||||
|
||||
/**
|
||||
* Get a POSIX filehandle for a file.
|
||||
* Filehandles are opened on demand and must be acquired for use.
|
||||
* Using filehandles is refcounted and might be nested.
|
||||
* After using them they must be released which puts them back into filehandlecache aging.
|
||||
* @param self file structure
|
||||
* @return POSIX filehandle or -1 on error, check lumiera_error() to retrieve the errorcode
|
||||
* Currently only LUMIERA_ERROR_ERRNO will be raised but this might change in future.
|
||||
* Opening files can fail for many reasons and at any time!
|
||||
*/
|
||||
int
|
||||
lumiera_file_handle_acquire (LumieraFile self);
|
||||
|
||||
/**
|
||||
* Put filehandle back into cache aging.
|
||||
* @param self file which handle to be released
|
||||
*/
|
||||
void
|
||||
lumiera_file_handle_release (LumieraFile self);
|
||||
|
||||
#endif
|
||||
|
||||
240
src/backend/filedescriptor.c
Normal file
240
src/backend/filedescriptor.c
Normal file
|
|
@ -0,0 +1,240 @@
|
|||
/*
|
||||
filedescriptor.c - file handling
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "lib/mutex.h"
|
||||
#include "lib/safeclib.h"
|
||||
#include "lib/cuckoo.h"
|
||||
|
||||
#include "backend/file.h"
|
||||
#include "backend/filedescriptor.h"
|
||||
#include "backend/filehandle.h"
|
||||
#include "backend/filehandlecache.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
NOBUG_DEFINE_FLAG_PARENT (filedescriptor, file_all);
|
||||
|
||||
/*
|
||||
Filedescriptor registry
|
||||
|
||||
This registry stores all acquired filedescriptors for lookup, they will be freed when not referenced anymore.
|
||||
*/
|
||||
static Cuckoo registry = NULL;
|
||||
static lumiera_mutex registry_mutex = {PTHREAD_MUTEX_INITIALIZER};
|
||||
|
||||
/*
|
||||
* setup hashing and compare functions for cuckoo hashing
|
||||
*/
|
||||
static size_t
|
||||
h1 (const void* item, const uint32_t r)
|
||||
{
|
||||
const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item;
|
||||
return i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK)
|
||||
^((i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK))>>7)^r;
|
||||
}
|
||||
|
||||
static size_t
|
||||
h2 (const void* item, const uint32_t r)
|
||||
{
|
||||
const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item;
|
||||
return i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK)
|
||||
^((i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK))>>5)^r;
|
||||
}
|
||||
|
||||
static size_t
|
||||
h3 (const void* item, const uint32_t r)
|
||||
{
|
||||
const LumieraFiledescriptor i = *(const LumieraFiledescriptor*)item;
|
||||
return i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK)
|
||||
^((i->stat.st_dev^i->stat.st_ino^(i->flags&LUMIERA_FILE_MASK))>>3)^r;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cmp (const void* keya, const void* keyb)
|
||||
{
|
||||
const LumieraFiledescriptor a = *(const LumieraFiledescriptor*)keya;
|
||||
const LumieraFiledescriptor b = *(const LumieraFiledescriptor*)keyb;
|
||||
return a->stat.st_dev == b->stat.st_dev && a->stat.st_ino == b->stat.st_ino
|
||||
&& (a->flags&LUMIERA_FILE_MASK) == (b->flags&LUMIERA_FILE_MASK);
|
||||
}
|
||||
|
||||
void
|
||||
lumiera_filedescriptor_registry_init (void)
|
||||
{
|
||||
NOBUG_INIT_FLAG (filedescriptor);
|
||||
TRACE (filedescriptor);
|
||||
REQUIRE (!registry);
|
||||
|
||||
registry = cuckoo_new (h1, h2, h3, cmp,
|
||||
sizeof (LumieraFiledescriptor),
|
||||
3);
|
||||
if (!registry)
|
||||
LUMIERA_DIE (NO_MEMORY);
|
||||
}
|
||||
|
||||
void
|
||||
lumiera_filedescriptor_registry_destroy (void)
|
||||
{
|
||||
TRACE (filedescriptor);
|
||||
REQUIRE (!cuckoo_nelements (registry));
|
||||
if (registry)
|
||||
cuckoo_free (registry);
|
||||
registry = NULL;
|
||||
}
|
||||
|
||||
|
||||
LumieraFiledescriptor
|
||||
lumiera_filedescriptor_acquire (const char* name, int flags)
|
||||
{
|
||||
TRACE (filedescriptor, "%s", name);
|
||||
REQUIRE (registry, "not initialized");
|
||||
|
||||
lumiera_mutexacquirer registry_lock;
|
||||
lumiera_mutexacquirer_init_mutex (®istry_lock, ®istry_mutex, LUMIERA_LOCKED);
|
||||
|
||||
lumiera_filedescriptor fdesc;
|
||||
fdesc.flags = flags;
|
||||
|
||||
if (stat (name, &fdesc.stat) != 0)
|
||||
{
|
||||
if (errno == ENOENT && flags&O_CREAT)
|
||||
{
|
||||
char* dir = lumiera_tmpbuf_strndup (name, PATH_MAX);
|
||||
char* slash = dir;
|
||||
while ((slash = strchr (slash+1, '/')))
|
||||
{
|
||||
*slash = '\0';
|
||||
INFO (filedescriptor, "try creating dir: %s", dir);
|
||||
if (mkdir (dir, 0777) == -1 && errno != EEXIST)
|
||||
{
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO);
|
||||
goto efile;
|
||||
}
|
||||
*slash = '/';
|
||||
}
|
||||
int fd;
|
||||
INFO (filedescriptor, "try creating file: %s", name);
|
||||
fd = creat (name, 0777);
|
||||
if (fd == -1)
|
||||
{
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO);
|
||||
goto efile;
|
||||
}
|
||||
close (fd);
|
||||
if (stat (name, &fdesc.stat) != 0)
|
||||
{
|
||||
/* finally, no luck */
|
||||
LUMIERA_ERROR_SET (filedescriptor, ERRNO);
|
||||
goto efile;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* lookup/create descriptor */
|
||||
LumieraFiledescriptor dest = &fdesc;
|
||||
LumieraFiledescriptor* found = cuckoo_find (registry, &dest);
|
||||
|
||||
if (!found)
|
||||
{
|
||||
TRACE (filedescriptor, "Descriptor not found");
|
||||
|
||||
dest = lumiera_filedescriptor_new (&fdesc);
|
||||
if (!dest)
|
||||
goto ecreate;
|
||||
|
||||
cuckoo_insert (registry, &dest);
|
||||
}
|
||||
else
|
||||
{
|
||||
TRACE (filedescriptor, "Descriptor already existing");
|
||||
dest = *found;
|
||||
++dest->refcount;
|
||||
}
|
||||
|
||||
lumiera_mutexacquirer_unlock (®istry_lock);
|
||||
return dest;
|
||||
|
||||
efile:
|
||||
ecreate:
|
||||
lumiera_mutexacquirer_unlock (®istry_lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_filedescriptor_release (LumieraFiledescriptor self)
|
||||
{
|
||||
TRACE (filedescriptor);
|
||||
if (!--self->refcount)
|
||||
lumiera_filedescriptor_delete (self);
|
||||
}
|
||||
|
||||
|
||||
LumieraFiledescriptor
|
||||
lumiera_filedescriptor_new (LumieraFiledescriptor template)
|
||||
{
|
||||
LumieraFiledescriptor self = lumiera_malloc (sizeof (lumiera_filedescriptor));
|
||||
TRACE (filedescriptor, "at %p", self);
|
||||
|
||||
self->stat = template->stat;
|
||||
|
||||
self->flags = template->flags;
|
||||
lumiera_mutex_init (&self->lock);
|
||||
self->refcount = 1;
|
||||
self->handle = 0;
|
||||
|
||||
const char* type = "mutex";
|
||||
const char* name = "filedescriptor";
|
||||
|
||||
RESOURCE_ANNOUNCE (filedescriptor, type, name, self, self->rh);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_filedescriptor_delete (LumieraFiledescriptor self)
|
||||
{
|
||||
TRACE (filedescriptor, "%p", self);
|
||||
lumiera_mutexacquirer registry_lock;
|
||||
lumiera_mutexacquirer_init_mutex (®istry_lock, ®istry_mutex, LUMIERA_LOCKED);
|
||||
|
||||
REQUIRE (self->refcount == 0);
|
||||
|
||||
RESOURCE_FORGET (filedescriptor, self->rh);
|
||||
|
||||
cuckoo_remove (registry, cuckoo_find (registry, &self));
|
||||
|
||||
TODO ("destruct other members (WIP)");
|
||||
|
||||
|
||||
TODO ("release filehandle");
|
||||
|
||||
lumiera_mutex_destroy (&self->lock);
|
||||
free (self);
|
||||
|
||||
lumiera_mutexacquirer_unlock (®istry_lock);
|
||||
}
|
||||
113
src/backend/filedescriptor.h
Normal file
113
src/backend/filedescriptor.h
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
filedescriptor.h - file handling
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef LUMIERA_FILEDESCRIPTOR_H
|
||||
#define LUMIERA_FILEDESCRIPTOR_H
|
||||
|
||||
#include "lib/mutex.h"
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
typedef struct lumiera_filedescriptor_struct lumiera_filedescriptor;
|
||||
typedef lumiera_filedescriptor* LumieraFiledescriptor;
|
||||
|
||||
|
||||
#include "backend/filehandle.h"
|
||||
#include "backend/file.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Filedescriptors.
|
||||
* Filedescriptors are the underlying working horse in accessing files.
|
||||
* All information associated with managing a file is kept here.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
struct lumiera_filedescriptor_struct
|
||||
{
|
||||
struct stat stat; /* create after first open, maintained metadata, MUST BE FIRST! */
|
||||
int flags; /* open flags, must be masked for reopen */
|
||||
lumiera_mutex lock; /* locks operations on this file descriptor */
|
||||
unsigned refcount; /* reference counter, all users sans registry */
|
||||
|
||||
LumieraFilehandle handle;
|
||||
//LumieraFileMap mappings;
|
||||
//LumieraWriteBuffer writebuffer;
|
||||
|
||||
RESOURCE_HANDLE (rh);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initialize the global filedescriptor registry.
|
||||
* All filedescriptors are looked up by dev/ino/open-flags in a hashtable. Opening hardlinked
|
||||
* files will be targeted to the same filedescriptor.
|
||||
* This function never fails but dies on error.
|
||||
*/
|
||||
void
|
||||
lumiera_filedescriptor_registry_init (void);
|
||||
|
||||
/**
|
||||
* Destroy and free the global filedescriptor registry.
|
||||
* Never fails.
|
||||
*/
|
||||
void
|
||||
lumiera_filedescriptor_registry_destroy (void);
|
||||
|
||||
|
||||
/**
|
||||
* Find existing filedescriptor or create one
|
||||
* @param name name of the file
|
||||
* @param flags opening flags for the filedescriptor
|
||||
* @return descriptor on success or NULL on error
|
||||
*/
|
||||
LumieraFiledescriptor
|
||||
lumiera_filedescriptor_acquire (const char* name, int flags);
|
||||
|
||||
|
||||
/**
|
||||
* Release a filedescriptor.
|
||||
* @param self filedescriptor to be released
|
||||
*/
|
||||
void
|
||||
lumiera_filedescriptor_release (LumieraFiledescriptor self);
|
||||
|
||||
|
||||
/**
|
||||
* Allocate a new filedescriptor cloned from a template
|
||||
* @param template the source filedescriptor
|
||||
* @return the constrccted filedescriptor
|
||||
*/
|
||||
LumieraFiledescriptor
|
||||
lumiera_filedescriptor_new (LumieraFiledescriptor template);
|
||||
|
||||
/**
|
||||
* Delete a filedescriptor
|
||||
* Called whenever its reference count drops to zero.
|
||||
* @param self the filedescriptor to be deleted
|
||||
*/
|
||||
void
|
||||
lumiera_filedescriptor_delete (LumieraFiledescriptor self);
|
||||
|
||||
#endif
|
||||
70
src/backend/filehandle.c
Normal file
70
src/backend/filehandle.c
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
filehandle - filehandle management and caching
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "lib/llist.h"
|
||||
#include "lib/safeclib.h"
|
||||
|
||||
#include "backend/file.h"
|
||||
#include "backend/filehandle.h"
|
||||
#include "backend/filedescriptor.h"
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
NOBUG_DEFINE_FLAG_PARENT (filehandle, file_all);
|
||||
|
||||
LumieraFilehandle
|
||||
lumiera_filehandle_new ()
|
||||
{
|
||||
LumieraFilehandle self = lumiera_malloc (sizeof (lumiera_filehandle));
|
||||
TRACE (filehandle, "%p", self);
|
||||
|
||||
llist_init (&self->cachenode);
|
||||
self->fd = -1;
|
||||
self->use_cnt = 1;
|
||||
self->descriptor = NULL;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
lumiera_filehandle_destroy_node (LList node)
|
||||
{
|
||||
TRACE (filehandle);
|
||||
REQUIRE (llist_is_empty (node));
|
||||
LumieraFilehandle self = (LumieraFilehandle)node;
|
||||
REQUIRE (self->use_cnt == 0);
|
||||
|
||||
if (self->fd >= 0)
|
||||
close (self->fd);
|
||||
self->fd = -1;
|
||||
self->descriptor = NULL;
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lumiera_filehandle_get (LumieraFilehandle self)
|
||||
{
|
||||
REQUIRE (self->descriptor);
|
||||
return -1;
|
||||
}
|
||||
|
||||
69
src/backend/filehandle.h
Normal file
69
src/backend/filehandle.h
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
filehandle - filehandle management and caching
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef LUMIERA_FILEHANDLE_H
|
||||
#define LUMIERA_FILEHANDLE_H
|
||||
|
||||
#include "lib/error.h"
|
||||
#include "lib/llist.h"
|
||||
|
||||
typedef struct lumiera_filehandle_struct lumiera_filehandle;
|
||||
typedef lumiera_filehandle* LumieraFilehandle;
|
||||
|
||||
#include "backend/filedescriptor.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Filehandles.
|
||||
* Filehandles manage the underlying POSIX filehandle for a filedescriptor.
|
||||
* Since we want to support handling of more files than POSIX filehandles are available on a common system
|
||||
* the filehandles are opened, cached and closed on demand, see 'filehandlecache'.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* File handles
|
||||
*/
|
||||
struct lumiera_filehandle_struct
|
||||
{
|
||||
llist cachenode;
|
||||
int fd;
|
||||
unsigned use_cnt;
|
||||
LumieraFiledescriptor descriptor;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allocate a new filehandle structure.
|
||||
* @return new filehandle structure
|
||||
*/
|
||||
LumieraFilehandle
|
||||
lumiera_filehandle_new ();
|
||||
|
||||
|
||||
/**
|
||||
* destroy the resources associated eith a filehandle structure.
|
||||
* This function is used by the filehandlecache to recycle filehandle structs.
|
||||
* @param node pointer to the cachenode member of a struct filehandle
|
||||
* @return pointer to the start of the memory of the destroyed filehandle
|
||||
*/
|
||||
void*
|
||||
lumiera_filehandle_destroy_node (LList node);
|
||||
|
||||
#endif
|
||||
138
src/backend/filehandlecache.c
Normal file
138
src/backend/filehandlecache.c
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
filehandlecache - filehandle management and caching
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "lib/safeclib.h"
|
||||
|
||||
#include "backend/file.h"
|
||||
#include "backend/filehandlecache.h"
|
||||
|
||||
NOBUG_DEFINE_FLAG_PARENT (filehandlecache, file_all);
|
||||
|
||||
/* errors */
|
||||
|
||||
LUMIERA_ERROR_DEFINE (FILEHANDLECACHE_NOHANDLE, "No filehandle available");
|
||||
|
||||
|
||||
LumieraFilehandlecache lumiera_fhcache = NULL;
|
||||
|
||||
|
||||
void
|
||||
lumiera_filehandlecache_new (int max_entries)
|
||||
{
|
||||
REQUIRE (!lumiera_fhcache, "Filehandlecache already initialized");
|
||||
|
||||
NOBUG_INIT_FLAG (filehandlecache);
|
||||
lumiera_fhcache = lumiera_malloc (sizeof (lumiera_filehandlecache));
|
||||
lumiera_mrucache_init (&lumiera_fhcache->cache, lumiera_filehandle_destroy_node);
|
||||
lumiera_fhcache->available = max_entries;
|
||||
lumiera_fhcache->checked_out = 0;
|
||||
lumiera_mutex_init (&lumiera_fhcache->lock);
|
||||
RESOURCE_ANNOUNCE (filehandlecache, "mutex", "filehandlecache", lumiera_fhcache, lumiera_fhcache->rh);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_filehandlecache_delete (void)
|
||||
{
|
||||
if (lumiera_fhcache)
|
||||
{
|
||||
REQUIRE (!lumiera_fhcache->checked_out, "Filehandles in use at shutdown");
|
||||
RESOURCE_FORGET (filehandlecache, lumiera_fhcache->rh);
|
||||
lumiera_mrucache_destroy (&lumiera_fhcache->cache);
|
||||
lumiera_mutex_destroy (&lumiera_fhcache->lock);
|
||||
free (lumiera_fhcache);
|
||||
lumiera_fhcache = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LumieraFilehandle
|
||||
lumiera_filehandlecache_handle_acquire (LumieraFilehandlecache self, LumieraFiledescriptor desc)
|
||||
{
|
||||
TRACE (filehandlecache);
|
||||
LumieraFilehandle ret = NULL;
|
||||
LUMIERA_MUTEX_SECTION (filehandlecache, self->rh, &self->lock)
|
||||
{
|
||||
if (self->available <= 0 && self->cache.cached)
|
||||
{
|
||||
/* pop a filehandle from cache */
|
||||
ret = lumiera_mrucache_pop (&self->cache);
|
||||
if (self->available < 0)
|
||||
/* try to free overallocated filehandles */
|
||||
self->available -= self->available + lumiera_mrucache_age (&self->cache, -self->available);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* allocate new filehandle if we are below the limit or no cached handles are available (overallocating) */
|
||||
ret = lumiera_filehandle_new ();
|
||||
if (!ret)
|
||||
LUMIERA_ERROR_SET (filehandlecache, FILEHANDLECACHE_NOHANDLE);
|
||||
else
|
||||
--self->available;
|
||||
}
|
||||
ret->use_cnt = 1;
|
||||
ret->descriptor = desc;
|
||||
desc->handle = ret;
|
||||
++self->checked_out;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
LumieraFilehandle
|
||||
lumiera_filehandlecache_checkout (LumieraFilehandlecache self, LumieraFilehandle handle)
|
||||
{
|
||||
REQUIRE (self);
|
||||
REQUIRE (handle);
|
||||
/* This function is called with the associated descriptor locked, nothing can modify 'handle' */
|
||||
if (!handle->use_cnt)
|
||||
{
|
||||
/* lock cache and checkout */
|
||||
LUMIERA_MUTEX_SECTION (filehandlecache, self->rh, &self->lock)
|
||||
{
|
||||
lumiera_mrucache_checkout (&self->cache, &handle->cachenode);
|
||||
}
|
||||
}
|
||||
++handle->use_cnt;
|
||||
++self->checked_out;
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
void
|
||||
lumiera_filehandlecache_checkin (LumieraFilehandlecache self, LumieraFilehandle handle)
|
||||
{
|
||||
REQUIRE (self);
|
||||
REQUIRE (handle);
|
||||
REQUIRE (handle->use_cnt);
|
||||
|
||||
/* This function is called with the associated descriptor locked, nothing can modify 'self' */
|
||||
if (!--handle->use_cnt)
|
||||
{
|
||||
/* lock cache and checin */
|
||||
LUMIERA_MUTEX_SECTION (filehandlecache, self->rh, &self->lock)
|
||||
{
|
||||
--self->checked_out;
|
||||
lumiera_mrucache_checkin (&self->cache, &handle->cachenode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
108
src/backend/filehandlecache.h
Normal file
108
src/backend/filehandlecache.h
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
/*
|
||||
filehandlecache - filehandle management and caching
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef LUMIERA_FILEHANDLECACHE_H
|
||||
#define LUMIERA_FILEHANDLECACHE_H
|
||||
|
||||
#include "lib/error.h"
|
||||
#include "lib/mrucache.h"
|
||||
#include "lib/mutex.h"
|
||||
|
||||
typedef struct lumiera_filehandlecache_struct lumiera_filehandlecache;
|
||||
typedef lumiera_filehandlecache* LumieraFilehandlecache;
|
||||
|
||||
#include "backend/filehandle.h"
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Filehandle management and caching
|
||||
* The number of filehandles a program can held open is usually limited, since we want to support
|
||||
* using a less limited number of files and closing/opening for each operation is expensive, we
|
||||
* provide a cache to keep the most frequent used files open and gracefully close/recycle unused filehandles.
|
||||
* The filehandlecache defined here protects all operations on the cache with a mutex.
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
File handle cache manages file handles
|
||||
*/
|
||||
struct lumiera_filehandlecache_struct
|
||||
{
|
||||
lumiera_mrucache cache;
|
||||
int available;
|
||||
int checked_out;
|
||||
lumiera_mutex lock;
|
||||
RESOURCE_HANDLE (rh);
|
||||
};
|
||||
|
||||
extern LumieraFilehandlecache lumiera_fhcache;
|
||||
|
||||
/**
|
||||
* Initializes the filehandle cache.
|
||||
* @param max_entries number how much filehandles shall be managed
|
||||
* The number of elements the cache can hold is static and should be
|
||||
* determined by sysconf (_SC_OPEN_MAX) minus some (big) safety margin.
|
||||
*/
|
||||
void
|
||||
lumiera_filehandlecache_new (int max_entries);
|
||||
|
||||
/**
|
||||
* Delete the filehandle cache.
|
||||
* No filehandles in the cache must be locked, this would be a fatal error.
|
||||
* The handles are closed automatically.
|
||||
*/
|
||||
void
|
||||
lumiera_filehandlecache_delete (void);
|
||||
|
||||
/**
|
||||
* Get a fresh filehandle.
|
||||
* @param self pointer to the cache
|
||||
* @return the new filehandle
|
||||
*/
|
||||
LumieraFilehandle
|
||||
lumiera_filehandlecache_handle_acquire (LumieraFilehandlecache self, LumieraFiledescriptor desc);
|
||||
|
||||
/**
|
||||
* Add filehande back to cache, the filehandle becomes subject of aging.
|
||||
* @param self pointer to the cache
|
||||
* @param handle filehandle to be put back
|
||||
*/
|
||||
void
|
||||
lumiera_filehandlecache_add_filehandle (LumieraFilehandlecache self, LumieraFilehandle handle);
|
||||
|
||||
/**
|
||||
* Remove a filehandle from cache aging
|
||||
* Filehandles which are subject of cache aging must be checked out before they can be used.
|
||||
* @param self the filehandlecache
|
||||
* @param handle the filehandle to be checked out
|
||||
*/
|
||||
LumieraFilehandle
|
||||
lumiera_filehandlecache_checkout (LumieraFilehandlecache self, LumieraFilehandle handle);
|
||||
|
||||
/**
|
||||
* Put a filehandle into the cache
|
||||
* Filehandles which are checked in are subject of cache aging and might get destroyed and reused.
|
||||
* @param self the filehandlecache
|
||||
* @param handle the filehandle to be checked in
|
||||
*/
|
||||
void
|
||||
lumiera_filehandlecache_checkin (LumieraFilehandlecache self, LumieraFilehandle handle);
|
||||
|
||||
#endif
|
||||
88
src/backend/mmap.h
Normal file
88
src/backend/mmap.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
mmap.h - memory mapped acces to files
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef LUMIERA_MMAP_H
|
||||
#define LUMIERA_MMAP_H
|
||||
|
||||
#include "lib/llist.h"
|
||||
|
||||
|
||||
typedef struct lumiera_mmap_struct lumiera_mmap;
|
||||
typedef lumiera_mmap* LumieraMMap;
|
||||
|
||||
|
||||
#include "backend/filedescriptor.h"
|
||||
|
||||
|
||||
#include <nobug.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
NOBUG_DECLARE_FLAG (mmap);
|
||||
|
||||
/**
|
||||
* @file
|
||||
* MMap objects cover a memory maped range in a file
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* mmaped area
|
||||
*
|
||||
*/
|
||||
struct lumiera_mmap_struct
|
||||
{
|
||||
/** used for the mrucache when checked in the cache OR for attaching owners when checked out **/
|
||||
llist cachenode;
|
||||
|
||||
/** all mmaps of a file are chained in this list, used to find ranges **/
|
||||
llist searchnode;
|
||||
|
||||
off_t start;
|
||||
size_t size;
|
||||
void* address;
|
||||
|
||||
/** array with refcounters per page **/
|
||||
unsigned short* refmap;
|
||||
|
||||
/** 0 when this mmap is in cache, else the count of attached owners **/
|
||||
unsigned use_cnt;
|
||||
//RESOURCE_HANDLE (rh);
|
||||
};
|
||||
|
||||
|
||||
LumieraMMap
|
||||
lumiera_mmap_init (LumieraMMap self, LumieraFile file, LList acquirer, off_t start, size_t size, size_t chunksize);
|
||||
|
||||
LumieraMMap
|
||||
lumiera_mmap_new (LumieraFile file, LList acquirer, off_t start, size_t size, size_t chunksize);
|
||||
|
||||
void*
|
||||
lumiera_mmap_destroy_node (LList node);
|
||||
|
||||
#endif
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
136
src/backend/mmapcache.h
Normal file
136
src/backend/mmapcache.h
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
mmapcache.h - handle aging of mmap objects
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef LUMIERA_MMAPCACHE_H
|
||||
#define LUMIERA_MMAPCACHE_H
|
||||
|
||||
#include "lib/error.h"
|
||||
#include "lib/mrucache.h"
|
||||
#include "lib/mutex.h"
|
||||
|
||||
|
||||
typedef struct lumiera_mmapcache_struct lumiera_mmapcache;
|
||||
typedef lumiera_mmapcache* LumieraMMapcache;
|
||||
|
||||
#include "backend/mmap.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Mmapcache stores a MRU cache of all established mmaped memory regions which are currently not in use.
|
||||
* The mmapcache also manages the upper limit about how much memory can be mmaped.
|
||||
*/
|
||||
|
||||
struct lumiera_mmapcache_struct
|
||||
{
|
||||
lumiera_mrucache cache;
|
||||
size_t limit;
|
||||
size_t total;
|
||||
size_t cached;
|
||||
lumiera_mutex lock;
|
||||
RESOURCE_HANDLE (rh);
|
||||
};
|
||||
|
||||
extern LumieraMMapcache lumiera_mcache;
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the mmapcache.
|
||||
* @param limit the mmapcache will drop elements when the sum of all mmapings gives over limit
|
||||
*/
|
||||
void
|
||||
lumiera_mmapcache_new (size_t limit);
|
||||
|
||||
/**
|
||||
* Delete the mmap cache.
|
||||
* No mmaps in the cache must be locked, this would be a fatal error.
|
||||
* The handles are closed automatically.
|
||||
*/
|
||||
void
|
||||
lumiera_mmapcache_delete (void);
|
||||
|
||||
/**
|
||||
* Get a fresh mmap object.
|
||||
* when mmaped_limit is reached, the oldest mmap object gets dropped else a new allocated object
|
||||
* is returned
|
||||
* @param self pointer to the cache
|
||||
* @return the new mmap
|
||||
*/
|
||||
LumieraMMap
|
||||
lumiera_mmapcache_mmap_acquire (LumieraMMapcache self);
|
||||
|
||||
|
||||
/**
|
||||
* Announce a new mmap object to the cache quotas.
|
||||
* Update the statistics kept in the cache,
|
||||
* the map object is still considered to be checked out
|
||||
* @param self pointer to the cache
|
||||
* @param map object to be announced
|
||||
*/
|
||||
void
|
||||
lumiera_mmapcache_announce (LumieraMMapcache self, LumieraMMap map);
|
||||
|
||||
/**
|
||||
* Remove a mmap object from the cache quotas.
|
||||
* Update the statistics kept in the cache,
|
||||
* called by mmap's destructor only
|
||||
* @param self pointer to the cache
|
||||
* @param map object to be removed
|
||||
*/
|
||||
void
|
||||
lumiera_mmapcache_forget (LumieraMMapcache self, LumieraMMap map);
|
||||
|
||||
/**
|
||||
* Destroy and free the nelem oldest elements.
|
||||
* Used to free up resources and memory.
|
||||
* @param self cache where to free elements.
|
||||
* @return nelem-(numer of elements which got freed), that is 0 if all requested elements got freed
|
||||
*/
|
||||
int
|
||||
lumiera_mmapcache_age (LumieraMMapcache self);
|
||||
|
||||
/**
|
||||
* Remove a mmap from cache aging
|
||||
* Mmaps which are subject of cache aging must be checked out before they can be used.
|
||||
* @param self the mmapcache
|
||||
* @param handle the mmap to be checked out
|
||||
*/
|
||||
LumieraMMap
|
||||
lumiera_mmapcache_checkout (LumieraMMapcache self, LumieraMMap handle);
|
||||
|
||||
/**
|
||||
* Put a mmap into the cache
|
||||
* Mmaps which are checked in are subject of cache aging and might get destroyed and reused.
|
||||
* @param self the mmapcache
|
||||
* @param handle the mmap to be checked in
|
||||
*/
|
||||
void
|
||||
lumiera_mmapcache_checkin (LumieraMMapcache self, LumieraMMap handle);
|
||||
|
||||
#endif
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
118
src/backend/mmapings.h
Normal file
118
src/backend/mmapings.h
Normal file
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
mmapings.h - manage ranges of mmaped areas on a filedescriptor
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef LUMIERA_MMAPINGS_H
|
||||
#define LUMIERA_MMAPINGS_H
|
||||
|
||||
#include "lib/mutex.h"
|
||||
#include "lib/llist.h"
|
||||
|
||||
typedef struct lumiera_mmapings_struct lumiera_mmapings;
|
||||
typedef lumiera_mmapings* LumieraMMapings;
|
||||
|
||||
#include "backend/filedescriptor.h"
|
||||
#include "backend/mmap.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Keeps all mmaped areas
|
||||
*
|
||||
*/
|
||||
|
||||
struct lumiera_mmapings_struct
|
||||
{
|
||||
/** mmaped ranges are kept in an list sorted by the size of the mmaping, might be improved to a tree someday **/
|
||||
llist mmaps;
|
||||
|
||||
/** sum of all mmaped areas, areas might be overlapping **/
|
||||
// size_t vsz;
|
||||
|
||||
/**
|
||||
* chunkssize is the smallest granularity which is used for mmapping files, it
|
||||
* should reflect the intended file usage, that is 'pagesize' for small or non growing
|
||||
* files and some MB for media files. Must be a 2's exponent of pagesize.
|
||||
**/
|
||||
size_t chunksize;
|
||||
|
||||
LumieraFiledescriptor descriptor;
|
||||
lumiera_mutex lock;
|
||||
RESOURCE_HANDLE (rh);
|
||||
};
|
||||
|
||||
/**
|
||||
* initialize mmapings container
|
||||
*
|
||||
*/
|
||||
LumieraMMapings
|
||||
lumiera_mmapings_init (LumieraMMapings self, LumieraFile file, size_t chunksize);
|
||||
|
||||
/**
|
||||
* destroy mmapings container and free all resources.
|
||||
*
|
||||
*/
|
||||
LumieraMMapings
|
||||
lumiera_mmapings_destroy (LumieraMMapings self);
|
||||
|
||||
/**
|
||||
* allocate and initialize new mmapings container
|
||||
*
|
||||
*/
|
||||
LumieraMMapings
|
||||
lumiera_mmapings_new (LumieraFile file, size_t chunksize);
|
||||
|
||||
/**
|
||||
* destroy and free mmapings container and all its resources
|
||||
*
|
||||
*/
|
||||
void
|
||||
lumiera_mmapings_delete (LumieraMMapings self);
|
||||
|
||||
/**
|
||||
* acquire a mmap which covers the given range
|
||||
* @param self mmapings where to search
|
||||
* @param acquirer list node of the new owner which will registered in the mmap
|
||||
* @param start begin of the required range
|
||||
* @param size requested size
|
||||
* @return MMap object covering the requested range or NULL on error
|
||||
*/
|
||||
LumieraMMap
|
||||
lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, LList acquirer, off_t start, size_t size);
|
||||
|
||||
/**
|
||||
* release a previously acquired MMap object
|
||||
* @param self mmapings to which the map belongs
|
||||
* @param acquirer holding node
|
||||
* @param map object to be released
|
||||
*/
|
||||
void
|
||||
lumiera_mmapings_release_mmap (LumieraMMapings self, LList acquirer, LumieraMMap map);
|
||||
|
||||
#endif
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
65
src/common/Makefile.am
Normal file
65
src/common/Makefile.am
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
# Copyright (C) Lumiera.org
|
||||
# 2008, Christian Thaeter <ct@pipapo.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
# TODO use -Wextra -Werror
|
||||
|
||||
liblumicommon_a_srcdir = $(top_srcdir)/src/common
|
||||
noinst_LIBRARIES += liblumicommon.a
|
||||
|
||||
liblumicommon_a_CXXFLAGS = $(CXXFLAGS) -Wall
|
||||
liblumicommon_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumicommon_a_SOURCES = \
|
||||
$(liblumicommon_a_srcdir)/time.cpp \
|
||||
$(liblumicommon_a_srcdir)/util.cpp \
|
||||
$(liblumicommon_a_srcdir)/visitor.cpp \
|
||||
$(liblumicommon_a_srcdir)/cmdline.cpp \
|
||||
$(liblumicommon_a_srcdir)/configrules.cpp \
|
||||
$(liblumicommon_a_srcdir)/error.cpp \
|
||||
$(liblumicommon_a_srcdir)/query.cpp \
|
||||
$(liblumicommon_a_srcdir)/query/mockconfigrules.cpp \
|
||||
$(liblumicommon_a_srcdir)/test/suite.cpp \
|
||||
$(liblumicommon_a_srcdir)/test/testoption.cpp
|
||||
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(liblumicommon_a_srcdir)/cmdline.hpp \
|
||||
$(liblumicommon_a_srcdir)/factory.hpp \
|
||||
$(liblumicommon_a_srcdir)/singleton.hpp \
|
||||
$(liblumicommon_a_srcdir)/singletonpolicies.hpp \
|
||||
$(liblumicommon_a_srcdir)/singletonpreconfigure.hpp \
|
||||
$(liblumicommon_a_srcdir)/time.hpp \
|
||||
$(liblumicommon_a_srcdir)/typelist.hpp \
|
||||
$(liblumicommon_a_srcdir)/visitor.hpp \
|
||||
$(liblumicommon_a_srcdir)/visitordispatcher.hpp \
|
||||
$(liblumicommon_a_srcdir)/visitorpolicies.hpp \
|
||||
$(liblumicommon_a_srcdir)/configrules.hpp \
|
||||
$(liblumicommon_a_srcdir)/error.hpp \
|
||||
$(liblumicommon_a_srcdir)/multithread.hpp \
|
||||
$(liblumicommon_a_srcdir)/p.hpp \
|
||||
$(liblumicommon_a_srcdir)/query.hpp \
|
||||
$(liblumicommon_a_srcdir)/query/mockconfigrules.hpp \
|
||||
$(liblumicommon_a_srcdir)/singletonfactory.hpp \
|
||||
$(liblumicommon_a_srcdir)/singletonsubclass.hpp \
|
||||
$(liblumicommon_a_srcdir)/typelistutil.hpp \
|
||||
$(liblumicommon_a_srcdir)/util.hpp \
|
||||
$(liblumicommon_a_srcdir)/test/mockinjector.hpp \
|
||||
$(liblumicommon_a_srcdir)/test/suite.hpp \
|
||||
$(liblumicommon_a_srcdir)/test/testoption.hpp \
|
||||
$(liblumicommon_a_srcdir)/test/run.hpp
|
||||
|
||||
|
|
@ -21,23 +21,30 @@ noinst_LIBRARIES += liblumi.a
|
|||
liblumi_a_CFLAGS = $(CFLAGS) -std=gnu99 -Wall -Werror
|
||||
liblumi_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumi_a_SOURCES = \
|
||||
$(liblumi_a_srcdir)/plugin.c \
|
||||
$(liblumi_a_srcdir)/error.c \
|
||||
$(liblumi_a_srcdir)/framerate.c \
|
||||
$(liblumi_a_srcdir)/mutex.c \
|
||||
$(liblumi_a_srcdir)/rwlock.c \
|
||||
$(liblumi_a_srcdir)/condition.c \
|
||||
$(liblumi_a_srcdir)/references.c
|
||||
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(liblumi_a_srcdir)/plugin.h \
|
||||
$(liblumi_a_srcdir)/error.h \
|
||||
$(liblumi_a_srcdir)/framerate.h \
|
||||
$(liblumi_a_srcdir)/locking.h \
|
||||
$(liblumi_a_srcdir)/mutex.h \
|
||||
$(liblumi_a_srcdir)/rwlock.h \
|
||||
$(liblumi_a_srcdir)/condition.h \
|
||||
$(liblumi_a_srcdir)/references.h
|
||||
liblumi_a_SOURCES = \
|
||||
$(liblumi_a_srcdir)/plugin.c \
|
||||
$(liblumi_a_srcdir)/error.c \
|
||||
$(liblumi_a_srcdir)/mutex.c \
|
||||
$(liblumi_a_srcdir)/rwlock.c \
|
||||
$(liblumi_a_srcdir)/condition.c \
|
||||
$(liblumi_a_srcdir)/references.c \
|
||||
$(liblumi_a_srcdir)/uuid.c \
|
||||
$(liblumi_a_srcdir)/safeclib.c \
|
||||
$(liblumi_a_srcdir)/cuckoo.c \
|
||||
$(liblumi_a_srcdir)/mrucache.c \
|
||||
$(liblumi_a_srcdir)/appconfig.cpp
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(liblumi_a_srcdir)/plugin.h \
|
||||
$(liblumi_a_srcdir)/error.h \
|
||||
$(liblumi_a_srcdir)/locking.h \
|
||||
$(liblumi_a_srcdir)/mutex.h \
|
||||
$(liblumi_a_srcdir)/rwlock.h \
|
||||
$(liblumi_a_srcdir)/condition.h \
|
||||
$(liblumi_a_srcdir)/references.h \
|
||||
$(liblumi_a_srcdir)/uuid.h \
|
||||
$(liblumi_a_srcdir)/safeclib.h \
|
||||
$(liblumi_a_srcdir)/cuckoo.h \
|
||||
$(liblumi_a_srcdir)/mrucache.h \
|
||||
$(liblumi_a_srcdir)/appconfig.hpp \
|
||||
$(liblumi_a_srcdir)/lifecycleregistry.hpp
|
||||
|
|
|
|||
|
|
@ -22,9 +22,12 @@
|
|||
#include "lib/condition.h"
|
||||
|
||||
/**
|
||||
* @file Condition variables
|
||||
* @file
|
||||
* Condition variables
|
||||
*/
|
||||
|
||||
LUMIERA_ERROR_DEFINE (CONDITION_DESTROY, "condition destroy failed");
|
||||
|
||||
/**
|
||||
* Initialize a condition variable
|
||||
* @param self is a pointer to the condition variable to be initialized
|
||||
|
|
@ -53,9 +56,9 @@ lumiera_condition_destroy (LumieraCondition self)
|
|||
if (self)
|
||||
{
|
||||
if (pthread_mutex_destroy (&self->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_DESTROY);
|
||||
else if (pthread_cond_destroy (&self->cond))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (CONDITION_DESTROY);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,9 +25,11 @@
|
|||
#include "lib/locking.h"
|
||||
|
||||
/**
|
||||
* @file Condition variables, header
|
||||
* @file
|
||||
* Condition variables, header
|
||||
*/
|
||||
|
||||
LUMIERA_ERROR_DECLARE (CONDITION_DESTROY);
|
||||
|
||||
/**
|
||||
* Condition variables.
|
||||
|
|
@ -59,10 +61,10 @@ lumiera_condition_signal (LumieraCondition self)
|
|||
{
|
||||
REQUIRE (self);
|
||||
if (pthread_mutex_lock (&self->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_LOCK);
|
||||
pthread_cond_signal (&self->cond);
|
||||
if (pthread_mutex_unlock (&self->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_UNLOCK);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,10 +76,10 @@ lumiera_condition_broadcast (LumieraCondition self)
|
|||
{
|
||||
REQUIRE (self);
|
||||
if (pthread_mutex_lock (&self->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_LOCK);
|
||||
pthread_cond_broadcast (&self->cond);
|
||||
if (pthread_mutex_unlock (&self->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_UNLOCK);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -124,7 +126,7 @@ lumiera_conditionacquirer_init (LumieraConditionacquirer self, LumieraCondition
|
|||
self->state = state;
|
||||
if (state == LUMIERA_LOCKED)
|
||||
if (pthread_mutex_lock (&cond->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_LOCK);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
@ -141,7 +143,7 @@ lumiera_conditionacquirer_lock (LumieraConditionacquirer self)
|
|||
REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked");
|
||||
|
||||
if (pthread_mutex_lock (&self->cond->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_LOCK);
|
||||
|
||||
self->state = LUMIERA_LOCKED;
|
||||
}
|
||||
|
|
@ -166,13 +168,13 @@ lumiera_conditionacquirer_wait (LumieraConditionacquirer self)
|
|||
* a conditionacquirer must be unlocked before leaving scope
|
||||
* @param self conditionacquirer associated with a condition variable
|
||||
*/
|
||||
static inline int
|
||||
static inline void
|
||||
lumiera_conditionacquirer_unlock (LumieraConditionacquirer self)
|
||||
{
|
||||
REQUIRE (self);
|
||||
REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked");
|
||||
if (pthread_mutex_unlock (&self->cond->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_UNLOCK);
|
||||
self->state = LUMIERA_UNLOCKED;
|
||||
}
|
||||
|
||||
|
|
@ -194,7 +196,7 @@ lumiera_conditionacquirer_signal (LumieraConditionacquirer self)
|
|||
* signal all waiting threads
|
||||
* @param self conditionacquirer associated with the condition variable to be signaled
|
||||
*/
|
||||
static inline int
|
||||
static inline void
|
||||
lumiera_conditionacquirer_broadcast (LumieraConditionacquirer self)
|
||||
{
|
||||
REQUIRE (self);
|
||||
|
|
|
|||
504
src/lib/cuckoo.c
Normal file
504
src/lib/cuckoo.c
Normal file
|
|
@ -0,0 +1,504 @@
|
|||
/*
|
||||
A cuckoo hash implementation
|
||||
|
||||
Copyright (C)
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "cuckoo.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
enum compact_state
|
||||
{
|
||||
COMPACTING_OFF,
|
||||
COMPACTING_AUTO,
|
||||
COMPACTED
|
||||
};
|
||||
|
||||
struct cuckoo_struct
|
||||
{
|
||||
size_t size; /* t1 = 4*size; t2 = 2*size; t3 = size */
|
||||
size_t itemsize;
|
||||
|
||||
cuckoo_hashfunc h1; /* hash function */
|
||||
uint32_t r1; /* random, reset for each rehash */
|
||||
cuckoo_hashfunc h2;
|
||||
uint32_t r2;
|
||||
cuckoo_hashfunc h3;
|
||||
uint32_t r3;
|
||||
|
||||
cuckoo_cmpfunc cmp;
|
||||
|
||||
void* t1;
|
||||
void* t2;
|
||||
void* t3;
|
||||
|
||||
unsigned maxloops; /* sqrt (4 * size) */
|
||||
|
||||
enum compact_state autocompact;
|
||||
size_t elements;
|
||||
};
|
||||
|
||||
|
||||
static inline uint32_t cuckoo_fast_prng ()
|
||||
{
|
||||
static uint32_t rnd = 0xbabeface;
|
||||
return rnd = rnd<<1 ^ ((rnd>>30) & 1) ^ ((rnd>>2) & 1);
|
||||
}
|
||||
|
||||
Cuckoo
|
||||
cuckoo_init (Cuckoo self,
|
||||
cuckoo_hashfunc h1,
|
||||
cuckoo_hashfunc h2,
|
||||
cuckoo_hashfunc h3,
|
||||
cuckoo_cmpfunc cmp,
|
||||
size_t itemsize,
|
||||
unsigned startsize)
|
||||
{
|
||||
if (!self)
|
||||
return NULL;
|
||||
|
||||
self->size = 1<<startsize;
|
||||
self->itemsize = itemsize;
|
||||
self->h1 = h1;
|
||||
self->r1 = cuckoo_fast_prng ();
|
||||
self->h2 = h2;
|
||||
self->r2 = cuckoo_fast_prng ();
|
||||
self->h3 = h3;
|
||||
self->r3 = cuckoo_fast_prng ();
|
||||
|
||||
self->cmp = cmp;
|
||||
|
||||
self->t1 = calloc (self->size * 4, itemsize);
|
||||
self->t2 = calloc (self->size * 2, itemsize);
|
||||
self->t3 = calloc (self->size, itemsize);
|
||||
if (!self->t1 || !self->t2 || !self->t3)
|
||||
{
|
||||
free (self->t1);
|
||||
free (self->t2);
|
||||
free (self->t3);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
self->maxloops = 1;
|
||||
while (self->maxloops * self->maxloops < self->size * 4)
|
||||
++self->maxloops;
|
||||
|
||||
self->autocompact = COMPACTING_AUTO;
|
||||
self->elements = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
Cuckoo
|
||||
cuckoo_new (cuckoo_hashfunc h1,
|
||||
cuckoo_hashfunc h2,
|
||||
cuckoo_hashfunc h3,
|
||||
cuckoo_cmpfunc cmp,
|
||||
size_t itemsize,
|
||||
unsigned startsize)
|
||||
{
|
||||
Cuckoo self = malloc (sizeof (struct cuckoo_struct));
|
||||
if (!cuckoo_init (self, h1, h2, h3, cmp, itemsize, startsize))
|
||||
{
|
||||
free (self);
|
||||
return NULL;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
Cuckoo
|
||||
cuckoo_destroy (Cuckoo self)
|
||||
{
|
||||
if (self)
|
||||
{
|
||||
free (self->t1);
|
||||
free (self->t2);
|
||||
free (self->t3);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cuckoo_free (Cuckoo self)
|
||||
{
|
||||
free (cuckoo_destroy (self));
|
||||
}
|
||||
|
||||
|
||||
static inline int
|
||||
iszero (void* mem, size_t size)
|
||||
{
|
||||
while (size && !*(int*)mem)
|
||||
{
|
||||
size -= sizeof (int);
|
||||
mem += sizeof (int);
|
||||
}
|
||||
return !size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
xmemcpy (void* dst, void* src, size_t size)
|
||||
{
|
||||
while (size)
|
||||
{
|
||||
size -= sizeof (int);
|
||||
*(int*)(dst + size) = *(int*)(src + size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
cuckoo_insert_internal_ (Cuckoo self, void* item)
|
||||
{
|
||||
void* pos;
|
||||
char tmp[self->itemsize];
|
||||
|
||||
for (unsigned n = 0; n < self->maxloops; ++n)
|
||||
{
|
||||
/* find nest */
|
||||
pos = self->t1 + self->itemsize * (self->h1 (item, self->r1) % (4*self->size));
|
||||
/* kick old egg out */
|
||||
xmemcpy (tmp, pos, self->itemsize);
|
||||
/* lay egg */
|
||||
xmemcpy (pos, item, self->itemsize);
|
||||
|
||||
if (iszero (tmp, self->itemsize))
|
||||
return 1;
|
||||
|
||||
/* find nest */
|
||||
pos = self->t2 + self->itemsize * (self->h2 (tmp, self->r2) % (2*self->size));
|
||||
/* kick old egg out */
|
||||
xmemcpy (item, pos, self->itemsize);
|
||||
/* lay egg */
|
||||
xmemcpy (pos, tmp, self->itemsize);
|
||||
|
||||
if (iszero (item, self->itemsize))
|
||||
return 1;
|
||||
|
||||
/* find nest */
|
||||
pos = self->t3 + self->itemsize * (self->h3 (item, self->r3) % self->size);
|
||||
/* kick old egg out */
|
||||
xmemcpy (tmp, pos, self->itemsize);
|
||||
/* lay egg */
|
||||
xmemcpy (pos, item, self->itemsize);
|
||||
|
||||
if (iszero (tmp, self->itemsize))
|
||||
return 1;
|
||||
|
||||
/* copy tmp to item, which will be reinserted on next interation / after rehashing */
|
||||
xmemcpy (item, tmp, self->itemsize);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
cuckoo_nelements (Cuckoo self)
|
||||
{
|
||||
return self->elements;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
cuckoo_rehash (Cuckoo self)
|
||||
{
|
||||
retry1:
|
||||
|
||||
self->r1 = cuckoo_fast_prng ();
|
||||
|
||||
for (size_t i = 0; i < 4*self->size; ++i)
|
||||
{
|
||||
unsigned n;
|
||||
void* pos = self->t1 + self->itemsize * i;
|
||||
if (!iszero (pos, self->itemsize))
|
||||
{
|
||||
for (n = 0; n < self->maxloops; ++n)
|
||||
{
|
||||
unsigned hash = self->h1 (pos, self->r1) % (4*self->size);
|
||||
if (hash != i)
|
||||
{
|
||||
char t[self->itemsize];
|
||||
void* hpos = self->t1 + self->itemsize * hash;
|
||||
xmemcpy (t, hpos, self->itemsize);
|
||||
xmemcpy (hpos, pos, self->itemsize);
|
||||
xmemcpy (pos, t, self->itemsize);
|
||||
if (iszero (t, self->itemsize))
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (n == self->maxloops)
|
||||
goto retry1;
|
||||
}
|
||||
}
|
||||
|
||||
retry2:
|
||||
self->r2 = cuckoo_fast_prng ();
|
||||
|
||||
for (size_t i = 0; i < 2*self->size; ++i)
|
||||
{
|
||||
unsigned n;
|
||||
void* pos = self->t2 + self->itemsize * i;
|
||||
if (!iszero (pos, self->itemsize))
|
||||
{
|
||||
for (n = 0; n < self->maxloops; ++n)
|
||||
{
|
||||
unsigned hash = self->h2 (pos, self->r2) % (2*self->size);
|
||||
if (hash != i)
|
||||
{
|
||||
char t[self->itemsize];
|
||||
void* hpos = self->t2 + self->itemsize * hash;
|
||||
xmemcpy (t, hpos, self->itemsize);
|
||||
xmemcpy (hpos, pos, self->itemsize);
|
||||
xmemcpy (pos, t, self->itemsize);
|
||||
if (iszero (t, self->itemsize))
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (n == self->maxloops)
|
||||
goto retry2;
|
||||
}
|
||||
}
|
||||
|
||||
retry3:
|
||||
self->r3 = cuckoo_fast_prng ();
|
||||
|
||||
for (size_t i = 0; i < self->size; ++i)
|
||||
{
|
||||
unsigned n;
|
||||
void* pos = self->t3 + self->itemsize * i;
|
||||
if (!iszero (pos, self->itemsize))
|
||||
{
|
||||
for (n = 0; n < self->maxloops; ++n)
|
||||
{
|
||||
unsigned hash = self->h3 (pos, self->r3) % self->size;
|
||||
if (hash != i)
|
||||
{
|
||||
char t[self->itemsize];
|
||||
void* hpos = self->t3 + self->itemsize * hash;
|
||||
xmemcpy (t, hpos, self->itemsize);
|
||||
xmemcpy (hpos, pos, self->itemsize);
|
||||
xmemcpy (pos, t, self->itemsize);
|
||||
if (iszero (t, self->itemsize))
|
||||
break;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (n == self->maxloops)
|
||||
goto retry3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
cuckoo_grow (Cuckoo self)
|
||||
{
|
||||
/* rotate hashfuncs, tables, randoms */
|
||||
cuckoo_hashfunc th = self->h3;
|
||||
self->h3 = self->h2;
|
||||
self->h2 = self->h1;
|
||||
self->h1 = th;
|
||||
|
||||
uint32_t tr = self->r3;
|
||||
self->r3 = self->r2;
|
||||
self->r2 = self->r1;
|
||||
self->r1 = tr;
|
||||
|
||||
void* tt = self->t3;
|
||||
self->t3 = self->t2;
|
||||
self->t2 = self->t1;
|
||||
|
||||
/* double new base size */
|
||||
self->size *= 2;
|
||||
while (self->maxloops * self->maxloops < self->size * 4)
|
||||
++self->maxloops;
|
||||
|
||||
/* alloc new t1 */
|
||||
self->t1 = calloc (self->size * 4, self->itemsize);
|
||||
if (!self->t1)
|
||||
{
|
||||
self->t1 = tt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reinsert tt */
|
||||
size_t ttsize = self->size / 2;
|
||||
for (size_t i = 0; i < ttsize; ++i)
|
||||
{
|
||||
void* pos = tt + i * self->itemsize;
|
||||
if (!iszero (pos, self->itemsize))
|
||||
{
|
||||
while (!cuckoo_insert_internal_ (self, pos))
|
||||
cuckoo_rehash (self);
|
||||
}
|
||||
}
|
||||
free (tt);
|
||||
|
||||
self->autocompact = COMPACTING_AUTO;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cuckoo_reserve (Cuckoo self, size_t more)
|
||||
{
|
||||
int ret = 1;
|
||||
if (more)
|
||||
while (self->elements+self->maxloops+more >= 6*self->size)
|
||||
ret = cuckoo_grow (self);
|
||||
|
||||
self->autocompact = COMPACTING_OFF;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cuckoo_compact (Cuckoo self)
|
||||
{
|
||||
if (self->autocompact == COMPACTED)
|
||||
return 1;
|
||||
|
||||
if (self->size > 2 && self->elements < self->size * 3)
|
||||
{
|
||||
cuckoo_hashfunc th = self->h1;
|
||||
self->h1 = self->h2;
|
||||
self->h2 = self->h3;
|
||||
self->h3 = th;
|
||||
|
||||
uint32_t tr = self->r1;
|
||||
self->r1 = self->r2;
|
||||
self->r2 = self->r3;
|
||||
self->r3 = tr;
|
||||
|
||||
void* tt = self->t1;
|
||||
self->t1 = self->t2;
|
||||
self->t2 = self->t3;
|
||||
|
||||
/* halve base size */
|
||||
self->size /= 2;
|
||||
while (self->maxloops * self->maxloops >= self->size * 4)
|
||||
--self->maxloops;
|
||||
|
||||
/* alloc new t3 */
|
||||
self->t3 = calloc (self->size, self->itemsize);
|
||||
if (!self->t3)
|
||||
{
|
||||
self->t3 = tt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reinsert tt */
|
||||
size_t ttsize = self->size * 8;
|
||||
for (size_t i = 0; i < ttsize; ++i)
|
||||
{
|
||||
void* pos = tt + i * self->itemsize;
|
||||
if (!iszero (pos, self->itemsize))
|
||||
{
|
||||
--self->elements;
|
||||
cuckoo_insert (self, pos);
|
||||
}
|
||||
}
|
||||
free (tt);
|
||||
self->autocompact = COMPACTED;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
cuckoo_insert (Cuckoo self, void* item)
|
||||
{
|
||||
char tmp[self->itemsize];
|
||||
|
||||
void* found;
|
||||
if ((found = cuckoo_find (self, item)))
|
||||
{
|
||||
xmemcpy (found, item, self->itemsize);
|
||||
return 1;
|
||||
}
|
||||
|
||||
xmemcpy (tmp, item, self->itemsize);
|
||||
|
||||
for (unsigned n = 6; n; --n) /* rehash/grow loop */
|
||||
{
|
||||
if (cuckoo_insert_internal_ (self, tmp))
|
||||
{
|
||||
++self->elements;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (self->elements > n*self->size)
|
||||
{
|
||||
n = 6;
|
||||
if (!cuckoo_grow (self))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
cuckoo_rehash (self);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
cuckoo_find (Cuckoo self, void* item)
|
||||
{
|
||||
void* pos;
|
||||
|
||||
pos = self->t1 + self->itemsize * (self->h1 (item, self->r1) % (4*self->size));
|
||||
if (!iszero (pos, self->itemsize) && self->cmp (item, pos))
|
||||
return pos;
|
||||
|
||||
pos = self->t2 + self->itemsize * (self->h2 (item, self->r2) % (2*self->size));
|
||||
if (!iszero (pos, self->itemsize) && self->cmp (item, pos))
|
||||
return pos;
|
||||
|
||||
pos = self->t3 + self->itemsize * (self->h3 (item, self->r3) % self->size);
|
||||
if (!iszero (pos, self->itemsize) && self->cmp (item, pos))
|
||||
return pos;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
cuckoo_remove (Cuckoo self, void* item)
|
||||
{
|
||||
if (item)
|
||||
{
|
||||
memset (item, 0, self->itemsize);
|
||||
--self->elements;
|
||||
|
||||
if (self->autocompact == COMPACTING_AUTO && self->size > 2 && self->elements <= self->size*2)
|
||||
cuckoo_compact (self);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
175
src/lib/cuckoo.h
Normal file
175
src/lib/cuckoo.h
Normal file
|
|
@ -0,0 +1,175 @@
|
|||
/*
|
||||
A cuckoo hash implementation
|
||||
|
||||
Copyright (C)
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef CUCKOO_H
|
||||
#define CUCKOO_H
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Cuckoo hashing
|
||||
* This hashing gives guaranteed O(1) lookup complexity and amortized O(1) insert and remove complexity.
|
||||
* Hash tables by default grow and shrink automatically. It is posible to preallocate entries and turn
|
||||
* automatic shrinking off taking out the memory management factors for insert and remove operations.
|
||||
* This implementation uses 3 Tables which exponential growing sizes.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
|
||||
struct cuckoo_struct;
|
||||
typedef struct cuckoo_struct * Cuckoo;
|
||||
|
||||
/**
|
||||
* Hash function.
|
||||
* User supplied universal hash function
|
||||
* @param item address of the item to be hashed
|
||||
* @param r pseudo random number, 31 significant bits, regenerated on each rehash
|
||||
* @return hash value
|
||||
*/
|
||||
typedef size_t (*cuckoo_hashfunc)(const void* item, const uint32_t r);
|
||||
|
||||
/**
|
||||
* Compare function.
|
||||
* User supplied compare function
|
||||
* @param item1 address of the first item
|
||||
* @param item2 address of the second item
|
||||
* @return 1 when the items are identical, 0 otherwise
|
||||
*/
|
||||
typedef int (*cuckoo_cmpfunc)(const void* item1, const void* item2);
|
||||
|
||||
/**
|
||||
* Initialize a cuckoo hash.
|
||||
* @param self pointer to a uninitialized cuckoo datastructure
|
||||
* @param h1 hash function for the first table
|
||||
* @param h2 hash function for the second table
|
||||
* @param h3 hash function for the third table
|
||||
* @param cmp function which compares two keys
|
||||
* @param startsize initial size of table t3, as 2's exponent
|
||||
* @return The initialized hashtable or NULL at allocation failure
|
||||
*/
|
||||
Cuckoo
|
||||
cuckoo_init (Cuckoo self,
|
||||
cuckoo_hashfunc h1,
|
||||
cuckoo_hashfunc h2,
|
||||
cuckoo_hashfunc h3,
|
||||
cuckoo_cmpfunc cmp,
|
||||
size_t itemsize,
|
||||
unsigned startsize);
|
||||
|
||||
/**
|
||||
* Allocate a new cuckoo hash.
|
||||
* @param h1 hash function for the first table
|
||||
* @param h2 hash function for the second table
|
||||
* @param h3 hash function for the third table
|
||||
* @param cmp function which compares two keys
|
||||
* @param startsize initial size of table t3, as 2's exponent
|
||||
* @return The initialized hashtable or NULL at allocation failure
|
||||
*/
|
||||
Cuckoo
|
||||
cuckoo_new (cuckoo_hashfunc h1,
|
||||
cuckoo_hashfunc h2,
|
||||
cuckoo_hashfunc h3,
|
||||
cuckoo_cmpfunc cmp,
|
||||
size_t itemsize,
|
||||
unsigned startsize);
|
||||
|
||||
/**
|
||||
* Destroy a cuckoo hash.
|
||||
* Frees internal used resources.
|
||||
* @param self cuckoo hash to destroy
|
||||
* @return The now uninitialized hashtable
|
||||
*/
|
||||
Cuckoo
|
||||
cuckoo_destroy (Cuckoo self);
|
||||
|
||||
/**
|
||||
* Deallocate a cuckoo hash.
|
||||
* @param self handle of the hash table to be freed
|
||||
*/
|
||||
void
|
||||
cuckoo_free (Cuckoo self);
|
||||
|
||||
/**
|
||||
* Get the number of elements stored in a hash.
|
||||
* @return number of elements, 0 when empty
|
||||
*/
|
||||
size_t
|
||||
cuckoo_nelements (Cuckoo self);
|
||||
|
||||
/**
|
||||
* Insert an element into a hash.
|
||||
* amortized O(1) complexity because it may rarely rehash the tables or even grow them.
|
||||
* see cuckoo_reserve() about how to preallocate entries to prevent the growing costs.
|
||||
* @param self handle to the hash table
|
||||
* @param item pointer to a item to be inserted
|
||||
* @return 1 on successful insert, 0 on allocation failure
|
||||
* Note: at failure there is one arbitary hash cell lost!
|
||||
*/
|
||||
int
|
||||
cuckoo_insert (Cuckoo self, void* item);
|
||||
|
||||
/**
|
||||
* Find a value by key in a hash.
|
||||
* @param self handle to the hash table
|
||||
* @param item pointer to an item to be looked up
|
||||
* @return found object or NULL if not present
|
||||
*/
|
||||
void*
|
||||
cuckoo_find (Cuckoo self, void* item);
|
||||
|
||||
/**
|
||||
* Remove a item from a hash.
|
||||
* amortized O(1) complexity when it automatically shrink its tables.
|
||||
* guaranteed O(1) complexity when automatic shrinking is turned off.
|
||||
* see cuckoo_reserve() about how turn automatic shrinking off.
|
||||
* @param self handle to the hash table
|
||||
* @param item pointer to the item to be removed
|
||||
*/
|
||||
void
|
||||
cuckoo_remove (Cuckoo self, void* item);
|
||||
|
||||
/**
|
||||
* Shrink the hash sizes when possible and turn autocompacting on.
|
||||
* only useful when autmatic shrinking is turned off.
|
||||
* see cuckoo_reserve() about how turn shrinking off.
|
||||
* @param self handle to the hash table
|
||||
*/
|
||||
int
|
||||
cuckoo_compact (Cuckoo self);
|
||||
|
||||
/**
|
||||
* Prereserve hash entries and turn autocompacting off.
|
||||
* @param self handle to the hash table
|
||||
* @param more number of entries to be additionally reserved
|
||||
* In rare circumstances inserting into a hash which has reserved some entries
|
||||
* it may still need to rehash (or even rarer) to grow the table.
|
||||
* While autocompacting is turned off, removing is completely O(1).
|
||||
*/
|
||||
int
|
||||
cuckoo_reserve (Cuckoo self, size_t more);
|
||||
|
||||
#endif
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
|
|
@ -24,7 +24,8 @@
|
|||
#include "lib/error.h"
|
||||
|
||||
/**
|
||||
* @file C Error handling in Lumiera.
|
||||
* @file
|
||||
* C Error handling in Lumiera.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,8 @@ extern "C" {
|
|||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @file C Error handling in Lumiera, header.
|
||||
* @file
|
||||
* C Error handling in Lumiera, header.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -39,7 +40,8 @@ extern "C" {
|
|||
* Abort unconditionally with a 'Fatal Error!' message.
|
||||
* This macro is used whenever the program end up in a invalid state from which no runtime recovery is possible
|
||||
*/
|
||||
#define LUMIERA_DIE do { NOBUG_ERROR(NOBUG_ON, "Fatal Error!"); abort(); } while(0)
|
||||
#define LUMIERA_DIE(err) \
|
||||
do { NOBUG_ERROR(NOBUG_ON, "Fatal Error: %s ", strchr(LUMIERA_ERROR_##err, ':')); abort(); } while(0)
|
||||
|
||||
/**
|
||||
* Forward declare an error constant.
|
||||
|
|
@ -58,7 +60,8 @@ extern const char* LUMIERA_ERROR_##err
|
|||
#define LUMIERA_ERROR_DEFINE(err, msg) \
|
||||
const char* LUMIERA_ERROR_##err = "LUMIERA_ERROR_" #err ":" msg
|
||||
|
||||
/** Helper macro to raise an error for the current thread.
|
||||
/**
|
||||
* Helper macro to raise an error for the current thread.
|
||||
* This macro eases setting an error. It adds NoBug logging support to the low level error handling.
|
||||
* @param flag NoBug flag describing the subsystem where the error was raised
|
||||
* @param err name of the error without the 'LUMIERA_ERROR_' prefix (example: NO_MEMORY)
|
||||
|
|
|
|||
|
|
@ -1,107 +0,0 @@
|
|||
/*
|
||||
framerate.h - framerate calculations
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef LUMIERA_FRAMERATE_H
|
||||
#define LUMIERA_FRAMERATE_H
|
||||
|
||||
#include <limits.h>
|
||||
|
||||
#include "lib/error.h"
|
||||
|
||||
/**
|
||||
* @file Framerate calculations, header.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* framerates are defined as a rational number
|
||||
* for example NTSC with 30000/1001fps
|
||||
*/
|
||||
struct lumiera_framerate_struct
|
||||
{
|
||||
unsigned n; //numerator
|
||||
unsigned d; //denominator
|
||||
};
|
||||
|
||||
typedef struct lumiera_framerate_struct lumiera_framerate;
|
||||
typedef lumiera_framerate* LumieraFramerate;
|
||||
|
||||
typedef signed long lumiera_framepos;
|
||||
|
||||
LUMIERA_ERROR_DECLARE(FRAMERATE_ILLEGAL_TIME);
|
||||
LUMIERA_ERROR_DECLARE(FRAMERATE_ILLEGAL_FRAME);
|
||||
|
||||
#define LUMIERA_FRAMEPOS_ERROR LONG_MIN
|
||||
|
||||
/**
|
||||
* Get the frame number of a given time at a given frame rate.
|
||||
* frame indexing starts with 1
|
||||
* @param framerate is a pointer to the framerate used, defined as rational number. Must be given.
|
||||
* @param time is a pointer to a lumiera_time which shall be converted.
|
||||
* @return frame at the given time or LUMIERA_FRAMEPOS_ERROR on error.
|
||||
*/
|
||||
static inline lumiera_framepos
|
||||
lumiera_framerate_frame_get_time (const LumieraFramerate framerate, LumieraTime time)
|
||||
{
|
||||
REQUIRE (framerate);
|
||||
if (!time || time->tv_sec == (time_t)-1)
|
||||
{
|
||||
lumiera_error_set(LUMIERA_ERROR_FRAMERATE_ILLEGAL_TIME);
|
||||
return LUMIERA_FRAMEPOS_ERROR;
|
||||
}
|
||||
|
||||
/* we add a magic microsecond for rounding, because of integer truncation frames may be calculated at most 1us earlier,
|
||||
the idea is to compensate odd framerates which fall out off microsecond precision.
|
||||
*/
|
||||
return ((time->tv_sec * 1000000ULL + time->tv_usec + /*magic*/1) * framerate->n)/(framerate->d * 1000000ULL) + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the start time for a frame.
|
||||
* frame indexing starts with 1
|
||||
* @param framerate is a pointer to the framerate used, defined as rational number. Must be given.
|
||||
* @param time is a pointer to a lumiera_time which shall take the result.
|
||||
* @param frame frame number to be converted to time. This frame number must be greater than 0.
|
||||
* @return the pointer given in time or NULL on error (or when it was given as time).
|
||||
*/
|
||||
static inline LumieraTime
|
||||
lumiera_framerate_time_get_time_frame (const LumieraFramerate framerate,
|
||||
LumieraTime time,
|
||||
lumiera_framepos frame)
|
||||
{
|
||||
REQUIRE (framerate);
|
||||
if (time)
|
||||
{
|
||||
if (frame < 1)
|
||||
{
|
||||
lumiera_error_set(LUMIERA_ERROR_FRAMERATE_ILLEGAL_FRAME);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
unsigned long long usec = ((frame-1) * framerate->d * 1000000ULL - (/*magic*/frame>1?1:0)) / framerate->n;
|
||||
|
||||
time->tv_sec = usec / 1000000;
|
||||
time->tv_usec = usec % 1000000;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -27,7 +27,8 @@
|
|||
#include <stddef.h>
|
||||
|
||||
/**
|
||||
* @file Intrusive cyclic double linked list
|
||||
* @file
|
||||
* Intrusive cyclic double linked list
|
||||
* There is only one node type which contains a forward and a backward pointer. In a empty initialized node,
|
||||
* this pointers point to the node itself. Note that these pointers can never ever become NULL.
|
||||
* This lists are used by using one node as 'root' node where its both pointers are the head/tail pointer to the actual list.
|
||||
|
|
@ -88,6 +89,7 @@ typedef llist * LList;
|
|||
typedef const llist * const_LList;
|
||||
typedef llist ** LList_ref;
|
||||
|
||||
|
||||
/**
|
||||
* Macro to instantiate a local llist.
|
||||
* @param name of the llist node
|
||||
|
|
@ -95,6 +97,14 @@ typedef llist ** LList_ref;
|
|||
#define LLIST_AUTO(name) llist name = {&name,&name}
|
||||
|
||||
|
||||
/*
|
||||
some macros for convenience
|
||||
*/
|
||||
#define llist_insert_head(list, element) llist_insert_next (list, element)
|
||||
#define llist_insert_tail(list, element) llist_insert_prev (list, element)
|
||||
#define llist_head llist_next
|
||||
#define llist_tail llist_prev
|
||||
|
||||
/**
|
||||
* cast back from a member of a structure to a pointer of the structure
|
||||
*/
|
||||
|
|
@ -129,6 +139,30 @@ typedef llist ** LList_ref;
|
|||
! llist_is_end (node, list); \
|
||||
llist_backward (&node))
|
||||
|
||||
|
||||
/**
|
||||
* Iterate forward over a range.
|
||||
* @param start first node to be interated
|
||||
* @param end node after the last node be iterated
|
||||
* @param node pointer to the iterated node
|
||||
*/
|
||||
#define LLIST_FORRANGE(start, end, node) \
|
||||
for (LList node = start; \
|
||||
node != end; \
|
||||
llist_forward (&node))
|
||||
|
||||
/**
|
||||
* Iterate backward over a range.
|
||||
* @param rstart first node to be interated
|
||||
* @param rend node before the last node be iterated
|
||||
* @param node pointer to the iterated node
|
||||
*/
|
||||
#define LLIST_FORRANGE_REV(rstart, rend, node) \
|
||||
for (LList node = rstart; \
|
||||
node != rend; \
|
||||
llist_backward (&node))
|
||||
|
||||
|
||||
/**
|
||||
* Consume a list from head.
|
||||
* The body of this statement should remove the head from the list, else it would be a infinite loop
|
||||
|
|
@ -290,7 +324,7 @@ LLIST_FUNC (LList llist_insert_next (LList self, LList next),
|
|||
/**
|
||||
* Insert a node before another.
|
||||
* @param self node before which we want to insert
|
||||
* @param prev node which shall be inserted nefore self. Could already linked to a list from where it will be removed.
|
||||
* @param prev node which shall be inserted before self. Could already linked to a list from where it will be removed.
|
||||
* @return self
|
||||
*/
|
||||
LLIST_FUNC (LList llist_insert_prev (LList self, LList prev),
|
||||
|
|
@ -314,10 +348,9 @@ LLIST_FUNC (LList llist_insertlist_next (LList self, LList next),
|
|||
if (!llist_is_empty (next))
|
||||
{
|
||||
self->next->prev = next->prev;
|
||||
self->next = next->next;
|
||||
|
||||
next->next->prev = self;
|
||||
next->prev->next = self->next;
|
||||
self->next = next->next;
|
||||
next->next->prev = self;
|
||||
|
||||
next->prev = next->next = next;
|
||||
}
|
||||
|
|
@ -335,10 +368,9 @@ LLIST_FUNC (LList llist_insertlist_prev (LList self, LList prev),
|
|||
if (!llist_is_empty (prev))
|
||||
{
|
||||
self->prev->next = prev->next;
|
||||
self->prev = prev->prev;
|
||||
|
||||
prev->prev->next = self;
|
||||
prev->next->prev = self->prev;
|
||||
self->prev = prev->prev;
|
||||
prev->prev->next = self;
|
||||
|
||||
prev->prev = prev->next = prev;
|
||||
}
|
||||
|
|
@ -494,20 +526,45 @@ LLIST_FUNC (LList llist_get_nth_stop (LList self, int n, const_LList stop),
|
|||
return self;
|
||||
);
|
||||
|
||||
/*
|
||||
some macros for convenience
|
||||
*/
|
||||
#define llist_insert_head(list, element) llist_insert_next (list, element)
|
||||
#define llist_insert_tail(list, element) llist_insert_prev (list, element)
|
||||
#define llist_head llist_next
|
||||
#define llist_tail llist_prev
|
||||
|
||||
/**
|
||||
* Sort a list.
|
||||
* @param self list to be sorted
|
||||
* @param cmp function takeing 2 LLists
|
||||
* simple recursive mergesort
|
||||
*/
|
||||
typedef int (*llist_cmpfn)(LList a, LList b);
|
||||
|
||||
LLIST_FUNC (LList llist_sort (LList self, llist_cmpfn cmp),
|
||||
llist left;
|
||||
llist right;
|
||||
llist_init (&left);
|
||||
llist_init (&right);
|
||||
unsigned n = 0;
|
||||
if (!llist_is_single (self))
|
||||
{
|
||||
LLIST_WHILE_HEAD (self, head)
|
||||
llist_insert_prev (++n & 1 ? &left : &right, head);
|
||||
|
||||
llist_sort (&left, cmp);
|
||||
llist_sort (&right, cmp);
|
||||
|
||||
while (!llist_is_empty (&left) && !llist_is_empty (&right))
|
||||
llist_insert_prev (self, cmp (left.next, right.next) < 0 ? left.next : right.next);
|
||||
|
||||
if (!llist_is_empty (&left))
|
||||
llist_insertlist_prev (self, &left);
|
||||
if (!llist_is_empty (&right))
|
||||
llist_insertlist_prev (self, &right);
|
||||
}
|
||||
return self;
|
||||
)
|
||||
|
||||
#endif /* LLIST_H */
|
||||
/*
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// End:
|
||||
// arch-tag: e8fe4a59-fd55-4c45-b860-5cd1e0771213
|
||||
// end_of_file
|
||||
// Local Variables:
|
||||
// mode: C
|
||||
// c-file-style: "gnu"
|
||||
// indent-tabs-mode: nil
|
||||
// End:
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -28,8 +28,14 @@
|
|||
|
||||
#include "lib/error.h"
|
||||
|
||||
|
||||
LUMIERA_ERROR_DECLARE (MUTEX_LOCK);
|
||||
LUMIERA_ERROR_DECLARE (MUTEX_UNLOCK);
|
||||
LUMIERA_ERROR_DECLARE (MUTEX_DESTROY);
|
||||
|
||||
/**
|
||||
* @file Shared declarations for all locking primitives.
|
||||
* @file
|
||||
* Shared declarations for all locking primitives.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
|||
58
src/lib/mrucache.c
Normal file
58
src/lib/mrucache.c
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
mrucache.h - most recent used cache
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "lib/mrucache.h"
|
||||
|
||||
|
||||
LumieraMruCache
|
||||
lumiera_mrucache_init (LumieraMruCache self, lumiera_cache_destructor_fn destructor_cb)
|
||||
{
|
||||
REQUIRE (self);
|
||||
llist_init (&self->cache_list);
|
||||
self->cached = 0;
|
||||
self->destructor_cb = destructor_cb;
|
||||
return self;
|
||||
}
|
||||
|
||||
LumieraMruCache
|
||||
lumiera_mrucache_destroy (LumieraMruCache self)
|
||||
{
|
||||
LLIST_WHILE_TAIL (&self->cache_list, node)
|
||||
{
|
||||
llist_unlink (node);
|
||||
if (self->destructor_cb)
|
||||
free (self->destructor_cb (node));
|
||||
else
|
||||
free (node);
|
||||
}
|
||||
self->cached = 0;
|
||||
return self;
|
||||
}
|
||||
|
||||
int
|
||||
lumiera_mrucache_age (LumieraMruCache self, int nelem)
|
||||
{
|
||||
REQUIRE (self);
|
||||
while (self->cached && nelem--)
|
||||
free (lumiera_mrucache_pop (self));
|
||||
|
||||
return nelem;
|
||||
}
|
||||
178
src/lib/mrucache.h
Normal file
178
src/lib/mrucache.h
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
/*
|
||||
mrucache.h - most recent used cache
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef LUMIERA_CACHE_H
|
||||
#define LUMIERA_CACHE_H
|
||||
|
||||
#include "lib/llist.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Most recent used cache
|
||||
* Elements (addressed by a LList node) are either checked in the cache and thereby subject of aging
|
||||
* or checked out under control of the user. Most operations require that the chache is locked. This locking
|
||||
* must be done from elsewhere.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback function used to destruct/cleanup aged elements.
|
||||
* shall clean the element sufficiently up to be ready for being freed or reused,
|
||||
* this callback function must be reentrant and prepared to be called twice.
|
||||
* @param node the llist node used to link cache elements (will be empty at call)
|
||||
* @return pointer to the begin of the element.
|
||||
*/
|
||||
typedef void* (*lumiera_cache_destructor_fn)(LList node);
|
||||
|
||||
struct lumiera_mrucache_struct
|
||||
{
|
||||
llist cache_list;
|
||||
size_t cached;
|
||||
lumiera_cache_destructor_fn destructor_cb;
|
||||
};
|
||||
typedef struct lumiera_mrucache_struct lumiera_mrucache;
|
||||
typedef lumiera_mrucache* LumieraMruCache;
|
||||
|
||||
/**
|
||||
* Initialize a cache.
|
||||
* @param self cache to be initialized
|
||||
* @param destructor_cb function for destructing a cache node, preparing for reuse.
|
||||
* @return self
|
||||
*/
|
||||
LumieraMruCache
|
||||
lumiera_mrucache_init (LumieraMruCache self, lumiera_cache_destructor_fn destructor_cb);
|
||||
|
||||
/**
|
||||
* Destroy a cache.
|
||||
* frees all checked in items.
|
||||
* @param self cache to be destroyed
|
||||
* @return self
|
||||
*/
|
||||
LumieraMruCache
|
||||
lumiera_mrucache_destroy (LumieraMruCache self);
|
||||
|
||||
|
||||
/**
|
||||
* Add an element to a mrucache.
|
||||
* When added the element is subject of aging and must not be accessed anymore.
|
||||
* To acces elements they have to be checked out again.
|
||||
* Checkin and checkout operations must be protected by a lock over the cache.
|
||||
* @param self cache where to checkin
|
||||
* @param node a llist member in the cached data which is used as queue in the cache
|
||||
*/
|
||||
static inline void
|
||||
lumiera_mrucache_checkin (LumieraMruCache self, LList node)
|
||||
{
|
||||
REQUIRE (self);
|
||||
REQUIRE (node && llist_is_empty (node));
|
||||
llist_insert_head (&self->cache_list, node);
|
||||
++self->cached;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Schedule an element for fast aging.
|
||||
* When an element is not longer needed it can be placed at the end of the chache
|
||||
* aging queue and thus become the first one to be reused when a new element is queried.
|
||||
* This can be done on a checked out element as well as on an element which is in the cache.
|
||||
* The cache must be locked for this operation.
|
||||
* @param self cache
|
||||
* @param node a llist member in the cached data which is used as queue in the cache
|
||||
*/
|
||||
static inline void
|
||||
lumiera_mrucache_drop (LumieraMruCache self, LList node)
|
||||
{
|
||||
REQUIRE (self);
|
||||
REQUIRE (node);
|
||||
|
||||
if (llist_is_empty (node))
|
||||
{
|
||||
/* was not in list, we need to count it */
|
||||
++self->cached;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* speedup loop warning :P, this check is costly */
|
||||
REQUIRE (llist_is_member (&self->cache_list, node), "node must be empty or member of cache");
|
||||
}
|
||||
llist_insert_tail (&self->cache_list, node);
|
||||
|
||||
if (self->destructor_cb)
|
||||
self->destructor_cb (node);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checkout an element from a cache.
|
||||
* A checked out element is not under cache control anymore until is gets checked in again.
|
||||
* The code which checked the element out takes ownership of the element.
|
||||
* The cache must be locked for this operation.
|
||||
* @param self cache
|
||||
* @param node a llist member in the cached data which is used as queue in the cache
|
||||
*/
|
||||
static inline void
|
||||
lumiera_mrucache_checkout (LumieraMruCache self, LList node)
|
||||
{
|
||||
REQUIRE (self);
|
||||
REQUIRE (node && llist_is_member (&self->cache_list, node)); /* speedup loop warning :P, this check is costly */
|
||||
llist_unlink (node);
|
||||
--self->cached;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy the oldest element from the cache and return it.
|
||||
* This function is used to get a new element by deleting the oldest least used one from the cache.
|
||||
* The cache must be locked for this operation.
|
||||
* @param self cache
|
||||
* @return pointer to the uninitialized memory ready for being reused
|
||||
*/
|
||||
static inline void*
|
||||
lumiera_mrucache_pop (LumieraMruCache self)
|
||||
{
|
||||
REQUIRE (self);
|
||||
if (llist_is_empty (&self->cache_list))
|
||||
return NULL;
|
||||
|
||||
LList node = llist_tail (&self->cache_list);
|
||||
llist_unlink (node);
|
||||
--self->cached;
|
||||
|
||||
if (self->destructor_cb)
|
||||
return self->destructor_cb (node);
|
||||
else
|
||||
return node;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroy and free the nelem oldest elements.
|
||||
* Used to free up resources and memory.
|
||||
* @param self cache where to free elements.
|
||||
* @param nelem number of elements wished to be freed
|
||||
* @return nelem-(numer of elements which got freed), that is 0 if all requested elements got freed
|
||||
*/
|
||||
int
|
||||
lumiera_mrucache_age (LumieraMruCache self, int nelem);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -22,9 +22,14 @@
|
|||
#include "lib/mutex.h"
|
||||
|
||||
/**
|
||||
* @file Mutual exclusion locking.
|
||||
* @file
|
||||
* Mutual exclusion locking.
|
||||
*/
|
||||
|
||||
LUMIERA_ERROR_DEFINE (MUTEX_LOCK, "Mutex locking failed");
|
||||
LUMIERA_ERROR_DEFINE (MUTEX_UNLOCK, "Mutex unlocking failed");
|
||||
LUMIERA_ERROR_DEFINE (MUTEX_DESTROY, "Mutex destroy failed");
|
||||
|
||||
|
||||
/**
|
||||
* Initialize a mutex variable
|
||||
|
|
@ -52,7 +57,7 @@ lumiera_mutex_destroy (LumieraMutex self)
|
|||
if (self)
|
||||
{
|
||||
if (pthread_mutex_destroy (&self->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_DESTROY);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,8 +25,18 @@
|
|||
#include "lib/locking.h"
|
||||
|
||||
/**
|
||||
* @file Mutual exclusion locking, header.
|
||||
* @file
|
||||
* Mutual exclusion locking, header.
|
||||
*/
|
||||
#define LUMIERA_MUTEX_SECTION(flag, handle, mutex) \
|
||||
RESOURCE_HANDLE (rh_##__LINE__##_); \
|
||||
lumiera_mutexacquirer lock_##__LINE__##_; \
|
||||
RESOURCE_ENTER (flag, handle, "acquire mutex", &lock_##__LINE__##_, \
|
||||
NOBUG_RESOURCE_EXCLUSIVE, rh_##__LINE__##_); \
|
||||
for (lumiera_mutexacquirer_init_mutex (&lock_##__LINE__##_, mutex, LUMIERA_LOCKED); \
|
||||
lock_##__LINE__##_.state == LUMIERA_LOCKED; \
|
||||
lumiera_mutexacquirer_unlock (&lock_##__LINE__##_), \
|
||||
({RESOURCE_LEAVE(flag, rh_##__LINE__##_);}))
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -106,7 +116,7 @@ lumiera_mutexacquirer_init_mutex (LumieraMutexacquirer self, LumieraMutex mutex,
|
|||
self->state = state;
|
||||
if (state == LUMIERA_LOCKED)
|
||||
if (pthread_mutex_lock (&mutex->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_LOCK);
|
||||
|
||||
return self;
|
||||
}
|
||||
|
|
@ -124,7 +134,7 @@ lumiera_mutexacquirer_lock (LumieraMutexacquirer self)
|
|||
REQUIRE (self->state == LUMIERA_UNLOCKED, "mutex already locked");
|
||||
|
||||
if (pthread_mutex_lock (&self->mutex->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_LOCK);
|
||||
|
||||
self->state = LUMIERA_LOCKED;
|
||||
}
|
||||
|
|
@ -164,7 +174,7 @@ lumiera_mutexacquirer_try_mutex (LumieraMutexacquirer self, LumieraMutex mutex)
|
|||
case EBUSY:
|
||||
return LUMIERA_UNLOCKED;
|
||||
default:
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_LOCK);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -180,7 +190,7 @@ lumiera_mutexacquirer_unlock (LumieraMutexacquirer self)
|
|||
REQUIRE (self);
|
||||
REQUIRE (self->state == LUMIERA_LOCKED, "mutex was not locked");
|
||||
if (pthread_mutex_unlock (&self->mutex->mutex))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (MUTEX_UNLOCK);
|
||||
self->state = LUMIERA_UNLOCKED;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,11 +25,14 @@
|
|||
#include <dlfcn.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "plugin.h"
|
||||
#include "safeclib.h"
|
||||
|
||||
/**
|
||||
* @file Plugin loader.
|
||||
* @file
|
||||
* Plugin loader.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -159,8 +162,8 @@ lumiera_plugin_lookup (struct lumiera_plugin* self, const char* path)
|
|||
{
|
||||
/* got it */
|
||||
TRACE (lumiera_plugin, "found %s", pathname);
|
||||
self->pathname = strdup (pathname);
|
||||
if (!self->pathname) LUMIERA_DIE;
|
||||
self->pathname = lumiera_strndup (pathname, PATH_MAX);
|
||||
|
||||
self->type = lumiera_plugin_extensions[i].type;
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -195,21 +198,20 @@ lumiera_interface_open (const char* name, const char* interface, size_t min_revi
|
|||
plugin.name = name; /* for searching */
|
||||
|
||||
found = tsearch (&plugin, &lumiera_plugin_registry, lumiera_plugin_name_cmp);
|
||||
if (!found) LUMIERA_DIE;
|
||||
if (!found)
|
||||
LUMIERA_DIE (NO_MEMORY);
|
||||
|
||||
if (*found == &plugin)
|
||||
{
|
||||
NOTICE (lumiera_plugin, "new plugin");
|
||||
|
||||
/* now really create new item */
|
||||
*found = malloc (sizeof (struct lumiera_plugin));
|
||||
if (!*found) LUMIERA_DIE;
|
||||
*found = lumiera_malloc (sizeof (struct lumiera_plugin));
|
||||
|
||||
if (name) /* NULL is main app, no lookup needed */
|
||||
{
|
||||
/*lookup for $LUMIERA_PLUGIN_PATH*/
|
||||
(*found)->name = strdup (name);
|
||||
if (!(*found)->name) LUMIERA_DIE;
|
||||
(*found)->name = lumiera_strndup (name, PATH_MAX);
|
||||
|
||||
if (!!lumiera_plugin_lookup (*found, getenv("LUMIERA_PLUGIN_PATH"))
|
||||
#ifdef LUMIERA_PLUGIN_PATH
|
||||
|
|
|
|||
|
|
@ -33,7 +33,8 @@ extern "C" {
|
|||
#include "error.h"
|
||||
|
||||
/**
|
||||
* @file Plugin loader, header.
|
||||
* @file
|
||||
* Plugin loader, header.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -19,9 +19,11 @@
|
|||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "lib/references.h"
|
||||
#include "lib/safeclib.h"
|
||||
|
||||
/**
|
||||
* @file Strong and Weak references
|
||||
* @file
|
||||
* Strong and Weak references
|
||||
* Strong references keep some object alive while they existing
|
||||
* Weak references become invalidated when the referenced object gets destroyed
|
||||
*
|
||||
|
|
@ -43,8 +45,7 @@
|
|||
LumieraReference
|
||||
lumiera_reference_strong_init_once (LumieraReference self, void* obj, void (*dtor)(void*))
|
||||
{
|
||||
LumieraReftarget target = malloc (sizeof(lumiera_reftarget));
|
||||
if (!target) LUMIERA_DIE;
|
||||
LumieraReftarget target = lumiera_malloc (sizeof(lumiera_reftarget));
|
||||
|
||||
target->object = obj;
|
||||
target->dtor = dtor;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,8 @@
|
|||
#include <nobug.h>
|
||||
|
||||
/**
|
||||
* @file Strong and Weak references, header.
|
||||
* @file
|
||||
* Strong and Weak references, header.
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -18,16 +18,19 @@
|
|||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <errno.h>
|
||||
#include "lib/rwlock.h"
|
||||
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_AGAIN, "maximum number of readlocks exceed");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_DEADLOCK, "deadlock detected");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_DESTROY, "destroy rwlock");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_UNLOCK, "unlock");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_RLOCK, "rlock");
|
||||
LUMIERA_ERROR_DEFINE(RWLOCK_WLOCK, "wlock");
|
||||
|
||||
/**
|
||||
* @file Read/write locks.
|
||||
* @file
|
||||
* Read/write locks.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -57,7 +60,7 @@ lumiera_rwlock_destroy (LumieraRWLock self)
|
|||
if (self)
|
||||
{
|
||||
if (pthread_rwlock_destroy (&self->rwlock))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (RWLOCK_DESTROY);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
@ -95,7 +98,7 @@ lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, e
|
|||
lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK);
|
||||
return NULL;
|
||||
default:
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (RWLOCK_RLOCK);
|
||||
}
|
||||
case LUMIERA_WRLOCKED:
|
||||
switch (pthread_rwlock_wrlock (&rwlock->rwlock))
|
||||
|
|
@ -106,7 +109,7 @@ lumiera_rwlockacquirer_init (LumieraRWLockacquirer self, LumieraRWLock rwlock, e
|
|||
lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK);
|
||||
return NULL;
|
||||
default:
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (RWLOCK_WLOCK);
|
||||
}
|
||||
default:
|
||||
break;
|
||||
|
|
@ -138,7 +141,7 @@ lumiera_rwlockacquirer_rdlock (LumieraRWLockacquirer self)
|
|||
lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK);
|
||||
return NULL;
|
||||
default:
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (RWLOCK_RLOCK);
|
||||
}
|
||||
|
||||
self->state = LUMIERA_RDLOCKED;
|
||||
|
|
@ -166,7 +169,7 @@ lumiera_rwlockacquirer_wrlock (LumieraRWLockacquirer self)
|
|||
lumiera_error_set (LUMIERA_ERROR_RWLOCK_DEADLOCK);
|
||||
return NULL;
|
||||
default:
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (RWLOCK_WLOCK);
|
||||
}
|
||||
|
||||
self->state = LUMIERA_WRLOCKED;
|
||||
|
|
|
|||
|
|
@ -33,9 +33,14 @@
|
|||
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_AGAIN);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_DEADLOCK);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_DESTROY);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_UNLOCK);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_RLOCK);
|
||||
LUMIERA_ERROR_DECLARE(RWLOCK_WLOCK);
|
||||
|
||||
/**
|
||||
* @file Read/write locks, header.
|
||||
* @file
|
||||
* Read/write locks, header.
|
||||
*/
|
||||
|
||||
|
||||
|
|
@ -106,7 +111,7 @@ lumiera_rwlockacquirer_unlock (LumieraRWLockacquirer self)
|
|||
REQUIRE (self);
|
||||
REQUIRE (self->state != LUMIERA_UNLOCKED, "rwlock was not locked");
|
||||
if (pthread_rwlock_unlock (&self->rwlock->rwlock))
|
||||
LUMIERA_DIE;
|
||||
LUMIERA_DIE (RWLOCK_UNLOCK);
|
||||
self->state = LUMIERA_UNLOCKED;
|
||||
}
|
||||
|
||||
|
|
|
|||
225
src/lib/safeclib.c
Normal file
225
src/lib/safeclib.c
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/*
|
||||
safe_clib.c - Portable and safe wrapers around some clib functions and some tools
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "error.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Portable and safe wrapers around some clib functions and some tools
|
||||
*/
|
||||
|
||||
LUMIERA_ERROR_DEFINE (NO_MEMORY, "Out of Memory!");
|
||||
|
||||
/**
|
||||
* Allocate memory.
|
||||
* always succeeds or dies
|
||||
* @param size memory to be allocated
|
||||
* @return pointer to the allocated memory
|
||||
*/
|
||||
void*
|
||||
lumiera_malloc (size_t size)
|
||||
{
|
||||
void* o = size ? malloc (size) : NULL;
|
||||
if (!o)
|
||||
LUMIERA_DIE (NO_MEMORY);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Allocate cleared memory for an array.
|
||||
* always succeeds or dies
|
||||
* @param n number of elements
|
||||
* @param size memory to be allocated
|
||||
* @return pointer to the allocated memory
|
||||
*/
|
||||
void*
|
||||
lumiera_calloc (size_t n, size_t size)
|
||||
{
|
||||
void* o = (n&&size)? calloc (n, size) : NULL;
|
||||
if (!o)
|
||||
LUMIERA_DIE (NO_MEMORY);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Duplicate a C string.
|
||||
* always succeeds or dies
|
||||
* @param str string to be copied
|
||||
* @param len maximal length to be copied
|
||||
* @return pointer to the new string, "" if NULL was passed as str
|
||||
*/
|
||||
char*
|
||||
lumiera_strndup (const char* str, size_t len)
|
||||
{
|
||||
char* o;
|
||||
if (str)
|
||||
o = strndup (str, len);
|
||||
else
|
||||
o = strdup ("");
|
||||
|
||||
if (!o)
|
||||
LUMIERA_DIE (NO_MEMORY);
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Compare two C strings.
|
||||
* Handles NULL pointers as "", shortcut for same addresses
|
||||
* @param a first string for comparsion
|
||||
* @param b second string for comparsion
|
||||
* @param len maximal length for the comparsion
|
||||
* @return 0 if the strings are identical, -1 if smaller 1 if bigger.
|
||||
*/
|
||||
int
|
||||
lumiera_strncmp (const char* a, const char* b, size_t len)
|
||||
{
|
||||
return a == b ? 0 : strncmp (a?a:"", b?b:"", len);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* check 2 strings for identity.
|
||||
* @param a first string for comparsion
|
||||
* @param b second string for comparsion
|
||||
* @return 1 when the strings are the the same, 0 if not.
|
||||
*/
|
||||
int
|
||||
lumiera_streq (const char* a, const char* b)
|
||||
{
|
||||
return !lumiera_strncmp (a, b, SIZE_MAX);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Round robin temporary buffers.
|
||||
* This provides 64 buffers per thread which are recycled with each use.
|
||||
* The idea here is to have fast buffers for temporal data without need for explicit heap management.
|
||||
*/
|
||||
struct lumiera_tmpbuf_struct
|
||||
{
|
||||
void* buffers[64];
|
||||
size_t sizes[64];
|
||||
unsigned idx;
|
||||
};
|
||||
|
||||
static pthread_once_t lumiera_tmpbuf_tls_once = PTHREAD_ONCE_INIT;
|
||||
static pthread_key_t lumiera_tmpbuf_tls_key;
|
||||
|
||||
void
|
||||
lumiera_tmpbuf_freeall (void);
|
||||
|
||||
static void
|
||||
lumiera_tmpbuf_destroy (void* buf)
|
||||
{
|
||||
lumiera_tmpbuf_freeall ();
|
||||
}
|
||||
|
||||
static void
|
||||
lumiera_tmpbuf_init (void)
|
||||
{
|
||||
pthread_key_create (&lumiera_tmpbuf_tls_key, lumiera_tmpbuf_destroy);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* free all buffers associated with this thread.
|
||||
* This function is called automatically, usually one doesnt need to call it.
|
||||
*/
|
||||
void
|
||||
lumiera_tmpbuf_freeall (void)
|
||||
{
|
||||
pthread_once (&lumiera_tmpbuf_tls_once, lumiera_tmpbuf_init);
|
||||
struct lumiera_tmpbuf_struct* buf = pthread_getspecific (lumiera_tmpbuf_tls_key);
|
||||
if (buf)
|
||||
{
|
||||
pthread_setspecific (lumiera_tmpbuf_tls_key, NULL);
|
||||
for (int idx = 0; idx < 64; ++idx)
|
||||
free (buf->buffers[idx]);
|
||||
free (buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Query a thread local buffer.
|
||||
* @param size minimal needed size for the buffer
|
||||
* @return the buffer
|
||||
*/
|
||||
void*
|
||||
lumiera_tmpbuf_provide (size_t size)
|
||||
{
|
||||
pthread_once (&lumiera_tmpbuf_tls_once, lumiera_tmpbuf_init);
|
||||
struct lumiera_tmpbuf_struct* buf = pthread_getspecific (lumiera_tmpbuf_tls_key);
|
||||
if (!buf)
|
||||
pthread_setspecific (lumiera_tmpbuf_tls_key,
|
||||
buf = lumiera_calloc (1, sizeof (struct lumiera_tmpbuf_struct)));
|
||||
|
||||
buf->idx = (buf->idx + 1) & 0x3f;
|
||||
|
||||
if (buf->sizes[buf->idx] < size || buf->sizes[buf->idx] > 8*size)
|
||||
{
|
||||
free (buf->buffers[buf->idx]);
|
||||
buf->sizes[buf->idx] = (size+4*sizeof(long)) & ~(4*sizeof(long)-1);
|
||||
buf->buffers[buf->idx] = lumiera_malloc (buf->sizes[buf->idx]);
|
||||
}
|
||||
return buf->buffers[buf->idx];
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
lumiera_tmpbuf_strndup (const char* src, size_t size)
|
||||
{
|
||||
size_t len = strlen (src);
|
||||
len = len > size ? size : len;
|
||||
|
||||
char* buf = lumiera_tmpbuf_provide (len + 1);
|
||||
strncpy (buf, src, len);
|
||||
buf[len] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
char*
|
||||
lumiera_tmpbuf_snprintf (size_t size, const char* fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start (args, fmt);
|
||||
size_t len = vsnprintf (NULL, 0, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
len = len > size ? size : len;
|
||||
char* buf = lumiera_tmpbuf_provide (len+1);
|
||||
va_start (args, fmt);
|
||||
vsnprintf (buf, len+1, fmt, args);
|
||||
va_end (args);
|
||||
|
||||
return buf;
|
||||
}
|
||||
125
src/lib/safeclib.h
Normal file
125
src/lib/safeclib.h
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
safe_clib.h - Portable and safe wrapers around some clib functions and some tools
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "error.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Portable and safe wrapers around some clib functions and some tools
|
||||
*/
|
||||
LUMIERA_ERROR_DECLARE(NO_MEMORY);
|
||||
|
||||
/**
|
||||
* Allocate memory.
|
||||
* always succeeds or dies
|
||||
* @param size memory to be allocated
|
||||
* @return pointer to the allocated memory
|
||||
*/
|
||||
void*
|
||||
lumiera_malloc (size_t sz);
|
||||
|
||||
|
||||
/**
|
||||
* Allocate cleared memory for an array.
|
||||
* always succeeds or dies
|
||||
* @param n number of elements
|
||||
* @param size memory to be allocated
|
||||
* @return pointer to the allocated memory
|
||||
*/
|
||||
void*
|
||||
lumiera_calloc (size_t n, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* Duplicate a C string.
|
||||
* always succeeds or dies
|
||||
* @param str string to be copied
|
||||
* @param len maximal length to be copied
|
||||
* @return pointer to the new string, "" if NULL was passed as str
|
||||
*/
|
||||
char*
|
||||
lumiera_strndup (const char* str, size_t len);
|
||||
|
||||
|
||||
/**
|
||||
* Compare two C strings.
|
||||
* Handles NULL pointers as "", shortcut for same addresses
|
||||
* @param a first string for comparsion
|
||||
* @param b second string for comparsion
|
||||
* @param len maximal length for the comparsion
|
||||
* @return 0 if the strings are identical, -1 if smaller 1 if bigger.
|
||||
*/
|
||||
int
|
||||
lumiera_strncmp (const char* a, const char* b, size_t len);
|
||||
|
||||
|
||||
/**
|
||||
* check 2 strings for identity.
|
||||
* @param a first string for comparsion
|
||||
* @param b second string for comparsion
|
||||
* @return 1 when the strings are the the same, 0 if not.
|
||||
*/
|
||||
int
|
||||
lumiera_streq (const char* a, const char* b);
|
||||
|
||||
|
||||
/**
|
||||
* Round robin temporary buffers.
|
||||
* This provides 64 buffers per thread which are recycled with each use.
|
||||
* The idea here is to have fast buffers for temporal data without need for explicit heap management.
|
||||
*/
|
||||
|
||||
/**
|
||||
* free all buffers associated with this thread.
|
||||
* This function is called automatically, usually one doesnt need to call it.
|
||||
*/
|
||||
void
|
||||
lumiera_tmpbuf_freeall (void);
|
||||
|
||||
/**
|
||||
* Query a thread local tmpbuf.
|
||||
* @param size minimal needed size for the tmpbuf
|
||||
* @return the tmpbuf
|
||||
*/
|
||||
void*
|
||||
lumiera_tmpbuf_provide (size_t size);
|
||||
|
||||
/**
|
||||
* Duplicate string to a tmpbuf.
|
||||
* @param src string to be duplicated
|
||||
* @param size maximal length to be copied
|
||||
* @return temporary buffer containing a copy of the string
|
||||
*/
|
||||
char*
|
||||
lumiera_tmpbuf_strndup (const char* src, size_t size);
|
||||
|
||||
/**
|
||||
* Construct a string in a tmpbuf.
|
||||
* @param size maximal length for the string
|
||||
* @param fmt printf like formatstring
|
||||
* @param ... parameters
|
||||
* @return temporary buffer containing the constructed of the string
|
||||
*/
|
||||
char*
|
||||
lumiera_tmpbuf_snprintf (size_t size, const char* fmt, ...);
|
||||
|
||||
95
src/lib/uuid.c
Normal file
95
src/lib/uuid.c
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
uuid - Universal unique identifiers
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include "lib/uuid.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
void
|
||||
lumiera_uuid_set_ptr (lumiera_uuid* uuid, void* ptr)
|
||||
{
|
||||
memset (uuid, 0, 16);
|
||||
*(void**)uuid = ptr;
|
||||
}
|
||||
|
||||
|
||||
void*
|
||||
lumiera_uuid_ptr_get (lumiera_uuid* uuid)
|
||||
{
|
||||
return *(void**)uuid;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_uuid_gen (lumiera_uuid* uuid)
|
||||
{
|
||||
static int fd = -2;
|
||||
if (!uuid)
|
||||
return;
|
||||
|
||||
if (fd == -2)
|
||||
{
|
||||
fd = open ("/dev/urandom", O_RDONLY);
|
||||
if (fd == -1)
|
||||
fd = open ("/dev/random", O_RDONLY);
|
||||
if (fd >= 0)
|
||||
fcntl (fd, F_SETFD, FD_CLOEXEC);
|
||||
else
|
||||
srand (getpid () + time (NULL));
|
||||
}
|
||||
if (fd < 0)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
((unsigned char*)uuid)[i] = (unsigned char)(rand()>>7);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (read (fd, uuid, 16) < 0)
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_uuid_copy (lumiera_uuid* dest, lumiera_uuid* src)
|
||||
{
|
||||
memcpy (dest, src, 16);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lumiera_uuid_eq (lumiera_uuid* uuida, lumiera_uuid* uuidb)
|
||||
{
|
||||
return !memcmp (uuida, uuidb, 16);
|
||||
}
|
||||
|
||||
size_t
|
||||
lumiera_uuid_hash (lumiera_uuid* uuid)
|
||||
{
|
||||
return *(size_t*)uuid;
|
||||
}
|
||||
|
||||
|
||||
67
src/lib/uuid.h
Normal file
67
src/lib/uuid.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
uuid - Universal unique identifiers
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef LUMIERA_UUID_H
|
||||
#define LUMIERA_UUID_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
typedef unsigned char lumiera_uuid[16];
|
||||
|
||||
/**
|
||||
* Retrieve a generic pointer stored in a uuid
|
||||
*/
|
||||
void*
|
||||
lumiera_uuid_ptr_get (lumiera_uuid* uuid);
|
||||
|
||||
/**
|
||||
* Generate a new uuid
|
||||
*/
|
||||
void
|
||||
lumiera_uuid_gen (lumiera_uuid* uuid);
|
||||
|
||||
/**
|
||||
* Store a generic pointer in a uuid
|
||||
*/
|
||||
void
|
||||
lumiera_uuid_set_ptr (lumiera_uuid* uuid, void* ptr);
|
||||
|
||||
|
||||
/**
|
||||
* Copy an uuid
|
||||
*/
|
||||
void
|
||||
lumiera_uuid_copy (lumiera_uuid* dest, lumiera_uuid* src);
|
||||
|
||||
|
||||
/**
|
||||
* Test 2 uuid's for equality
|
||||
*/
|
||||
int
|
||||
lumiera_uuid_eq (lumiera_uuid* uuida, lumiera_uuid* uuidb);
|
||||
|
||||
|
||||
/**
|
||||
* Generate a hashsum over an uuid
|
||||
*/
|
||||
size_t
|
||||
lumiera_uuid_hash (lumiera_uuid* uuid);
|
||||
|
||||
#endif
|
||||
251
src/proc/Makefile.am
Normal file
251
src/proc/Makefile.am
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
# Copyright (C) Lumiera.org
|
||||
# 2008, Christian Thaeter <ct@pipapo.org>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
|
||||
# TODO use -Wextra -Werror
|
||||
|
||||
liblumiproc_a_srcdir = $(top_srcdir)/src/proc
|
||||
noinst_LIBRARIES += liblumiproc.a
|
||||
|
||||
liblumiproc_a_CXXFLAGS = $(CXXFLAGS) -Wall
|
||||
liblumiproc_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumiproc_a_SOURCES = \
|
||||
$(liblumiproc_a_srcdir)/controllerfacade.cpp \
|
||||
$(liblumiproc_a_srcdir)/frame.cpp \
|
||||
$(liblumiproc_a_srcdir)/stateproxy.cpp \
|
||||
$(liblumiproc_a_srcdir)/asset.cpp \
|
||||
$(liblumiproc_a_srcdir)/assetmanager.cpp \
|
||||
$(liblumiproc_a_srcdir)/nobugcfg.cpp
|
||||
|
||||
|
||||
|
||||
liblumiprocasset_a_srcdir = $(top_srcdir)/src/proc/asset
|
||||
noinst_LIBRARIES += liblumiprocasset.a
|
||||
|
||||
liblumiprocasset_a_CXXFLAGS = $(CXXFLAGS) -Wall
|
||||
liblumiprocasset_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumiprocasset_a_SOURCES = \
|
||||
$(liblumiprocasset_a_srcdir)/codec.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/compoundmedia.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/dataset.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/effect.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/preview.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/unknown.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/clip.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/meta.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/category.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/media.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/pipe.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/proc.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/procpatt.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/struct.cpp \
|
||||
$(liblumiprocasset_a_srcdir)/track.cpp
|
||||
|
||||
|
||||
|
||||
liblumiprocengine_a_srcdir = $(top_srcdir)/src/proc/engine
|
||||
noinst_LIBRARIES += liblumiprocengine.a
|
||||
|
||||
liblumiprocengine_a_CXXFLAGS = $(CXXFLAGS) -Wall
|
||||
liblumiprocengine_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumiprocengine_a_SOURCES = \
|
||||
$(liblumiprocengine_a_srcdir)/aframe.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/arender.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/codecadapter.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/exitnode.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/glbuf.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/glpipe.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/glrender.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/hub.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/link.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/mask.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/pluginadapter.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/processor.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/procnode.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/projector.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/renderengine.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/source.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/trafo.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/vframe.cpp \
|
||||
$(liblumiprocengine_a_srcdir)/vrender.cpp
|
||||
|
||||
|
||||
|
||||
liblumiprocmobject_a_srcdir = $(top_srcdir)/src/proc/mobject
|
||||
noinst_LIBRARIES += liblumiprocmobject.a
|
||||
|
||||
liblumiprocmobject_a_CXXFLAGS = $(CXXFLAGS) -Wall
|
||||
liblumiprocmobject_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumiprocmobject_a_SOURCES = \
|
||||
$(liblumiprocmobject_a_srcdir)/builderfacade.cpp \
|
||||
$(liblumiprocmobject_a_srcdir)/interpolator.cpp \
|
||||
$(liblumiprocmobject_a_srcdir)/mobject.cpp \
|
||||
$(liblumiprocmobject_a_srcdir)/parameter.cpp \
|
||||
$(liblumiprocmobject_a_srcdir)/paramprovider.cpp \
|
||||
$(liblumiprocmobject_a_srcdir)/placement.cpp
|
||||
|
||||
|
||||
|
||||
liblumiprocmobjectbuilder_a_srcdir = $(top_srcdir)/src/proc/mobject/builder
|
||||
noinst_LIBRARIES += liblumiprocmobjectbuilder.a
|
||||
|
||||
liblumiprocmobjectbuilder_a_CXXFLAGS = $(CXXFLAGS) -Wall
|
||||
liblumiprocmobjectbuilder_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumiprocmobjectbuilder_a_SOURCES = \
|
||||
$(liblumiprocmobjectbuilder_a_srcdir)/assembler.cpp \
|
||||
$(liblumiprocmobjectbuilder_a_srcdir)/conmanager.cpp \
|
||||
$(liblumiprocmobjectbuilder_a_srcdir)/nodecreatertool.cpp \
|
||||
$(liblumiprocmobjectbuilder_a_srcdir)/segmentationtool.cpp \
|
||||
$(liblumiprocmobjectbuilder_a_srcdir)/toolfactory.cpp
|
||||
|
||||
|
||||
liblumiprocmobjectcontroller_a_srcdir = $(top_srcdir)/src/proc/mobject/controller
|
||||
noinst_LIBRARIES += liblumiprocmobjectcontroller.a
|
||||
|
||||
liblumiprocmobjectcontroller_a_CXXFLAGS = $(CXXFLAGS) -Wall
|
||||
liblumiprocmobjectcontroller_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumiprocmobjectcontroller_a_SOURCES = \
|
||||
$(liblumiprocmobjectcontroller_a_srcdir)/pathmanager.cpp \
|
||||
$(liblumiprocmobjectcontroller_a_srcdir)/renderstate.cpp
|
||||
|
||||
|
||||
liblumiprocmobjectsession_a_srcdir = $(top_srcdir)/src/proc/mobject/session
|
||||
noinst_LIBRARIES += liblumiprocmobjectsession.a
|
||||
|
||||
liblumiprocmobjectsession_a_CXXFLAGS = $(CXXFLAGS) -Wall
|
||||
liblumiprocmobjectsession_a_CPPFLAGS = -I$(top_srcdir)/src/
|
||||
|
||||
liblumiprocmobjectsession_a_SOURCES = \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/abstractmo.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/allocation.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/auto.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/compoundclip.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/effect.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/fixedlocation.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/label.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/meta.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/relativelocation.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/segment.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/simpleclip.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/plug.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/sessionimpl.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/sessmanagerimpl.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/edl.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/session.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/track.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/clip.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/constraint.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/defsmanager.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/fixture.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/locatingpin.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/mobjectfactory.cpp \
|
||||
$(liblumiprocmobjectsession_a_srcdir)/wish.cpp
|
||||
|
||||
|
||||
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(liblumiproc_a_srcdir)/asset/category.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/clip.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/codec.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/compoundmedia.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/dataset.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/effect.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/preview.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/db.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/buildinstruct.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/media.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/meta.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/pipe.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/proc.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/procpatt.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/struct.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/structfactoryimpl.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/track.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset/unknown.hpp \
|
||||
$(liblumiproc_a_srcdir)/controllerfacade.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/aframe.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/arender.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/codecadapter.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/exitnode.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/glbuf.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/glpipe.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/glrender.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/hub.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/link.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/mask.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/pluginadapter.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/procnode.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/projector.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/renderengine.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/source.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/trafo.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/vframe.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/vrender.hpp \
|
||||
$(liblumiproc_a_srcdir)/engine/processor.hpp \
|
||||
$(liblumiproc_a_srcdir)/frame.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/builder/assembler.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/builder/buildertool.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/builder/conmanager.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/builder/nodecreatertool.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/builder/segmentationtool.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/builder/toolfactory.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/builderfacade.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/controller/pathmanager.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/controller/renderstate.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/interpolator.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/parameter.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/paramprovider.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/abstractmo.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/allocation.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/auto.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/compoundclip.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/effect.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/fixedlocation.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/label.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/meta.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/relativelocation.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/simpleclip.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/mobjectfactory.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/segment.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/track.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/wish.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/clip.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/constraint.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/defsmanager.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/edl.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/fixture.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/locatingpin.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/plug.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/sessionimpl.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session/defsregistry.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/explicitplacement.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/mobject.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/placement.hpp \
|
||||
$(liblumiproc_a_srcdir)/mobject/session.hpp \
|
||||
$(liblumiproc_a_srcdir)/stateproxy.hpp \
|
||||
$(liblumiproc_a_srcdir)/asset.hpp \
|
||||
$(liblumiproc_a_srcdir)/assetmanager.hpp \
|
||||
$(liblumiproc_a_srcdir)/lumiera.hpp \
|
||||
$(liblumiproc_a_srcdir)/nobugcfg.hpp
|
||||
|
||||
28
tests/15safeclib.tests
Normal file
28
tests/15safeclib.tests
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
TESTING "Safe clib and tools" ./test-safeclib
|
||||
|
||||
TEST "Allocating 0 bytes" allocation0 <<END
|
||||
return: 134
|
||||
END
|
||||
|
||||
TEST "Allocating some memory" allocation1024 <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
TEST "Allocation error" allocationtoobig <<END
|
||||
return: 134
|
||||
END
|
||||
|
||||
|
||||
TEST "string equal check" streq <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
TEST "temporary buffers" tmpbuf <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
|
||||
|
||||
15
tests/15uuid.tests
Normal file
15
tests/15uuid.tests
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
TESTING "UUID's" ./test-uuid
|
||||
|
||||
TEST "uuid generate" uuidgen_2 <<END
|
||||
out: 0
|
||||
END
|
||||
|
||||
TEST "uuid copy" uuidgen_copy <<END
|
||||
out: 1
|
||||
END
|
||||
|
||||
TEST "storing pointers" ptrs <<END
|
||||
out: 1
|
||||
END
|
||||
|
||||
|
||||
26
tests/20filedescriptor.tests
Normal file
26
tests/20filedescriptor.tests
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
TESTING "Filedescriptor management" ./test-filedescriptors
|
||||
|
||||
echo testdata > ,tmp_testfile
|
||||
|
||||
TEST "acquire existing file" acquire_existing <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
TEST "acquire existing file twice" acquire_existing_again <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
rm ,tmp_testfile
|
||||
|
||||
TEST "acquire file, creating it" acquire_create <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
rm ,tmp_testfile
|
||||
|
||||
TEST "acquire file, creating it, nested dir" acquire_create_dir <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
rm ,tmp_testdir -r
|
||||
13
tests/20filehandle.tests
Normal file
13
tests/20filehandle.tests
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
TESTING "Filehandle management" ./test-filehandles
|
||||
|
||||
|
||||
TEST "basic filehandle usage" basic <<END
|
||||
return: 0
|
||||
END
|
||||
|
||||
rm -rf ,tmpdir
|
||||
|
||||
TEST "using many filehandles" more <<END
|
||||
return: 0
|
||||
END
|
||||
|
|
@ -62,7 +62,7 @@ out: caught error::Logic: LUMIERA_ERROR_FATAL:floundered (test-2).
|
|||
out: caught error::Invalid: LUMIERA_ERROR_INVALID:invalid input or parameters (test-3).
|
||||
out: caught lumiera::Error: LUMIERA_ERROR_EXTERNAL:failure in external service (test-4).
|
||||
out: caught std::runtime_error: test-5
|
||||
out: caught std::exception: St9exception
|
||||
out: caught std::exception: std::exception
|
||||
out: intermediate handler caught: LUMIERA_ERROR_EXTERNAL:failure in external service (test-7).....will rethrow as error::State
|
||||
out: caught lumiera::Error: LUMIERA_ERROR_STATE:unforseen state -- caused by: LUMIERA_ERROR_EXTERNAL:failure in external service (test-7).
|
||||
out: intermediate handler caught: LUMIERA_ERROR_EXTERNAL:failure in external service (test-8).....will rethrow as error::State
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
# Copyright (C) Lumiera.org
|
||||
# 2007, Christian Thaeter <ct@pipapo.org>
|
||||
# 2007-2008, Christian Thaeter <ct@pipapo.org>
|
||||
# Hermann Vosseler <Ichthyostega@web.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
|
|
@ -36,14 +36,29 @@ test_llist_SOURCES = $(tests_srcdir)/library/test-llist.c
|
|||
test_llist_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
test_llist_LDADD = liblumi.a -lnobugmt -lpthread -ldl -lm
|
||||
|
||||
check_PROGRAMS += test-safeclib
|
||||
test_safeclib_SOURCES = $(tests_srcdir)/library/test-safeclib.c
|
||||
test_safeclib_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
test_safeclib_LDADD = $(builddir)/liblumi.a -lnobugmt -lpthread -ldl -lm
|
||||
|
||||
check_PROGRAMS += test-uuid
|
||||
test_uuid_SOURCES = $(tests_srcdir)/library/test-uuid.c
|
||||
test_uuid_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
test_uuid_LDADD = $(builddir)/liblumi.a -lnobugmt -lpthread -ldl -lm
|
||||
|
||||
check_PROGRAMS += test-references
|
||||
test_references_SOURCES = $(tests_srcdir)/library/test-references.c
|
||||
test_references_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
test_references_LDADD = liblumi.a -lnobugmt -lpthread -ldl -lm -lrt
|
||||
|
||||
#check_PROGRAMS += test-filehandles
|
||||
#test_filehandles_SOURCES = $(tests_srcdir)/backend/test-filehandles.c
|
||||
#test_filehandles_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
#test_filehandles_LDADD = liblumibackend.a liblumi.a -lnobugmt -lpthread -ldl -lm
|
||||
check_PROGRAMS += test-filedescriptors
|
||||
test_filedescriptors_SOURCES = $(tests_srcdir)/backend/test-filedescriptors.c
|
||||
test_filedescriptors_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
test_filedescriptors_LDADD = liblumibackend.a liblumi.a -lnobugmt -lpthread -ldl -lm
|
||||
|
||||
check_PROGRAMS += test-filehandles
|
||||
test_filehandles_SOURCES = $(tests_srcdir)/backend/test-filehandles.c
|
||||
test_filehandles_CPPFLAGS = $(AM_CPPFLAGS) -std=gnu99 -Wall -Werror -I$(top_srcdir)/src/
|
||||
test_filehandles_LDADD = liblumibackend.a liblumi.a -lnobugmt -lpthread -ldl -lm
|
||||
|
||||
TESTS = $(tests_srcdir)/test.sh
|
||||
|
|
|
|||
89
tests/backend/test-filedescriptors.c
Normal file
89
tests/backend/test-filedescriptors.c
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
test-filedescriptors.c
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "lib/safeclib.h"
|
||||
|
||||
#include "backend/backend.h"
|
||||
#include "backend/filedescriptor.h"
|
||||
|
||||
#include "tests/test.h"
|
||||
|
||||
TESTS_BEGIN
|
||||
|
||||
TEST ("acquire_existing")
|
||||
{
|
||||
lumiera_backend_init ();
|
||||
LumieraFiledescriptor descriptor = lumiera_filedescriptor_acquire (",tmp_testfile", LUMIERA_FILE_READONLY);
|
||||
if (descriptor)
|
||||
{
|
||||
lumiera_filedescriptor_release (descriptor);
|
||||
lumiera_backend_destroy ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST ("acquire_existing_again")
|
||||
{
|
||||
lumiera_backend_init ();
|
||||
LumieraFiledescriptor descriptor = lumiera_filedescriptor_acquire (",tmp_testfile", LUMIERA_FILE_READONLY);
|
||||
if (descriptor)
|
||||
{
|
||||
LumieraFiledescriptor descriptor2 = lumiera_filedescriptor_acquire (",tmp_testfile", LUMIERA_FILE_READONLY);
|
||||
lumiera_filedescriptor_release (descriptor2);
|
||||
lumiera_filedescriptor_release (descriptor);
|
||||
lumiera_backend_destroy ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST ("acquire_create")
|
||||
{
|
||||
lumiera_backend_init ();
|
||||
LumieraFiledescriptor descriptor = lumiera_filedescriptor_acquire (",tmp_testfile", LUMIERA_FILE_CREATE);
|
||||
if (descriptor)
|
||||
{
|
||||
lumiera_filedescriptor_release (descriptor);
|
||||
lumiera_backend_destroy ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
TEST ("acquire_create_dir")
|
||||
{
|
||||
lumiera_backend_init ();
|
||||
LumieraFiledescriptor descriptor =
|
||||
lumiera_filedescriptor_acquire (",tmp_testdir/nested/,tmp_testfile", LUMIERA_FILE_CREATE);
|
||||
if (descriptor)
|
||||
{
|
||||
lumiera_filedescriptor_release (descriptor);
|
||||
lumiera_backend_destroy ();
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
TESTS_END
|
||||
87
tests/backend/test-filehandles.c
Normal file
87
tests/backend/test-filehandles.c
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
test-filehandles.c - test filehandle management
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "lib/llist.h"
|
||||
#include "lib/safeclib.h"
|
||||
|
||||
#include "backend/backend.h"
|
||||
#include "backend/filehandlecache.h"
|
||||
|
||||
#include "tests/test.h"
|
||||
|
||||
TESTS_BEGIN
|
||||
|
||||
TEST ("basic")
|
||||
{
|
||||
lumiera_backend_init ();
|
||||
LumieraFile file = lumiera_file_new (",tmp_testfile", LUMIERA_FILE_CREATE);
|
||||
|
||||
/* get the filehandle */
|
||||
int fd = lumiera_file_handle_acquire (file);
|
||||
|
||||
/* we now 'own'it and can use it */
|
||||
ENSURE (fd > -1);
|
||||
printf ("got filehandle #%d\n", fd);
|
||||
|
||||
/* put it into aging, can't use anymore */
|
||||
lumiera_file_handle_release (file);
|
||||
|
||||
lumiera_file_delete (file);
|
||||
lumiera_backend_destroy ();
|
||||
}
|
||||
|
||||
|
||||
TEST ("more")
|
||||
{
|
||||
lumiera_backend_init ();
|
||||
|
||||
LumieraFile files[100];
|
||||
int fds[100];
|
||||
|
||||
/*create 100 files*/
|
||||
for (int i=0; i<100; ++i)
|
||||
{
|
||||
files[i]= lumiera_file_new (lumiera_tmpbuf_snprintf (256, ",tmpdir/testfile%d", i), LUMIERA_FILE_CREATE);
|
||||
}
|
||||
|
||||
/* get the filehandles, this gross overallocates filehandles */
|
||||
for (int i=0; i<100; ++i)
|
||||
{
|
||||
fds[i] = lumiera_file_handle_acquire (files[i]);
|
||||
ENSURE (fds[i] > -1);
|
||||
printf ("got filehandle #%d\n", fds[i]);
|
||||
}
|
||||
|
||||
/* put them into aging, can't use anymore */
|
||||
for (int i=0; i<100; ++i)
|
||||
{
|
||||
lumiera_file_handle_release (files[i]);
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
for (int i=0; i<100; ++i)
|
||||
{
|
||||
lumiera_file_delete (files[i]);
|
||||
}
|
||||
|
||||
lumiera_backend_destroy ();
|
||||
}
|
||||
|
||||
TESTS_END
|
||||
61
tests/common/Makefile.am
Normal file
61
tests/common/Makefile.am
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
# Copyright (C) Lumiera.org
|
||||
# 2008, Christian Thaeter <ct@pipapo.org>
|
||||
# Hermann Vosseler <Ichthyostega@web.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
testcommon_srcdir = $(top_srcdir)/tests/common
|
||||
|
||||
check_PROGRAMS += test-common
|
||||
test_common_CPPFLAGS = $(AM_CPPFLAGS) -Wall -I$(top_srcdir)/src -I$(testcommon_srcdir)
|
||||
test_common_LDADD = \
|
||||
liblumiproc.a \
|
||||
liblumiprocengine.a \
|
||||
liblumiprocmobjectbuilder.a \
|
||||
liblumiprocmobjectsession.a \
|
||||
liblumiprocasset.a \
|
||||
liblumiprocmobject.a \
|
||||
liblumiprocmobjectcontroller.a \
|
||||
liblumi.a \
|
||||
liblumicommon.a \
|
||||
liblumibackend.a \
|
||||
-lnobugmt -lpthread -ldl -lboost_program_options-mt -lboost_regex-mt
|
||||
|
||||
test_common_SOURCES = \
|
||||
$(testcommon_srcdir)/appconfigtest.cpp \
|
||||
$(testcommon_srcdir)/customsharedptrtest.cpp \
|
||||
$(testcommon_srcdir)/exceptionerrortest.cpp \
|
||||
$(testcommon_srcdir)/factoryspecialtest.cpp \
|
||||
$(testcommon_srcdir)/factorytest.cpp \
|
||||
$(testcommon_srcdir)/helloworldtest.cpp \
|
||||
$(testcommon_srcdir)/lifecycletest.cpp \
|
||||
$(testcommon_srcdir)/mainsuite.cpp \
|
||||
$(testcommon_srcdir)/query/queryutilstest.cpp \
|
||||
$(testcommon_srcdir)/removefromsettest.cpp \
|
||||
$(testcommon_srcdir)/sanitizedidentifiertest.cpp \
|
||||
$(testcommon_srcdir)/singletonsubclasstest.cpp \
|
||||
$(testcommon_srcdir)/singletontest.cpp \
|
||||
$(testcommon_srcdir)/singletontestmocktest.cpp \
|
||||
$(testcommon_srcdir)/test/cmdlinewrappertest.cpp \
|
||||
$(testcommon_srcdir)/test/testoptiontest.cpp \
|
||||
$(testcommon_srcdir)/typelisttest.cpp \
|
||||
$(testcommon_srcdir)/typelistutiltest.cpp \
|
||||
$(testcommon_srcdir)/visitingtoolconcept.cpp \
|
||||
$(testcommon_srcdir)/visitingtoolextendedtest.cpp \
|
||||
$(testcommon_srcdir)/visitingtooltest.cpp
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(testcommon_srcdir)/query/querydiagnostics.hpp \
|
||||
$(testcommon_srcdir)/testtargetobj.hpp
|
||||
72
tests/components/Makefile.am
Normal file
72
tests/components/Makefile.am
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
# Copyright (C) Lumiera.org
|
||||
# 2008, Christian Thaeter <ct@pipapo.org>
|
||||
# Hermann Vosseler <Ichthyostega@web.de>
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License as
|
||||
# published by the Free Software Foundation; either version 2 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
testcomponents_srcdir = $(top_srcdir)/tests/components
|
||||
|
||||
check_PROGRAMS += test-components
|
||||
test_components_CPPFLAGS = $(AM_CPPFLAGS) -Wall -I$(top_srcdir)/src -I$(testcomponents_srcdir)
|
||||
test_components_LDADD = \
|
||||
liblumiproc.a \
|
||||
liblumiprocengine.a \
|
||||
liblumiprocmobjectbuilder.a \
|
||||
liblumiprocmobjectsession.a \
|
||||
liblumiprocasset.a \
|
||||
liblumiprocmobject.a \
|
||||
liblumiprocmobjectcontroller.a \
|
||||
liblumi.a \
|
||||
liblumicommon.a \
|
||||
liblumibackend.a \
|
||||
-lnobugmt -lpthread -ldl -lboost_program_options-mt -lboost_regex-mt
|
||||
|
||||
test_components_SOURCES = \
|
||||
$(testcomponents_srcdir)/backend/mediaaccessmock.cpp \
|
||||
$(testcomponents_srcdir)/backend/mediaaccessmocktest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/assetcategorytest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/compoundmediatest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/deleteassettest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/identityofassetstest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/mediastructurequerytest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/basicpipetest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/createassettest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/dependantassetstest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/makecliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/orderingofassetstest.cpp \
|
||||
$(testcomponents_srcdir)/proc/asset/testasset.cpp \
|
||||
$(testcomponents_srcdir)/proc/engine/sourcenodetest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/builder/buildertooltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/builder/buildsegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/controller/rendersegmenttest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/placementbasictest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/addcliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/deletecliptest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/rebuildfixturetest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/sessionmanagertest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/testclip.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsmanagerimpltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsmanagertest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/defsregistryimpltest.cpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/sessionstructuretest.cpp \
|
||||
$(testcomponents_srcdir)/mainsuite.cpp
|
||||
|
||||
noinst_HEADERS += \
|
||||
$(testcomponents_srcdir)/backend/mediaaccessmock.hpp \
|
||||
$(testcomponents_srcdir)/proc/asset/testclipasset.hpp \
|
||||
$(testcomponents_srcdir)/proc/asset/assetdiagnostics.hpp \
|
||||
$(testcomponents_srcdir)/proc/asset/testasset.hpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/testclip.hpp \
|
||||
$(testcomponents_srcdir)/proc/mobject/session/testsession1.hpp
|
||||
|
|
@ -23,173 +23,166 @@
|
|||
//#include <string.h>
|
||||
|
||||
#include "lib/llist.h"
|
||||
#include "lib/error.h"
|
||||
#include "tests/test.h"
|
||||
|
||||
TESTS_BEGIN
|
||||
|
||||
LUMIERA_ERROR_DEFINE(TEST, "test error");
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
TEST ("basic")
|
||||
{
|
||||
NOBUG_INIT;
|
||||
LLIST_AUTO (node1);
|
||||
|
||||
if (argc == 1)
|
||||
return 0;
|
||||
llist node2;
|
||||
llist_init (&node2);
|
||||
|
||||
if (!strcmp(argv[1], "basic"))
|
||||
{
|
||||
LLIST_AUTO (node1);
|
||||
|
||||
llist node2;
|
||||
llist_init (&node2);
|
||||
|
||||
printf ("%d\n", llist_is_empty (&node1));
|
||||
printf ("%d\n", llist_is_empty (&node2));
|
||||
}
|
||||
else if (!strcmp(argv[1], "nodeinsert"))
|
||||
{
|
||||
LLIST_AUTO (list);
|
||||
LLIST_AUTO (node1);
|
||||
LLIST_AUTO (node2);
|
||||
LLIST_AUTO (node3);
|
||||
|
||||
llist_insert_next (&list, &node1);
|
||||
printf ("%d\n", llist_is_empty (&list));
|
||||
printf ("%d\n", llist_is_empty (&node1));
|
||||
printf ("%d\n", llist_is_single (&node1));
|
||||
llist_insert_next (&node1, &node2);
|
||||
printf ("%d\n", llist_is_single (&node1));
|
||||
llist_insert_prev (&node1, &node3);
|
||||
printf ("%d\n", llist_next (&list) == &node3);
|
||||
printf ("%d\n", llist_next (&node3) == &node1);
|
||||
printf ("%d\n", llist_next (&node1) == &node2);
|
||||
printf ("%d\n", llist_prev (&list) == &node2);
|
||||
printf ("%d\n", llist_count (&list));
|
||||
}
|
||||
else if (!strcmp(argv[1], "predicates"))
|
||||
{
|
||||
LLIST_AUTO (list);
|
||||
LLIST_AUTO (node1);
|
||||
LLIST_AUTO (node2);
|
||||
LLIST_AUTO (node3);
|
||||
LLIST_AUTO (node4);
|
||||
LLIST_AUTO (nil);
|
||||
|
||||
llist_insert_tail (&list, &node2);
|
||||
llist_insert_tail (&list, &node3);
|
||||
llist_insert_tail (&list, &node4);
|
||||
llist_insert_head (&list, &node1);
|
||||
|
||||
printf ("%d\n", llist_is_head (&list, &node1));
|
||||
printf ("%d\n", llist_is_tail (&list, &node4));
|
||||
printf ("%d\n", llist_is_head (&list, &node4));
|
||||
printf ("%d\n", llist_is_tail (&list, &node1));
|
||||
printf ("%d\n", llist_is_end (&list, &list));
|
||||
printf ("%d\n", llist_is_member (&list, &node3));
|
||||
printf ("%d\n", llist_is_member (&list, &nil));
|
||||
|
||||
printf ("%d\n", llist_is_before_after (&list, &node1, &node3));
|
||||
printf ("%d\n", llist_is_before_after (&list, &node3, &node1));
|
||||
printf ("%d\n", llist_is_before_after (&list, &node1, &nil));
|
||||
}
|
||||
else if (!strcmp(argv[1], "unlink"))
|
||||
{
|
||||
LLIST_AUTO (list);
|
||||
LLIST_AUTO (node1);
|
||||
LLIST_AUTO (node2);
|
||||
LLIST_AUTO (node3);
|
||||
LLIST_AUTO (node4);
|
||||
LLIST_AUTO (nil);
|
||||
|
||||
llist_insert_tail (&list, &node2);
|
||||
llist_insert_tail (&list, &node3);
|
||||
llist_insert_tail (&list, &node4);
|
||||
llist_insert_head (&list, &node1);
|
||||
|
||||
LLIST_FOREACH_REV (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
|
||||
llist_unlink (&nil);
|
||||
llist_unlink (&node2);
|
||||
llist_unlink (&node3);
|
||||
|
||||
LLIST_FOREACH (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
printf ("%d\n", llist_is_empty (&node2));
|
||||
printf ("%d\n", llist_is_empty (&node3));
|
||||
printf ("%d\n", llist_is_empty (&nil));
|
||||
}
|
||||
else if (!strcmp(argv[1], "whiles"))
|
||||
{
|
||||
LLIST_AUTO (list);
|
||||
LLIST_AUTO (node1);
|
||||
LLIST_AUTO (node2);
|
||||
LLIST_AUTO (node3);
|
||||
LLIST_AUTO (node4);
|
||||
LLIST_AUTO (nil);
|
||||
|
||||
llist_insert_tail (&list, &node2);
|
||||
llist_insert_tail (&list, &node3);
|
||||
llist_insert_tail (&list, &node4);
|
||||
llist_insert_head (&list, &node1);
|
||||
|
||||
LLIST_FOREACH_REV (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
|
||||
LLIST_WHILE_HEAD (&list, head)
|
||||
llist_unlink (head);
|
||||
|
||||
LLIST_FOREACH (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
|
||||
llist_insert_tail (&list, &node2);
|
||||
llist_insert_tail (&list, &node3);
|
||||
llist_insert_tail (&list, &node4);
|
||||
llist_insert_head (&list, &node1);
|
||||
|
||||
LLIST_WHILE_TAIL (&list, tail)
|
||||
llist_unlink (tail);
|
||||
|
||||
LLIST_FOREACH (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
printf ("%d\n", llist_is_empty (&node1));
|
||||
printf ("%d\n", llist_is_empty (&node2));
|
||||
}
|
||||
|
||||
TEST ("nodeinsert")
|
||||
{
|
||||
LLIST_AUTO (list);
|
||||
LLIST_AUTO (node1);
|
||||
LLIST_AUTO (node2);
|
||||
LLIST_AUTO (node3);
|
||||
|
||||
llist_insert_next (&list, &node1);
|
||||
printf ("%d\n", llist_is_empty (&list));
|
||||
printf ("%d\n", llist_is_empty (&node1));
|
||||
printf ("%d\n", llist_is_single (&node1));
|
||||
llist_insert_next (&node1, &node2);
|
||||
printf ("%d\n", llist_is_single (&node1));
|
||||
llist_insert_prev (&node1, &node3);
|
||||
printf ("%d\n", llist_next (&list) == &node3);
|
||||
printf ("%d\n", llist_next (&node3) == &node1);
|
||||
printf ("%d\n", llist_next (&node1) == &node2);
|
||||
printf ("%d\n", llist_prev (&list) == &node2);
|
||||
printf ("%d\n", llist_count (&list));
|
||||
}
|
||||
|
||||
TEST ("predicates")
|
||||
{
|
||||
LLIST_AUTO (list);
|
||||
LLIST_AUTO (node1);
|
||||
LLIST_AUTO (node2);
|
||||
LLIST_AUTO (node3);
|
||||
LLIST_AUTO (node4);
|
||||
LLIST_AUTO (nil);
|
||||
|
||||
llist_insert_tail (&list, &node2);
|
||||
llist_insert_tail (&list, &node3);
|
||||
llist_insert_tail (&list, &node4);
|
||||
llist_insert_head (&list, &node1);
|
||||
|
||||
printf ("%d\n", llist_is_head (&list, &node1));
|
||||
printf ("%d\n", llist_is_tail (&list, &node4));
|
||||
printf ("%d\n", llist_is_head (&list, &node4));
|
||||
printf ("%d\n", llist_is_tail (&list, &node1));
|
||||
printf ("%d\n", llist_is_end (&list, &list));
|
||||
printf ("%d\n", llist_is_member (&list, &node3));
|
||||
printf ("%d\n", llist_is_member (&list, &nil));
|
||||
|
||||
printf ("%d\n", llist_is_before_after (&list, &node1, &node3));
|
||||
printf ("%d\n", llist_is_before_after (&list, &node3, &node1));
|
||||
printf ("%d\n", llist_is_before_after (&list, &node1, &nil));
|
||||
}
|
||||
|
||||
TEST ("unlink")
|
||||
{
|
||||
LLIST_AUTO (list);
|
||||
LLIST_AUTO (node1);
|
||||
LLIST_AUTO (node2);
|
||||
LLIST_AUTO (node3);
|
||||
LLIST_AUTO (node4);
|
||||
LLIST_AUTO (nil);
|
||||
|
||||
llist_insert_tail (&list, &node2);
|
||||
llist_insert_tail (&list, &node3);
|
||||
llist_insert_tail (&list, &node4);
|
||||
llist_insert_head (&list, &node1);
|
||||
|
||||
LLIST_FOREACH_REV (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
|
||||
llist_unlink (&nil);
|
||||
llist_unlink (&node2);
|
||||
llist_unlink (&node3);
|
||||
|
||||
LLIST_FOREACH (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
printf ("%d\n", llist_is_empty (&node2));
|
||||
printf ("%d\n", llist_is_empty (&node3));
|
||||
printf ("%d\n", llist_is_empty (&nil));
|
||||
}
|
||||
|
||||
TEST ("whiles")
|
||||
{
|
||||
LLIST_AUTO (list);
|
||||
LLIST_AUTO (node1);
|
||||
LLIST_AUTO (node2);
|
||||
LLIST_AUTO (node3);
|
||||
LLIST_AUTO (node4);
|
||||
LLIST_AUTO (nil);
|
||||
|
||||
llist_insert_tail (&list, &node2);
|
||||
llist_insert_tail (&list, &node3);
|
||||
llist_insert_tail (&list, &node4);
|
||||
llist_insert_head (&list, &node1);
|
||||
|
||||
LLIST_FOREACH_REV (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
|
||||
LLIST_WHILE_HEAD (&list, head)
|
||||
llist_unlink (head);
|
||||
|
||||
LLIST_FOREACH (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
|
||||
llist_insert_tail (&list, &node2);
|
||||
llist_insert_tail (&list, &node3);
|
||||
llist_insert_tail (&list, &node4);
|
||||
llist_insert_head (&list, &node1);
|
||||
|
||||
LLIST_WHILE_TAIL (&list, tail)
|
||||
llist_unlink (tail);
|
||||
|
||||
LLIST_FOREACH (&list, itr)
|
||||
{
|
||||
if(itr == &node1) printf ("node1 ");
|
||||
else if(itr == &node2) printf ("node2 ");
|
||||
else if(itr == &node3) printf ("node3 ");
|
||||
else if(itr == &node4) printf ("node4 ");
|
||||
else printf ("unknown ");
|
||||
}
|
||||
printf (".\n");
|
||||
}
|
||||
|
||||
|
||||
TESTS_END
|
||||
|
|
|
|||
85
tests/library/test-safeclib.c
Normal file
85
tests/library/test-safeclib.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
Copyright (C) Lumiera.org
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#include "lib/safeclib.h"
|
||||
#include "tests/test.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
|
||||
TESTS_BEGIN
|
||||
|
||||
TEST ("allocation0")
|
||||
{
|
||||
lumiera_malloc (0);
|
||||
NOTREACHED;
|
||||
}
|
||||
|
||||
TEST ("allocation1024")
|
||||
{
|
||||
void* data[1024];
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
data[i] = lumiera_malloc (1024);
|
||||
ENSURE (data[i]);
|
||||
}
|
||||
for (int i = 0; i < 1024; ++i)
|
||||
{
|
||||
free (data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST ("allocationtoobig")
|
||||
{
|
||||
struct rlimit rl;
|
||||
rl.rlim_cur = 100*1024*1024;
|
||||
rl.rlim_max = 100*1024*1024;
|
||||
setrlimit (RLIMIT_AS, &rl);
|
||||
lumiera_malloc (200*1024*1024);
|
||||
NOTREACHED;
|
||||
}
|
||||
|
||||
TEST ("streq")
|
||||
{
|
||||
if (!lumiera_streq ("foo", "foo"))
|
||||
LUMIERA_DIE (TEST);
|
||||
if (!lumiera_streq (NULL, NULL))
|
||||
LUMIERA_DIE (TEST);
|
||||
if (!!lumiera_streq (NULL, "foo"))
|
||||
LUMIERA_DIE (TEST);
|
||||
if (!!lumiera_streq ("foo", NULL))
|
||||
LUMIERA_DIE (TEST);
|
||||
if (!!lumiera_streq ("foo", "bar"))
|
||||
LUMIERA_DIE (TEST);
|
||||
}
|
||||
|
||||
TEST ("tmpbuf")
|
||||
{
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
char* buf = lumiera_tmpbuf_provide (1024);
|
||||
|
||||
for (int j = 0; j < 1024; ++j)
|
||||
{
|
||||
buf[j] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
TESTS_END
|
||||
73
tests/library/test-uuid.c
Normal file
73
tests/library/test-uuid.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
test-uuid.c - test the uuid lib
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2007, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
//#include "cinelerra-config.h"
|
||||
|
||||
//#include <stdio.h>
|
||||
|
||||
|
||||
#include "lib/uuid.h"
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
//CINELERRA_ERROR_DEFINE(TEST, "test error");
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
{
|
||||
NOBUG_INIT;
|
||||
|
||||
if (argc == 1)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(argv[1], "uuidgen_2"))
|
||||
{
|
||||
lumiera_uuid uuid1;
|
||||
lumiera_uuid uuid2;
|
||||
|
||||
lumiera_uuid_gen (&uuid1);
|
||||
lumiera_uuid_gen (&uuid2);
|
||||
|
||||
printf ("%d\n", lumiera_uuid_eq (&uuid2, &uuid1));
|
||||
}
|
||||
else if (!strcmp(argv[1], "uuidgen_copy"))
|
||||
{
|
||||
lumiera_uuid uuid1;
|
||||
lumiera_uuid uuid2;
|
||||
|
||||
lumiera_uuid_gen (&uuid1);
|
||||
|
||||
lumiera_uuid_copy (&uuid2, &uuid1);
|
||||
|
||||
printf ("%d\n", lumiera_uuid_eq (&uuid2, &uuid1));
|
||||
}
|
||||
else if (!strcmp(argv[1], "ptrs"))
|
||||
{
|
||||
lumiera_uuid uuid;
|
||||
|
||||
lumiera_uuid_set_ptr (&uuid, &uuid);
|
||||
|
||||
printf ("%d\n", lumiera_uuid_ptr_get (&uuid) == &uuid);
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -21,33 +21,21 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "lib/error.h"
|
||||
|
||||
LUMIERA_ERROR_DEFINE(TEST, "test error");
|
||||
#include "tests/test.h"
|
||||
|
||||
int conditionforgotunlock ();
|
||||
int mutexforgotunlock ();
|
||||
|
||||
TESTS_BEGIN
|
||||
|
||||
int
|
||||
main (int argc, char** argv)
|
||||
TEST ("conditionforgotunlock")
|
||||
{
|
||||
NOBUG_INIT;
|
||||
|
||||
if (argc == 1)
|
||||
return 0;
|
||||
|
||||
if (!strcmp(argv[1], "conditionforgotunlock"))
|
||||
{
|
||||
return conditionforgotunlock ();
|
||||
}
|
||||
if (!strcmp(argv[1], "mutexforgotunlock"))
|
||||
{
|
||||
return mutexforgotunlock ();
|
||||
}
|
||||
else
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
return conditionforgotunlock ();
|
||||
}
|
||||
|
||||
TEST ("mutexforgotunlock")
|
||||
{
|
||||
return mutexforgotunlock ();
|
||||
}
|
||||
|
||||
TESTS_END
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include "lib/plugin.h"
|
||||
#include "hello_interface.h"
|
||||
|
||||
LUMIERA_ERROR_DEFINE(FAILURE, "test failure");
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
|
|
@ -25,7 +26,7 @@ main(int argc, char** argv)
|
|||
LUMIERA_INTERFACE_TYPE(hello, 1)* hello_de =
|
||||
(LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin", "german_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1)));
|
||||
|
||||
if (!hello_de) LUMIERA_DIE;
|
||||
if (!hello_de) LUMIERA_DIE (FAILURE);
|
||||
|
||||
hello_de->hello();
|
||||
hello_de->goodbye(argv[1]);
|
||||
|
|
@ -33,7 +34,7 @@ main(int argc, char** argv)
|
|||
LUMIERA_INTERFACE_TYPE(hello, 1)* hello_en =
|
||||
(LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin", "english_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1)));
|
||||
|
||||
if (!hello_en) LUMIERA_DIE;
|
||||
if (!hello_en) LUMIERA_DIE (FAILURE);
|
||||
|
||||
hello_en->hello();
|
||||
hello_en->goodbye(argv[1]);
|
||||
|
|
@ -48,7 +49,7 @@ main(int argc, char** argv)
|
|||
LUMIERA_INTERFACE_TYPE(hello, 1)* hello_de =
|
||||
(LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin_cpp", "german_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1)));
|
||||
|
||||
if (!hello_de) LUMIERA_DIE;
|
||||
if (!hello_de) LUMIERA_DIE (FAILURE);
|
||||
|
||||
hello_de->hello();
|
||||
hello_de->goodbye(argv[1]);
|
||||
|
|
@ -56,7 +57,7 @@ main(int argc, char** argv)
|
|||
LUMIERA_INTERFACE_TYPE(hello, 1)* hello_en =
|
||||
(LUMIERA_INTERFACE_TYPE(hello, 1)*) lumiera_interface_open ("example_plugin_cpp", "english_1", sizeof(LUMIERA_INTERFACE_TYPE(hello, 1)));
|
||||
|
||||
if (!hello_en) LUMIERA_DIE;
|
||||
if (!hello_en) LUMIERA_DIE (FAILURE);
|
||||
|
||||
hello_en->hello();
|
||||
hello_en->goodbye(argv[1]);
|
||||
|
|
|
|||
52
tests/test.h
Normal file
52
tests/test.h
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
test.h - macros for running tests
|
||||
|
||||
Copyright (C) CinelerraCV
|
||||
2008, Christian Thaeter <ct@pipapo.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef TEST_H
|
||||
#define TEST_H
|
||||
|
||||
#include <nobug.h>
|
||||
|
||||
#include "lib/error.h"
|
||||
|
||||
LUMIERA_ERROR_DEFINE (TEST, "test error");
|
||||
|
||||
#define TESTS_BEGIN \
|
||||
int \
|
||||
main (int argc, char** argv) \
|
||||
{ \
|
||||
NOBUG_INIT; \
|
||||
\
|
||||
if (argc == 1) \
|
||||
return 1;
|
||||
|
||||
#define TEST(name) \
|
||||
else if (!strcmp(argv[1], name))
|
||||
|
||||
|
||||
#define TESTS_END \
|
||||
else \
|
||||
return 1; \
|
||||
\
|
||||
return 0; \
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -2104,13 +2104,26 @@ if (oldText.indexOf("SplashScreen")==-1)
|
|||
}
|
||||
//}}}</pre>
|
||||
</div>
|
||||
<div title="StyleGuide" modifier="CehTeh" modified="200803261336" created="200803261258" changecount="4">
|
||||
<div title="StyleGuide" modifier="CehTeh" modified="200803261924" created="200803261258" changecount="6">
|
||||
<pre>! Source code formatting
|
||||
http://www.gnu.org/prep/standards/html_node/Formatting.html#Formatting
|
||||
We decided to use the 'gnu-style' for indenting (using spaces and never tabs!):
|
||||
http://www.gnu.org/prep/standards/html_node/Formatting.html#Formatting
|
||||
|
||||
It is reasonable to be relaxed about soem formatting rules:
|
||||
* line length might be longer when required
|
||||
* inter expession spacing can be changed to the actual needed ex: (2*x + 2)
|
||||
|
||||
Things we are pedantic about:
|
||||
* use never ever tab characters in C/C++ sources
|
||||
* be consistent
|
||||
* source files should end with a newline
|
||||
* no trailing or bogus whitespaces
|
||||
|
||||
! Coding Practices
|
||||
|
||||
! Writing Tests
|
||||
|
||||
! Contibuting
|
||||
|
||||
! Tests
|
||||
</pre>
|
||||
</div>
|
||||
<div title="StyleSheet" modifier="CehTeh" modified="200706090017" created="200701131624" tags="MPTWTheme" server.type="file" server.host="file:///home/ct/.homepage/home.html" server.page.revision="200706090017">
|
||||
|
|
|
|||
0
wiki/index.html
Executable file → Normal file
0
wiki/index.html
Executable file → Normal file
|
|
@ -3344,6 +3344,15 @@ Someone might pickup a Doxygen-Maintainer. This is not writing actual documentat
|
|||
<div title="video player mockup" modifier="Ichthyostega" modified="200804120416" created="200804090216" changecount="4">
|
||||
<pre>Use the backend, gmerlin/avdecoder and a Player widget to playback videos. This should be a small application which can open and playback many videos from one instance in parallel. Later on scrubbing for this videos might be supported.
|
||||
|
||||
The idea here is to show and measure backend and scheduler performance
|
||||
and beeing a proof of concept for the design. It will run
|
||||
independent of the Proc layer but needs quite some work on the
|
||||
backend to be done.
|
||||
</pre>
|
||||
</div>
|
||||
<div title="video player mockup" modifier="CehTeh" modified="200804090218" created="200804090216" changecount="3">
|
||||
<pre>Use the backend, gmerlin/avdecoder and a Player widget to playback videos. This should be a small application which can open and playback many videos from on instance in parallel. Later on scrubbing for this videos might be supported.
|
||||
|
||||
The idea here is to show and measure backend and scheduler performance and beeing a proof of concept for the design. It will run independent of the Proc layer but needs quite some work on the backend to be done.</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue