├── .clang-format ├── .gitattributes ├── .gitignore ├── .gitmodules ├── .gitsubprojects ├── .travis.yml ├── ACKNOWLEDGEMENTS.txt ├── AUTHORS.txt ├── CHANGES.txt ├── CMake ├── .gitignore ├── CPackConfig.cmake ├── Lunchbox.in.spec └── Lunchbox.spec ├── CMakeLists.txt ├── LGPL.txt ├── LICENSE.txt ├── README.md ├── doc ├── CMakeLists.txt └── Changelog.md ├── lunchbox ├── CMakeLists.txt ├── algorithm.h ├── any.cpp ├── any.h ├── anySerialization.h ├── array.h ├── atomic.cpp ├── atomic.h ├── bitOperation.h ├── buffer.h ├── buffer.ipp ├── clock.cpp ├── clock.h ├── compiler.h ├── daemon.h ├── debug.cpp ├── debug.h ├── detail │ └── threadID.h ├── dso.cpp ├── dso.h ├── file.cpp ├── file.h ├── fork.cpp ├── fork.h ├── future.h ├── futureFunction.h ├── hash.h ├── indexIterator.h ├── init.cpp ├── init.h ├── intervalSet.h ├── intervalSet.ipp ├── lfQueue.h ├── lfQueue.ipp ├── lfVector.h ├── lfVector.ipp ├── lfVectorIterator.h ├── lockable.h ├── log.cpp ├── log.h ├── memoryMap.cpp ├── memoryMap.h ├── monitor.h ├── mtQueue.h ├── mtQueue.ipp ├── os.cpp ├── os.h ├── perThread.h ├── perThread.ipp ├── perThreadRef.h ├── plugin.h ├── pluginFactory.h ├── pluginFactory.ipp ├── pluginRegisterer.h ├── pool.h ├── readyFuture.h ├── refPtr.h ├── referenced.cpp ├── referenced.h ├── request.h ├── requestHandler.cpp ├── requestHandler.h ├── result.h ├── rng.cpp ├── rng.h ├── scopedMutex.h ├── serializable.h ├── servus.h ├── sleep.cpp ├── sleep.h ├── spinLock.cpp ├── spinLock.h ├── string.h ├── term.cpp ├── term.h ├── test.h ├── thread.cpp ├── thread.h ├── threadID.cpp ├── threadID.h ├── threadPool.cpp ├── threadPool.h ├── time.h ├── tls.cpp ├── tls.h ├── types.h ├── uint128_t.h ├── uri.h └── visitorResult.h ├── pthreads ├── CMakeLists.txt └── pthreads-w32-2011-03-16.tar.gz └── tests ├── CMakeLists.txt ├── any.cpp ├── anySerialization.cpp ├── bitOperation.cpp ├── buffer.cpp ├── clock.cpp ├── debug.cpp ├── dso.cpp ├── file.cpp ├── future.cpp ├── init.cpp ├── intervalSet.cpp ├── issue1.cpp ├── lfQueue.cpp ├── memoryMap.cpp ├── monitor.cpp ├── mtQueue.cpp ├── perThread.cpp ├── perf ├── lfVector.cpp ├── memory.cpp ├── mutex.cpp └── rwLock.cpp ├── pluginFactory.cpp ├── refPtr.cpp ├── requestHandler.cpp ├── result.cpp ├── rng.cpp ├── serialize.h ├── string.cpp ├── thread.cpp └── threadPool.cpp /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | AccessModifierOffset: -4 3 | AlignConsecutiveAssignments: false 4 | AlignConsecutiveDeclarations: false 5 | AlignEscapedNewlinesLeft: true 6 | AlignOperands: true 7 | AlignTrailingComments: true 8 | AllowAllParametersOfDeclarationOnNextLine: true 9 | AllowShortFunctionsOnASingleLine: Inline 10 | AllowShortIfStatementsOnASingleLine: false 11 | AllowShortLoopsOnASingleLine: false 12 | AlwaysBreakBeforeMultilineStrings: true 13 | AlwaysBreakTemplateDeclarations: true 14 | BinPackParameters: true 15 | BreakBeforeBinaryOperators: false 16 | BreakBeforeBraces: Allman # brace on new line 17 | BreakBeforeTernaryOperators: true 18 | BreakConstructorInitializersBeforeComma: true 19 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 20 | ConstructorInitializerIndentWidth: 4 21 | ContinuationIndentWidth: 4 22 | Cpp11BracedListStyle: true 23 | DerivePointerBinding: true 24 | ExperimentalAutoDetectBinPacking: false 25 | IndentCaseLabels: false 26 | IndentFunctionDeclarationAfterType: true 27 | IndentWidth: 4 28 | KeepEmptyLinesAtTheStartOfBlocks: false 29 | Language: Cpp 30 | MaxEmptyLinesToKeep: 1 31 | NamespaceIndentation: None 32 | PenaltyBreakBeforeFirstCallParameter: 100 33 | PenaltyBreakComment: 60 34 | PenaltyBreakFirstLessLess: 120 35 | PenaltyBreakString: 1000 36 | PenaltyExcessCharacter: 1000000 37 | PenaltyReturnTypeOnItsOwnLine: 200 38 | PointerBindsToType: true 39 | SortIncludes: true 40 | SpaceAfterControlStatementKeyword: true 41 | SpaceBeforeAssignmentOperators: true 42 | SpaceBeforeParens: ControlStatements 43 | SpaceInEmptyParentheses: false 44 | SpacesBeforeTrailingComments: 1 45 | SpacesInAngles: false # '< ' style 46 | SpacesInCStyleCastParentheses: false 47 | SpacesInParentheses: false # '(' style 48 | Standard: Cpp11 49 | TabWidth: 4 50 | UseTab: Never 51 | ... 52 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | .travis.yml merge=ours 2 | CMake/FindPackages.cmake merge=ours 3 | CMake/FindRequired.cmake merge=ours 4 | CMake/GitExternal.cmake merge=ours 5 | CMake/depends.txt merge=ours 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | CMakeLists.txt.user* 3 | build/ 4 | ___* 5 | Servus/ 6 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "CMake/common"] 2 | path = CMake/common 3 | url = https://github.com/Eyescale/CMake 4 | -------------------------------------------------------------------------------- /.gitsubprojects: -------------------------------------------------------------------------------- 1 | # -*- mode: cmake -*- 2 | git_subproject(Servus https://github.com/HBPVIS/Servus.git 170bd93) 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | notifications: 2 | email: 3 | on_success: never 4 | language: cpp 5 | matrix: 6 | include: 7 | - os: linux 8 | dist: trusty 9 | sudo: required 10 | env: BUILD_TYPE=Debug 11 | - os: linux 12 | dist: trusty 13 | sudo: required 14 | env: BUILD_TYPE=Release 15 | - os: osx 16 | env: BUILD_TYPE=Debug 17 | - os: osx 18 | env: BUILD_TYPE=Release 19 | sudo: false 20 | env: 21 | global: 22 | - NINJA_STATUS="[%p %u/%t@%o %r]" 23 | - PROJECT_NAME=${PWD##*/} 24 | addons: 25 | apt: 26 | packages: 27 | - cppcheck 28 | - clang-format-3.8 29 | - doxygen 30 | - ninja-build 31 | - libboost-all-dev 32 | - avahi-daemon 33 | - libavahi-client-dev 34 | - qtbase5-dev 35 | before_install: 36 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi 37 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew outdated cmake || brew upgrade cmake; fi 38 | - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install cppcheck doxygen ninja clang-format; fi 39 | script: 40 | - mkdir $BUILD_TYPE 41 | - cd $BUILD_TYPE 42 | - cmake -GNinja -DCLONE_SUBPROJECTS=ON -DCMAKE_INSTALL_PREFIX=$PWD/install -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. 43 | - ninja all && ninja $PROJECT_NAME-tests && ninja smoketests 44 | - find . -name '*.[hc]' -o -name '*.[hci]pp' -o -name '*.frag' -o -name '*.vert' -o -name '*.ispc' -o -name '*.ih' | grep -v 'CMake/common' | xargs clang-format -style=file -fallback-style=none -i 45 | - git diff 46 | - git diff-index --quiet HEAD -- 47 | -------------------------------------------------------------------------------- /AUTHORS.txt: -------------------------------------------------------------------------------- 1 | 2 | The following people have contributed to LunchBox: 3 | 4 | ------ Core Team ------ 5 | 6 | Daniel Nachbaur 7 | Stefan Eilemann 8 | 9 | ------- git master ------- 10 | 11 | Martin Lambers 12 | 13 | -------- Contributions pre-LunchBox ------- 14 | 15 | Ahmet Bilgili 16 | Andreas Kirsch 17 | Carsten Rohn 18 | Cedric Stalder 19 | Christian Marten 20 | Christian Vix 21 | Daniel Pfeifer 22 | Dardo D. Kleiner 23 | Dustin Wüest 24 | Hui Chang 25 | Jan Ciger 26 | Jaroslav Skarvada 27 | Jens Willebrand 28 | Jonas Boesch 29 | Lucas Peetz Dulley 30 | Marc Treib 31 | Mario Degenhardt 32 | Markus Duensser 33 | Martin Lambers 34 | Matthew Dawson 35 | Maxim Makhinya 36 | Michael Dürig 37 | Paul E.C. Melis 38 | Philippe Robert 39 | Robert Hauck 40 | Sarah Amsellem 41 | Shree Kumar 42 | Stefan Roettger 43 | Stephen Furlani 44 | Tamer Fahmy 45 | Thomas McGuire 46 | Tobias Wolf 47 | Tomas Garcia-Pozuelo Barrios 48 | 49 | -------------------------------------------------------------------------------- /CHANGES.txt: -------------------------------------------------------------------------------- 1 | 2 | This file lists all changes in the public Lunchbox API, latest on top: 3 | 4 | 29/Jun/2015 5 | Deprecated WARN log level. Introduced DEBUG log level. Promoted INFO 6 | to be default-visible in release builds. 7 | 8 | 15/Feb/2013 9 | lunchbox::searchDirectory uses boost::regex for pattern matching. This 10 | changes the behaviour of this function, e.g., 11 | searchDirectory( "foo*.bar" ) is now searchDirectory( "foo.*\\.bar" ) 12 | -------------------------------------------------------------------------------- /CMake/.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | GNUmakefile 3 | -------------------------------------------------------------------------------- /CMake/CPackConfig.cmake: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2012-2015 Stefan Eilemann 2 | 3 | # Info: http://www.itk.org/Wiki/CMake:Component_Install_With_CPack 4 | 5 | mark_as_advanced(LUNCHBOX_PACKAGE_VERSION) 6 | 7 | set(CPACK_PACKAGE_VENDOR "www.eyescale.ch") 8 | set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/doc/Changelog.md) 9 | set(CPACK_RESOURCE_FILE_README ${PROJECT_SOURCE_DIR}/README.md) 10 | 11 | set(CPACK_DEBIAN_PACKAGE_DEPENDS 12 | "libstdc++6, libboost-regex-dev, libboost-serialization-dev, libavahi-compat-libdnssd1, libhwloc-dev, libturbojpeg") 13 | 14 | set(CPACK_MACPORTS_CATEGORY devel) 15 | set(CPACK_MACPORTS_DEPENDS boost) 16 | 17 | include(CommonCPack) 18 | include(OSSCPack) 19 | -------------------------------------------------------------------------------- /CMake/Lunchbox.in.spec: -------------------------------------------------------------------------------- 1 | Name: @PROJECT_NAME@ 2 | Version: @VERSION@ 3 | Release: 1%{?dist} 4 | Summary: @CPACK_PACKAGE_DESCRIPTION_SUMMARY@ 5 | 6 | Group: Development/Libraries 7 | License: @_package_license@ 8 | URL: http://www.equalizergraphics.com/ 9 | Source0: http://www.equalizergraphics.com/downloads/@PROJECT_NAME@-%{version}.tar.gz 10 | #Patch0: @PROJECT_NAME@-@VERSION@-build-fix.patch 11 | BuildRequires: cmake boost-devel 12 | 13 | %description 14 | Lunchbox is a C++ toolkit library for multi-threaded programming. 15 | 16 | %package devel 17 | Summary: Development files for @PROJECT_NAME@ 18 | Group: Development/Libraries 19 | Requires: %{name} = %{version}-%{release} 20 | 21 | %description devel 22 | Development files for the @PROJECT_NAME@. 23 | 24 | %prep 25 | %setup -q 26 | %patch0 -p1 -b .build-fix 27 | 28 | %build 29 | %cmake 30 | 31 | make %{?_smp_mflags} 32 | 33 | 34 | %install 35 | make install DESTDIR=%{buildroot} 36 | mv %{buildroot}%{_datadir}/%{name}/doc _tmpdoc/ 37 | 38 | 39 | %post -p /sbin/ldconfig 40 | 41 | 42 | %postun -p /sbin/ldconfig 43 | 44 | 45 | %files 46 | %doc _tmpdoc/* 47 | %{_bindir}/* 48 | %{_libdir}/lib*.so.* 49 | %{_datadir}/%{name} 50 | 51 | %files devel 52 | %{_includedir}/* 53 | %{_libdir}/lib*.so 54 | %{_libdir}/pkgconfig/*.pc 55 | 56 | %changelog 57 | * Mon Sep 19 2011 Richard Shaw - 1.0.1-1 58 | - Initial Release 59 | -------------------------------------------------------------------------------- /CMake/Lunchbox.spec: -------------------------------------------------------------------------------- 1 | Name: Lunchbox 2 | Version: 3 | Release: 1%{?dist} 4 | Summary: Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs. 5 | 6 | Group: Development/Libraries 7 | License: LGPL 8 | URL: http://www.equalizergraphics.com/ 9 | Source0: http://www.equalizergraphics.com/downloads/Lunchbox-%{version}.tar.gz 10 | #Patch0: Lunchbox--build-fix.patch 11 | BuildRequires: cmake boost-devel 12 | 13 | %description 14 | Lunchbox is a C++ toolkit library for multi-threaded programming. 15 | 16 | %package devel 17 | Summary: Development files for Lunchbox 18 | Group: Development/Libraries 19 | Requires: %{name} = %{version}-%{release} 20 | 21 | %description devel 22 | Development files for the Lunchbox. 23 | 24 | %prep 25 | %setup -q 26 | %patch0 -p1 -b .build-fix 27 | 28 | %build 29 | %cmake 30 | 31 | make %{?_smp_mflags} 32 | 33 | 34 | %install 35 | make install DESTDIR=%{buildroot} 36 | mv %{buildroot}%{_datadir}/%{name}/doc _tmpdoc/ 37 | 38 | 39 | %post -p /sbin/ldconfig 40 | 41 | 42 | %postun -p /sbin/ldconfig 43 | 44 | 45 | %files 46 | %doc _tmpdoc/* 47 | %{_bindir}/* 48 | %{_libdir}/lib*.so.* 49 | %{_datadir}/%{name} 50 | 51 | %files devel 52 | %{_includedir}/* 53 | %{_libdir}/lib*.so 54 | %{_libdir}/pkgconfig/*.pc 55 | 56 | %changelog 57 | * Mon Sep 19 2011 Richard Shaw - 1.0.1-1 58 | - Initial Release 59 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (c) 2012-2017 Stefan Eilemann 3 | 4 | cmake_minimum_required(VERSION 3.1 FATAL_ERROR) 5 | project(Lunchbox VERSION 1.17.0) 6 | set(Lunchbox_VERSION_ABI 10) 7 | 8 | list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMake 9 | ${CMAKE_SOURCE_DIR}/CMake/common) 10 | if(NOT EXISTS ${CMAKE_SOURCE_DIR}/CMake/common/Common.cmake) 11 | message(FATAL_ERROR "CMake/common missing, run: git submodule update --init") 12 | endif() 13 | 14 | option(LUNCHBOX_BUILD_V2_API 15 | "Enable for pure 2.0 API (breaks compatibility with 1.x API)" OFF) 16 | 17 | set(DPUT_HOST "ppa:eilemann/equalizer-dev") 18 | 19 | set(LUNCHBOX_DESCRIPTION "Multi-threaded C++ toolbox library for all application developers creating high-performance multi-threaded programs.") 20 | set(LUNCHBOX_MAINTAINER "Stefan Eilemann ") 21 | set(LUNCHBOX_LICENSE LGPL) 22 | set(LUNCHBOX_DEB_DEPENDS libboost-filesystem-dev libboost-regex-dev 23 | libboost-serialization-dev libboost-system-dev libboost-test-dev 24 | libhwloc-dev avahi-daemon libavahi-client-dev) 25 | set(LUNCHBOX_PORT_DEPENDS boost libmemcached memcached) 26 | set(COMMON_PROJECT_DOMAIN ch.eyescale) 27 | 28 | include(Common) 29 | 30 | if(LUNCHBOX_BUILD_V2_API) 31 | list(APPEND COMMON_FIND_PACKAGE_DEFINES LUNCHBOX_USE_V2_API) 32 | else() 33 | list(APPEND COMMON_FIND_PACKAGE_DEFINES LUNCHBOX_USE_V1_API) 34 | endif() 35 | 36 | common_find_package(Boost REQUIRED COMPONENTS 37 | filesystem regex serialization system unit_test_framework) 38 | common_find_package(hwloc) 39 | common_find_package(Servus REQUIRED) 40 | common_find_package_post() 41 | 42 | set(LUNCHBOX_DEPENDENT_LIBRARIES Boost) 43 | if(NOT LUNCHBOX_BUILD_V2_API) 44 | list(APPEND LUNCHBOX_DEPENDENT_LIBRARIES Servus) 45 | endif() 46 | 47 | add_definitions("-DCMAKE_INSTALL_PREFIX=${CMAKE_INSTALL_PREFIX}") 48 | 49 | if(MSVC) 50 | add_definitions("-DHAVE_STRUCT_TIMESPEC") 51 | endif() 52 | 53 | include(pthreads/CMakeLists.txt) 54 | 55 | add_subdirectory(lunchbox) 56 | add_subdirectory(tests) 57 | add_subdirectory(doc) 58 | 59 | set(DOXYGEN_MAINPAGE_MD README.md) 60 | set(DOXYGEN_EXTRA_INPUT ${PROJECT_SOURCE_DIR}/README.md) 61 | include(DoxygenRule) # must be after all targets 62 | include(CPackConfig) 63 | 64 | set(CTEST_CUSTOM_WARNING_EXCEPTION ${CTEST_CUSTOM_WARNING_EXCEPTION} 65 | # http://public.kitware.com/Bug/view.php?id=10179 66 | "ld: warning: duplicate dylib") 67 | include(CTest) 68 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | LunchBox - a cross-platform C++ library for building multithreaded applications. 2 | 3 | LunchBox is licensed under the LGPL, unless noted otherwise, e.g., for external dependencies. See file LGPL.txt for the full license. External dependencies are either LGPL or BSD-licensed. See file ACKNOWLEDGEMENTS.txt and AUTHORS.txt for further details. 4 | 5 | Copyright (C) 2005-2015, Eyescale Software GmbH and AUTHORS 6 | 7 | This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. 8 | 9 | This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 10 | 11 | You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # Introduction 3 | 4 | Welcome to Lunchbox, a C++ library for multi-threaded programming. Lunchbox was 5 | formerly known as eq::base or co::base, the foundation for the 6 | [Equalizer parallel rendering framework](https://github.com/Eyescale/Equalizer) 7 | and the [Collage network library](https://github.com/Eyescale/Collage). It is 8 | intended for all application developers creating high-performance multi-threaded 9 | programs. 10 | 11 | The 12 | [API documentation](http://eyescale.github.io/Lunchbox-1.12/index.html) can be 13 | found on [eyescale.github.io](http://eyescale.github.io/). As with any open 14 | source project, the available source code, in particular the 15 | [unit tests](https://github.com/Eyescale/Lunchbox/tree/1.12/tests) provide a 16 | reference for developing applications. 17 | 18 | Technical questions can be posted to the Equalizer 19 | [Developer Mailing List](http://www.equalizergraphics.com/cgi-bin/mailman/listinfo/eq-dev), 20 | or directly to 21 | [info@equalizergraphics.com](mailto:info@equalizergraphics.com?subject=Lunchbox%20question). 22 | 23 | Commercial support, custom software development and porting services are 24 | available from [Eyescale](http://www.eyescale.ch). Please contact 25 | [info@eyescale.ch](mailto:info@eyescale.ch?subject=Lunchbox%20support) 26 | for further information. 27 | 28 | # Features 29 | 30 | Lunchbox provides the following major features to facilitate the 31 | development and deployment of multi-threaded applications: 32 | * Operating System Abstraction: lunchbox::Atomic, lunchbox::Condition, 33 | lunchbox::DSO, @ref bitops "bit operations", lunchbox::daemonize(), 34 | (lunchbox::Clock, lunchbox::MemoryMap, lunchbox::PerThread, lunchbox::RNG, 35 | lunchbox::Thread) 36 | * High-Performance Threading Primitives: lunchbox::Buffer, lunchbox::LFQueue, 37 | lunchbox::LFVector, lunchbox::Monitor, lunchbox::MTQueue, 38 | lunchbox::RequestHandler, lunchbox::SpinLock, (lunchbox::Lock, 39 | lunchbox::TimedLock) 40 | * Utility classes: lunchbox::Any, lunchbox::Log, lunchbox::Pool, 41 | lunchbox::UnorderedIntervalSet, lunchbox::Future, lunchbox::PersistentMap, 42 | (lunchbox::ScopedMutex) 43 | * Detailed @ref Changelog 44 | 45 | # Building 46 | 47 | Lunchbox is a cross-platform library, designed to run on any modern 48 | operating system, including all Unix variants and the Windows operating 49 | system. It requires a C++11 compiler and uses CMake to create a 50 | platform-specific build environment. The following platforms and build 51 | environments are tested: 52 | 53 | * Linux: Ubuntu 16.04, RHEL 6.8 (Makefile, Ninja) 54 | * Windows: 7 (Visual Studio 2012) 55 | * Mac OS X: 10.9 (Makefile, Ninja) 56 | 57 | Building from source is as simple as: 58 | 59 | git clone --recursive https://github.com/Eyescale/Lunchbox.git 60 | mkdir Lunchbox/build 61 | cd Lunchbox/build 62 | cmake -GNinja -DCLONE_SUBPROJECTS=ON .. 63 | ninja 64 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (c) 2012 Stefan Eilemann 3 | 4 | install(FILES Changelog.md ../AUTHORS.txt ../ACKNOWLEDGEMENTS.txt ../LGPL.txt 5 | ../LICENSE.txt DESTINATION ${COMMON_DOC_DIR} COMPONENT doc) 6 | -------------------------------------------------------------------------------- /lunchbox/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | 2 | # Copyright (c) 2012-2017 Stefan Eilemann 3 | 4 | set(LUNCHBOX_PUBLIC_HEADERS 5 | algorithm.h 6 | any.h 7 | anySerialization.h 8 | array.h 9 | atomic.h 10 | bitOperation.h 11 | buffer.h 12 | buffer.ipp 13 | clock.h 14 | compiler.h 15 | daemon.h 16 | debug.h 17 | dso.h 18 | file.h 19 | fork.h 20 | future.h 21 | futureFunction.h 22 | hash.h 23 | indexIterator.h 24 | init.h 25 | intervalSet.h 26 | intervalSet.ipp 27 | lfQueue.h 28 | lfQueue.ipp 29 | lfVector.h 30 | lfVector.ipp 31 | lfVectorIterator.h 32 | lockable.h 33 | log.h 34 | memoryMap.h 35 | monitor.h 36 | mtQueue.h 37 | mtQueue.ipp 38 | os.h 39 | perThread.h 40 | perThread.ipp 41 | perThreadRef.h 42 | plugin.h 43 | pluginFactory.h 44 | pluginFactory.ipp 45 | pluginRegisterer.h 46 | pool.h 47 | readyFuture.h 48 | refPtr.h 49 | referenced.h 50 | request.h 51 | requestHandler.h 52 | result.h 53 | rng.h 54 | scopedMutex.h 55 | serializable.h 56 | sleep.h 57 | spinLock.h 58 | string.h 59 | term.h 60 | thread.h 61 | threadID.h 62 | threadPool.h 63 | tls.h 64 | types.h 65 | visitorResult.h 66 | ) 67 | if(NOT LUNCHBOX_BUILD_V2_API) 68 | list(APPEND LUNCHBOX_PUBLIC_HEADERS 69 | servus.h 70 | uint128_t.h 71 | uri.h 72 | ) 73 | endif() 74 | 75 | set(LUNCHBOX_HEADERS 76 | detail/threadID.h 77 | time.h 78 | test.h 79 | ) 80 | 81 | set(LUNCHBOX_SOURCES 82 | any.cpp 83 | atomic.cpp 84 | clock.cpp 85 | debug.cpp 86 | dso.cpp 87 | file.cpp 88 | fork.cpp 89 | init.cpp 90 | log.cpp 91 | memoryMap.cpp 92 | os.cpp 93 | referenced.cpp 94 | requestHandler.cpp 95 | rng.cpp 96 | sleep.cpp 97 | spinLock.cpp 98 | term.cpp 99 | thread.cpp 100 | threadID.cpp 101 | threadPool.cpp 102 | tls.cpp 103 | ) 104 | 105 | set(LUNCHBOX_PUBLIC_INCLUDE_DIRECTORIES ${Boost_INCLUDE_DIRS}) 106 | 107 | list(APPEND LUNCHBOX_LINK_LIBRARIES PUBLIC 108 | ${Boost_FILESYSTEM_LIBRARIES} ${Boost_REGEX_LIBRARIES} 109 | ${Boost_SERIALIZATION_LIBRARIES} ${Boost_SYSTEM_LIBRARIES} Servus) 110 | 111 | if(COMMON_LIBRARY_TYPE MATCHES "SHARED") 112 | list(APPEND LUNCHBOX_LINK_LIBRARIES ${PTHREAD_LIBRARIES}) 113 | endif() 114 | 115 | list(APPEND LUNCHBOX_LINK_LIBRARIES PRIVATE) 116 | if(WIN32) 117 | list(APPEND LUNCHBOX_LINK_LIBRARIES ws2_32 mswsock imagehlp) 118 | endif(WIN32) 119 | if(LINUX) 120 | list(APPEND LUNCHBOX_LINK_LIBRARIES dl rt) 121 | endif() 122 | if(HWLOC_FOUND) 123 | list(APPEND LUNCHBOX_LINK_LIBRARIES ${hwloc_LIBRARIES}) 124 | endif() 125 | if(DNSSD_FOUND) 126 | list(APPEND LUNCHBOX_LINK_LIBRARIES ${DNSSD_LIBRARIES}) 127 | endif() 128 | if(AVAHI-CLIENT_FOUND) 129 | list(APPEND LUNCHBOX_LINK_LIBRARIES ${avahi-client_LIBRARIES}) 130 | endif() 131 | if(MPI_FOUND) 132 | list(APPEND LUNCHBOX_LINK_LIBRARIES ${MPI_LIBRARIES}) 133 | endif() 134 | 135 | common_library(Lunchbox) 136 | install_files(include/lunchbox FILES test.h COMPONENT dev) 137 | -------------------------------------------------------------------------------- /lunchbox/algorithm.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2017, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_ALGORITHM_H 19 | #define LUNCHBOX_ALGORITHM_H 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #ifdef LB_GCC_4_4_OR_LATER 26 | #include 27 | #endif 28 | 29 | namespace lunchbox 30 | { 31 | /** std::sort using parallel sorting where available @version 1.9.1 */ 32 | #ifdef LB_USE_STD_PARALLEL 33 | using std::__parallel::sort; 34 | #else 35 | using std::sort; 36 | #endif 37 | 38 | /** Find the element in the given vector. @version 1.0 */ 39 | template 40 | typename std::vector::iterator find(std::vector& container, 41 | const T& element) 42 | { 43 | return std::find(container.begin(), container.end(), element); 44 | } 45 | 46 | /** Find the element in the given vector. @version 1.0 */ 47 | template 48 | typename std::vector::const_iterator find(const std::vector& container, 49 | const T& element) 50 | { 51 | return std::find(container.begin(), container.end(), element); 52 | } 53 | 54 | /** Find the element matching the predicate @version 1.0 */ 55 | template 56 | typename std::vector::iterator find_if(std::vector& container, 57 | const P& predicate) 58 | { 59 | return std::find_if(container.begin(), container.end(), predicate); 60 | } 61 | 62 | /** Find the element matching the predicate @version 1.0 */ 63 | template 64 | typename std::vector::const_iterator find_if(std::vector& container, 65 | const P& predicate) 66 | { 67 | return std::find_if(container.begin(), container.end(), predicate); 68 | } 69 | 70 | /** Uniquely sort and eliminate duplicates in a container. @version 1.9.1 */ 71 | template 72 | void usort(C& c) 73 | { 74 | std::sort(c.begin(), c.end()); 75 | c.erase(std::unique(c.begin(), c.end()), c.end()); 76 | } 77 | } 78 | 79 | #endif // LUNCHBOX_ALGORITHM_H 80 | -------------------------------------------------------------------------------- /lunchbox/any.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012, Daniel Nachbaur 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 3.0 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "any.h" 19 | 20 | #include 21 | 22 | #ifdef WIN32 23 | #define snprintf _snprintf_s 24 | #endif 25 | 26 | namespace lunchbox 27 | { 28 | Any::Any() 29 | : content() 30 | { 31 | } 32 | 33 | Any::Any(const Any& other) 34 | : content(other.content ? other.content->clone() : 0) 35 | { 36 | } 37 | 38 | Any::~Any() 39 | { 40 | } 41 | 42 | Any& Any::swap(Any& rhs) 43 | { 44 | std::swap(content, rhs.content); 45 | return *this; 46 | } 47 | 48 | Any& Any::operator=(Any rhs) 49 | { 50 | rhs.swap(*this); 51 | return *this; 52 | } 53 | 54 | bool Any::empty() const 55 | { 56 | return !content; 57 | } 58 | 59 | const std::type_info& Any::type() const 60 | { 61 | return content ? content->type() : typeid(void); 62 | } 63 | 64 | bool Any::operator==(const Any& rhs) const 65 | { 66 | if ((this == &rhs) || (empty() && rhs.empty())) 67 | return true; 68 | 69 | if (empty() != rhs.empty() || type() != rhs.type()) 70 | return false; 71 | 72 | return *content == *rhs.content; 73 | } 74 | 75 | bad_any_cast::bad_any_cast(const std::string& from, const std::string& to) 76 | { 77 | snprintf(data, 256, 78 | "boost::bad_any_cast: failed conversion from %s to %s\n", 79 | from.c_str(), to.c_str()); 80 | data[255] = 0; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /lunchbox/anySerialization.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012, Daniel Nachbaur 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 3.0 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_ANYSERIALIZATION_H 19 | #define LUNCHBOX_ANYSERIALIZATION_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | 31 | /** 32 | * Declares the given class to be serializable within a lunchbox::Any. 33 | * User is supposed to use this macro on global scope and in the compilation 34 | * unit where this class is to be serialized. 35 | */ 36 | #define SERIALIZABLEANY(CLASS) BOOST_CLASS_EXPORT(lunchbox::Any::holder) 37 | 38 | namespace lunchbox 39 | { 40 | /** List of supported POD types for lunchbox::Any serialization. */ 41 | typedef boost::mpl::list 44 | podTypes; 45 | 46 | /** @cond IGNORE */ 47 | /** 48 | * @internal 49 | * Utility struct for registering types for lunchbox::Any from a type list. 50 | */ 51 | template 52 | struct registerWrapper 53 | { 54 | explicit registerWrapper(Archive& ar) 55 | : ar_(ar) 56 | { 57 | } 58 | Archive& ar_; 59 | 60 | template 61 | void operator()(T) 62 | { 63 | ar_.template register_type >(); 64 | } 65 | }; 66 | /** @endcond */ 67 | 68 | /** 69 | * Registers the types from the given type list for serializing it inside a 70 | * lunchbox::Any through the given archive. 71 | */ 72 | template 73 | void registerTypelist(Archive& ar) 74 | { 75 | boost::mpl::for_each(registerWrapper(ar)); 76 | } 77 | 78 | /** 79 | * Serializes the given object which can be a lunchbox::Any through the given 80 | * archive type to/from the given stream. 81 | */ 82 | template 83 | void serializeAny(Object& object, Stream& stream) 84 | { 85 | Archive ar(stream); 86 | registerTypelist(ar); 87 | ar& object; 88 | } 89 | 90 | /** 91 | * Saves the given object which can be a lunchbox::Any through the given archive 92 | * type to/from the given stream. 93 | */ 94 | template 95 | void saveAny(Object& object, Stream& stream) 96 | { 97 | Archive ar(stream); 98 | registerTypelist(ar); 99 | ar << object; 100 | } 101 | 102 | /** 103 | * Loads the given object which can be a lunchbox::Any through the given archive 104 | * type to/from the given stream. 105 | */ 106 | template 107 | void loadAny(Object& object, Stream& stream) 108 | { 109 | Archive ar(stream); 110 | registerTypelist(ar); 111 | ar >> object; 112 | } 113 | } 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /lunchbox/array.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012-2014, Stefan Eilemann 3 | * 4 | * This file is part of Lunchbox 5 | * 6 | * This library is free software; you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License version 2.1 as published 8 | * by the Free Software Foundation. 9 | * 10 | * This library is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | * details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this library; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef LUNCHBOX_ARRAY_H 21 | #define LUNCHBOX_ARRAY_H 22 | 23 | #include 24 | #include 25 | 26 | namespace lunchbox 27 | { 28 | /** A wrapper for C arrays without any memory management. */ 29 | template 30 | class Array 31 | { 32 | public: 33 | /** Create a new array wrapper for the given data. @version 1.9.1 */ 34 | Array(T* data_, const size_t num_) 35 | : data(data_) 36 | , num(num_) 37 | { 38 | } 39 | 40 | /** @return the number of bytes stored in the pointer. @version 1.9.1 */ 41 | size_t getNumBytes() const { return num * sizeof(T); } 42 | T* data; //!< The data 43 | size_t num; //!< The number of elements in the data 44 | }; 45 | 46 | template <> 47 | inline size_t Array::getNumBytes() const 48 | { 49 | return num; 50 | } 51 | template <> 52 | inline size_t Array::getNumBytes() const 53 | { 54 | return num; 55 | } 56 | 57 | /** Pretty-print all members of the array. @version 1.9.1 */ 58 | template 59 | inline std::ostream& operator<<(std::ostream& os, const Array& array) 60 | { 61 | return os << lunchbox::format(array.data, array.num); 62 | } 63 | } 64 | #endif // LUNCHBOX_ARRAY_H 65 | -------------------------------------------------------------------------------- /lunchbox/atomic.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2011, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "atomic.h" 19 | #include "os.h" 20 | 21 | namespace lunchbox 22 | { 23 | #ifdef _MSC_VER 24 | template <> 25 | int32_t Atomic::getAndAdd(int32_t& value, const int32_t increment) 26 | { 27 | return InterlockedExchangeAdd((long*)(&value), increment); 28 | } 29 | 30 | template <> 31 | int32_t Atomic::getAndSub(int32_t& value, const int32_t increment) 32 | { 33 | return InterlockedExchangeAdd((long*)(&value), -increment); 34 | } 35 | 36 | template <> 37 | int32_t Atomic::incAndGet(int32_t& value) 38 | { 39 | return InterlockedIncrement((long*)(&value)); 40 | } 41 | 42 | template <> 43 | int32_t Atomic::decAndGet(int32_t& value) 44 | { 45 | return InterlockedDecrement((long*)(&value)); 46 | } 47 | 48 | template <> 49 | bool Atomic::compareAndSwap(int32_t* value, const int32_t expected, 50 | const int32_t newValue) 51 | { 52 | return InterlockedCompareExchange((long*)(value), newValue, expected) == 53 | expected; 54 | } 55 | 56 | template <> 57 | bool Atomic::compareAndSwap(void** value, void* const expected, 58 | void* const newValue) 59 | { 60 | return InterlockedCompareExchangePointer(value, newValue, expected) == 61 | expected; 62 | } 63 | 64 | #ifdef _WIN64 65 | 66 | template <> 67 | ssize_t Atomic::getAndAdd(ssize_t& value, const ssize_t increment) 68 | { 69 | return InterlockedExchangeAdd64(&value, increment); 70 | } 71 | 72 | template <> 73 | ssize_t Atomic::getAndSub(ssize_t& value, const ssize_t increment) 74 | { 75 | return InterlockedExchangeAdd64(&value, -increment); 76 | } 77 | 78 | template <> 79 | ssize_t Atomic::incAndGet(ssize_t& value) 80 | { 81 | return InterlockedIncrement64(&value); 82 | } 83 | 84 | template <> 85 | ssize_t Atomic::decAndGet(ssize_t& value) 86 | { 87 | return InterlockedDecrement64(&value); 88 | } 89 | 90 | template <> 91 | bool Atomic::compareAndSwap(ssize_t* value, const ssize_t expected, 92 | const ssize_t newValue) 93 | { 94 | return InterlockedCompareExchange64(value, newValue, expected) == expected; 95 | } 96 | 97 | #else // _WIN64 98 | 99 | template <> 100 | ssize_t Atomic::getAndAdd(ssize_t& value, const ssize_t increment) 101 | { 102 | return InterlockedExchangeAdd(&value, increment); 103 | } 104 | 105 | template <> 106 | ssize_t Atomic::getAndSub(ssize_t& value, const ssize_t increment) 107 | { 108 | return InterlockedExchangeAdd(&value, -increment); 109 | } 110 | 111 | template <> 112 | ssize_t Atomic::incAndGet(ssize_t& value) 113 | { 114 | return InterlockedIncrement(&value); 115 | } 116 | 117 | template <> 118 | ssize_t Atomic::decAndGet(ssize_t& value) 119 | { 120 | return InterlockedDecrement(&value); 121 | } 122 | 123 | template <> 124 | bool Atomic::compareAndSwap(ssize_t* value, const ssize_t expected, 125 | const ssize_t newValue) 126 | { 127 | return InterlockedCompareExchange(value, newValue, expected) == expected; 128 | } 129 | 130 | #endif // else _WIN64 131 | #endif // _MSC_VER 132 | } 133 | -------------------------------------------------------------------------------- /lunchbox/buffer.ipp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2007-2016, Stefan Eilemann 3 | * Daniel Nachbaur 4 | * 5 | * This library is free software; you can redistribute it and/or modify it under 6 | * the terms of the GNU Lesser General Public License version 2.1 as published 7 | * by the Free Software Foundation. 8 | * 9 | * This library is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | namespace lunchbox 20 | { 21 | template 22 | Buffer::Buffer(const Buffer& from) 23 | : _data(nullptr) 24 | , _size(0) 25 | , _maxSize(0) 26 | { 27 | if (!from.isEmpty()) 28 | *this = from; 29 | } 30 | 31 | template 32 | Buffer::Buffer(Buffer&& from) 33 | : _data(std::move(from._data)) 34 | , _size(from._size) 35 | , _maxSize(from._maxSize) 36 | { 37 | from._data = nullptr; 38 | from._size = 0; 39 | from._maxSize = 0; 40 | } 41 | 42 | template 43 | T* Buffer::pack() 44 | { 45 | if (_maxSize != _size) 46 | { 47 | _data = static_cast(realloc(_data, _size * sizeof(T))); 48 | _maxSize = _size; 49 | } 50 | return _data; 51 | } 52 | 53 | template 54 | Buffer& Buffer::operator=(const Buffer& from) 55 | { 56 | if (this != &from) 57 | replace(from); 58 | return *this; 59 | } 60 | 61 | template 62 | Buffer& Buffer::operator=(Buffer&& from) 63 | { 64 | if (this == &from) 65 | return *this; 66 | std::swap(_data, from._data); 67 | std::swap(_size, from._size); 68 | std::swap(_maxSize, from._maxSize); 69 | return *this; 70 | } 71 | 72 | template 73 | T* Buffer::resize(const uint64_t newSize) 74 | { 75 | _size = newSize; 76 | if (newSize <= _maxSize) 77 | return _data; 78 | 79 | // avoid excessive reallocs 80 | const uint64_t nElems = newSize + (newSize >> 3); 81 | const uint64_t nBytes = nElems * sizeof(T); 82 | _data = static_cast(realloc(_data, nBytes)); 83 | _maxSize = nElems; 84 | return _data; 85 | } 86 | 87 | template 88 | void Buffer::grow(const uint64_t newSize) 89 | { 90 | if (newSize > _size) 91 | resize(newSize); 92 | } 93 | 94 | template 95 | T* Buffer::reserve(const uint64_t newSize) 96 | { 97 | if (newSize <= _maxSize) 98 | return _data; 99 | 100 | _data = static_cast(realloc(_data, newSize * sizeof(T))); 101 | _maxSize = newSize; 102 | return _data; 103 | } 104 | 105 | template 106 | T* Buffer::reset(const uint64_t newSize) 107 | { 108 | reserve(newSize); 109 | setSize(newSize); 110 | return _data; 111 | } 112 | 113 | template 114 | void Buffer::append(const T* data, const uint64_t size) 115 | { 116 | LBASSERT(data); 117 | LBASSERT(size); 118 | 119 | const uint64_t oldSize = _size; 120 | resize(oldSize + size); 121 | memcpy(_data + oldSize, data, size * sizeof(T)); 122 | } 123 | 124 | template 125 | void Buffer::append(const T& element) 126 | { 127 | append(&element, 1); 128 | } 129 | 130 | template 131 | void Buffer::replace(const void* data, const uint64_t size) 132 | { 133 | LBASSERT(data); 134 | LBASSERT(size); 135 | 136 | reserve(size); 137 | memcpy(_data, data, size * sizeof(T)); 138 | _size = size; 139 | } 140 | 141 | template 142 | void Buffer::swap(Buffer& buffer) 143 | { 144 | T* tmpData = buffer._data; 145 | const uint64_t tmpSize = buffer._size; 146 | const uint64_t tmpMaxSize = buffer._maxSize; 147 | 148 | buffer._data = _data; 149 | buffer._size = _size; 150 | buffer._maxSize = _maxSize; 151 | 152 | _data = tmpData; 153 | _size = tmpSize; 154 | _maxSize = tmpMaxSize; 155 | } 156 | 157 | template 158 | bool Buffer::setSize(const uint64_t size) 159 | { 160 | LBASSERT(size <= _maxSize); 161 | if (size > _maxSize) 162 | return false; 163 | 164 | _size = size; 165 | return true; 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /lunchbox/clock.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2005-2014, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_CLOCK_H 19 | #define LUNCHBOX_CLOCK_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace lunchbox 26 | { 27 | namespace detail 28 | { 29 | class Clock; 30 | } 31 | 32 | /** A class for time measurements. */ 33 | class Clock 34 | { 35 | public: 36 | /** Construct a new clock. @version 1.0 */ 37 | LUNCHBOX_API Clock(); 38 | 39 | /** Copy-construct a new clock with the same start time . @version 1.0 */ 40 | LUNCHBOX_API Clock(const Clock& from); 41 | 42 | /** Destroy the clock. @version 1.0 */ 43 | LUNCHBOX_API ~Clock(); 44 | 45 | /** Assignment operator. @version 1.7.2 */ 46 | LUNCHBOX_API Clock& operator=(const Clock& ref); 47 | 48 | /** 49 | * Reset the base time of the clock to the current time. 50 | * @version 1.0 51 | */ 52 | LUNCHBOX_API void reset(); 53 | 54 | /** Set the current time of the clock. @version 1.0 */ 55 | LUNCHBOX_API void set(const int64_t time); 56 | 57 | /** 58 | * @return the elapsed time in milliseconds since the last clock reset. 59 | * @version 1.0 60 | */ 61 | LUNCHBOX_API float getTimef() const; 62 | 63 | /** 64 | * @return the elapsed time in milliseconds since the last clock reset 65 | * and atomically reset the clock. 66 | * @version 1.0 67 | */ 68 | LUNCHBOX_API float resetTimef(); 69 | 70 | /** 71 | * @return the elapsed time in milliseconds since the last clock reset. 72 | * @version 1.0 73 | */ 74 | LUNCHBOX_API int64_t getTime64() const; 75 | 76 | /** 77 | * @return the elapsed time in milliseconds since the last clock reset. 78 | * @version 1.0 79 | */ 80 | LUNCHBOX_API double getTimed() const; 81 | 82 | private: 83 | detail::Clock* const _impl; 84 | }; 85 | } 86 | #endif // LUNCHBOX_CLOCK_H 87 | -------------------------------------------------------------------------------- /lunchbox/compiler.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #pragma once 19 | 20 | #ifdef __cplusplus 21 | #include 22 | #endif 23 | // align macros 24 | #ifdef _MSC_VER 25 | #define LB_ALIGN8(var) __declspec(align(8)) var; 26 | #define LB_ALIGN16(var) __declspec(align(16)) var; 27 | #elif defined(__GNUC__) 28 | #define LB_ALIGN8(var) var __attribute__((aligned(8))); 29 | #define LB_ALIGN16(var) var __attribute__((aligned(16))); 30 | #define LB_UNUSED __attribute__((unused)) 31 | #define LB_LIKELY(x) __builtin_expect((x), 1) 32 | #define LB_UNLIKELY(x) __builtin_expect((x), 0) 33 | #ifdef WARN_DEPRECATED // Set CMake option COMMON_WARN_DEPRECATED 34 | #define LB_DEPRECATED __attribute__((deprecated)) 35 | #endif 36 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 0))) 37 | #define LB_GCC_4_0_OR_LATER 38 | #endif 39 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 1))) 40 | #define LB_GCC_4_1_OR_LATER 41 | #endif 42 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))) 43 | #define LB_GCC_4_2_OR_LATER 44 | #endif 45 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3))) 46 | #define LB_GCC_4_3_OR_LATER 47 | #endif 48 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 4))) 49 | #define LB_GCC_4_4_OR_LATER 50 | #endif 51 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5))) 52 | #define LB_GCC_4_5_OR_LATER 53 | #endif 54 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 6))) 55 | #define LB_GCC_4_6_OR_LATER 56 | #endif 57 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 7))) 58 | #define LB_GCC_4_7_OR_LATER 59 | #endif 60 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8))) 61 | #define LB_GCC_4_8_OR_LATER 62 | #endif 63 | #if ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 9))) 64 | #define LB_GCC_4_9_OR_LATER 65 | #endif 66 | #if ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 3))) 67 | #define LB_GCC_4_3_OR_OLDER 68 | #endif 69 | 70 | #if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 2)) 71 | #define LB_GCC_4_2 72 | #endif 73 | #if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 3)) 74 | #define LB_GCC_4_3 75 | #endif 76 | #if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 4)) 77 | #define LB_GCC_4_4 78 | #endif 79 | #if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 5)) 80 | #define LB_GCC_4_5 81 | #endif 82 | #if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 6)) 83 | #define LB_GCC_4_6 84 | #endif 85 | #if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 7)) 86 | #define LB_GCC_4_7 87 | #endif 88 | #if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 8)) 89 | #define LB_GCC_4_8 90 | #endif 91 | #if ((__GNUC__ == 4) && (__GNUC_MINOR__ == 9)) 92 | #define LB_GCC_4_9 93 | #endif 94 | #else 95 | #warning Unknown compiler, taking guesses 96 | #define LB_ALIGN8(var) var __attribute__((aligned(8))); 97 | #define LB_ALIGN16(var) var __attribute__((aligned(16))); 98 | #endif // GCC 99 | 100 | #ifndef LB_UNUSED 101 | #define LB_UNUSED 102 | #endif 103 | #ifndef LB_LIKELY 104 | #define LB_LIKELY(x) x 105 | #define LB_UNLIKELY(x) x 106 | #endif 107 | #ifndef LB_PUSH_DEPRECATED 108 | #ifdef LB_DEPRECATED 109 | #define LB_PUSH_DEPRECATED \ 110 | _Pragma("clang diagnostic push") \ 111 | _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") \ 112 | _Pragma("GCC diagnostic push") _Pragma( \ 113 | "GCC diagnostic ignored \"-Wdeprecated-declarations\"") 114 | 115 | #define LB_POP_DEPRECATED \ 116 | _Pragma("clang diagnostic pop") _Pragma("GCC diagnostic pop") 117 | #else 118 | #define LB_DEPRECATED 119 | #define LB_PUSH_DEPRECATED 120 | #define LB_POP_DEPRECATED 121 | #endif 122 | #endif 123 | -------------------------------------------------------------------------------- /lunchbox/daemon.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_DAEMON_H 19 | #define LUNCHBOX_DAEMON_H 20 | 21 | #include 22 | #ifndef _MSC_VER 23 | #include 24 | #endif 25 | 26 | namespace lunchbox 27 | { 28 | /** 29 | * Turn the calling process into a daemon. 30 | * 31 | * Only the forked child process returns from this function. A new session is 32 | * created and the standard file descriptors are closed. The current working 33 | * directory is unchanged, and the Log output is not redirected to a file. 34 | * 35 | * @return true on success, false on error. 36 | * @version 1.5.1 37 | */ 38 | inline bool daemonize() 39 | { 40 | #ifdef _MSC_VER 41 | LBABORT("Not implemented"); 42 | return false; 43 | #else 44 | const pid_t pid = fork(); 45 | if (pid < 0) 46 | { 47 | LBWARN << "Fork failed: " << sysError << std::endl; 48 | return false; 49 | } 50 | 51 | if (pid > 0) // parent 52 | ::exit(EXIT_SUCCESS); 53 | 54 | const pid_t sid = setsid(); // child, create new seesion 55 | if (sid < 0) 56 | { 57 | LBWARN << "setsid failed: " << sysError << std::endl; 58 | return false; 59 | } 60 | 61 | // Close the standard file 62 | ::close(STDIN_FILENO); 63 | ::close(STDOUT_FILENO); 64 | ::close(STDERR_FILENO); 65 | return true; 66 | #endif 67 | } 68 | } 69 | 70 | #endif // LUNCHBOX_DAEMON_H 71 | -------------------------------------------------------------------------------- /lunchbox/detail/threadID.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2014, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_DETAIL_THREADID_H 19 | #define LUNCHBOX_DETAIL_THREADID_H 20 | 21 | namespace lunchbox 22 | { 23 | namespace detail 24 | { 25 | class ThreadID 26 | { 27 | public: 28 | pthread_t pthread; 29 | }; 30 | } 31 | } 32 | #endif 33 | -------------------------------------------------------------------------------- /lunchbox/dso.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2009, Cedric Stalder 3 | * 2009-2014, Stefan Eilemann 4 | * 5 | * This library is free software; you can redistribute it and/or modify it under 6 | * the terms of the GNU Lesser General Public License version 2.1 as published 7 | * by the Free Software Foundation. 8 | * 9 | * This library is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | #include "dso.h" 20 | 21 | #include "debug.h" 22 | #include "log.h" 23 | #include "os.h" 24 | 25 | #ifdef _WIN32 //_MSC_VER 26 | #define LB_DL_ERROR sysError 27 | #else 28 | #include 29 | #define LB_DL_ERROR dlerror() 30 | #endif 31 | 32 | namespace lunchbox 33 | { 34 | namespace detail 35 | { 36 | class DSO 37 | { 38 | public: 39 | DSO() 40 | : dso(0) 41 | { 42 | } 43 | 44 | #ifdef _WIN32 //_MSC_VER 45 | HMODULE dso; 46 | #else 47 | void* dso; 48 | #endif 49 | }; 50 | } 51 | 52 | DSO::DSO() 53 | : _impl(new detail::DSO) 54 | { 55 | } 56 | 57 | DSO::DSO(const std::string& name) 58 | : _impl(new detail::DSO) 59 | { 60 | open(name); 61 | } 62 | 63 | DSO::~DSO() 64 | { 65 | close(); 66 | delete _impl; 67 | } 68 | 69 | bool DSO::open(const std::string& fileName) 70 | { 71 | if (_impl->dso) 72 | { 73 | LBWARN << "DSO already open, close it first" << std::endl; 74 | return false; 75 | } 76 | 77 | if (fileName.empty()) 78 | { 79 | #ifdef _WIN32 //_MSC_VER 80 | _impl->dso = GetModuleHandle(0); 81 | LBASSERT(_impl->dso); 82 | #else 83 | _impl->dso = RTLD_DEFAULT; 84 | #endif 85 | } 86 | else 87 | { 88 | #ifdef _WIN32 //_MSC_VER 89 | _impl->dso = LoadLibrary(fileName.c_str()); 90 | #elif defined(RTLD_LOCAL) 91 | _impl->dso = dlopen(fileName.c_str(), RTLD_LAZY | RTLD_LOCAL); 92 | #else 93 | _impl->dso = dlopen(fileName.c_str(), RTLD_LAZY); 94 | #endif 95 | if (!_impl->dso) 96 | { 97 | LBDEBUG << "Can't open library " << fileName << ": " << LB_DL_ERROR 98 | << std::endl; 99 | return false; 100 | } 101 | } 102 | 103 | return true; 104 | } 105 | 106 | void DSO::close() 107 | { 108 | if (!_impl->dso) 109 | return; 110 | 111 | #ifdef _WIN32 //_MSC_VER 112 | if (_impl->dso != GetModuleHandle(0)) 113 | FreeLibrary(_impl->dso); 114 | #else 115 | if (_impl->dso != RTLD_DEFAULT) 116 | dlclose(_impl->dso); 117 | #endif 118 | 119 | _impl->dso = 0; 120 | } 121 | 122 | void* DSO::getFunctionPointer(const std::string& name) const 123 | { 124 | if (!_impl->dso) 125 | return 0; 126 | 127 | #ifdef _WIN32 //_MSC_VER 128 | return (void*)GetProcAddress(_impl->dso, name.c_str()); 129 | #else 130 | return dlsym(_impl->dso, name.c_str()); 131 | #endif 132 | } 133 | 134 | bool DSO::isOpen() const 135 | { 136 | return _impl->dso != 0; 137 | } 138 | 139 | bool DSO::operator==(const DSO& rhs) const 140 | { 141 | return _impl->dso == rhs._impl->dso; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /lunchbox/dso.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2009, Cedric Stalder 3 | * 2009-2014, Stefan Eilemann 4 | * 5 | * This library is free software; you can redistribute it and/or modify it under 6 | * the terms of the GNU Lesser General Public License version 2.1 as published 7 | * by the Free Software Foundation. 8 | * 9 | * This library is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | #ifndef LUNCHBOX_DSO_H 20 | #define LUNCHBOX_DSO_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | namespace lunchbox 27 | { 28 | namespace detail 29 | { 30 | class DSO; 31 | } 32 | 33 | /** 34 | * Helper to access dynamic shared objects (DSO) 35 | * 36 | * Example: @include tests/dso.cpp 37 | */ 38 | class DSO : public boost::noncopyable 39 | { 40 | public: 41 | /** Construct a new dynamic shared object. @version 1.0 */ 42 | LUNCHBOX_API DSO(); 43 | 44 | /** Construct and initialize a dynamic shared object. @version 1.7.1 */ 45 | LUNCHBOX_API explicit DSO(const std::string& name); 46 | 47 | /** Destruct this DSO handle. @version 1.0 */ 48 | LUNCHBOX_API ~DSO(); 49 | 50 | /** 51 | * Open a dynamic shared object. 52 | * 53 | * @param fileName The file name of the DSO. 54 | * @return true if the DSO was opened, false upon error. 55 | * @version 1.0 56 | */ 57 | LUNCHBOX_API bool open(const std::string& fileName); 58 | 59 | /** 60 | * Close the DSO, invalidates retrieved function pointers. 61 | * @version 1.0 62 | */ 63 | LUNCHBOX_API void close(); 64 | 65 | /** 66 | * @return a function pointer in the DSO, or 0 if the function is not 67 | * exported by the DSO. 68 | * @version 1.0 69 | */ 70 | LUNCHBOX_API 71 | void* getFunctionPointer(const std::string& functionName) const; 72 | 73 | /** 74 | * @return a typed function pointer in the DSO, or 0 if the function is 75 | * not exported by the DSO. 76 | * @version 1.7.1 77 | */ 78 | template 79 | F getFunctionPointer(const std::string& func) const 80 | { 81 | return (F)(getFunctionPointer(func)); 82 | } 83 | 84 | /** @return true if the DSO is loaded. @version 1.0 */ 85 | LUNCHBOX_API bool isOpen() const; 86 | 87 | /** 88 | * @return true if both instances manage the same shared object. 89 | * @version 1.9.1 90 | */ 91 | LUNCHBOX_API bool operator==(const DSO& rhs) const; 92 | 93 | /** 94 | * @return true if both instances manage different shared objects. 95 | * @version 1.9.1 96 | */ 97 | bool operator!=(const DSO& rhs) const { return !(*this == rhs); } 98 | private: 99 | detail::DSO* const _impl; 100 | }; 101 | } 102 | 103 | #endif // LUNCHBOX_DSO_H 104 | -------------------------------------------------------------------------------- /lunchbox/file.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2009-2015, Cedric Stalder 3 | * Stefan Eilemann 4 | * Daniel Nachbaur 5 | * 6 | * This library is free software; you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License version 2.1 as published 8 | * by the Free Software Foundation. 9 | * 10 | * This library is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | * details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this library; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef LUNCHBOX_FILE_H 21 | #define LUNCHBOX_FILE_H 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | namespace lunchbox 28 | { 29 | /** 30 | * Retrieve a list of files in a directory matching a boost::regex pattern. 31 | * 32 | * @return all file names matching the given pattern in the given directory. 33 | * @version 1.0 34 | * @version 1.7.1 using boost::regex for matching 35 | */ 36 | LUNCHBOX_API Strings searchDirectory(const std::string& directory, 37 | const std::string& pattern); 38 | 39 | /** 40 | * @return the file name part of a path. @version 1.0 41 | */ 42 | LUNCHBOX_API std::string getFilename(const std::string& filename); 43 | 44 | /** 45 | * @return the directory name part of a path. @version 1.0 46 | */ 47 | LUNCHBOX_API std::string getDirname(const std::string& filename); 48 | 49 | /** 50 | * Get the absolute directory of the current executable. 51 | * 52 | * On Mac OS X, this returns the path to the app bundle, i.e., the directory 53 | * where the Foo.app is located, not Foo.app/Contents/MacOS. 54 | * 55 | * @return the absolute directory of the current executable. 56 | * @version 1.11 57 | */ 58 | LUNCHBOX_API std::string getExecutableDir(); 59 | /** @deprecated */ 60 | inline std::string getExecutablePath() 61 | { 62 | return getExecutableDir(); 63 | } 64 | 65 | /** 66 | * @return the absolute directory of the current working directory 67 | * @version 1.14 68 | */ 69 | LUNCHBOX_API std::string getWorkDir(); 70 | 71 | /** 72 | * Get the absolute path to the root directory of the current executable. 73 | * 74 | * On all platforms, this returns the root directory of the 75 | * installation/distribution of the current executable. Can be empty, if 76 | * getExecutableDir() is empty. 77 | * 78 | * On Linux and Mac OS X, this returns the directory one level up of 79 | * getExecutableDir(). 80 | * On Windows, this returns the directory one or two levels up of 81 | * getExecutableDir(), depending if ${BuildType} is in the path. 82 | * 83 | * @return the absolute root directory of the current executable. 84 | * @version 1.12 85 | */ 86 | LUNCHBOX_API std::string getRootDir(); 87 | inline std::string getRootPath() 88 | { 89 | return getRootDir(); 90 | } //!< @deprecated 91 | 92 | /** 93 | * @return the absolute path to the libraries of the current executable. 94 | * @version 1.11 95 | */ 96 | LUNCHBOX_API std::string getLibraryPath(); 97 | 98 | /** 99 | * @return the search paths to libraries of the current executable. 100 | * @version 1.11 101 | */ 102 | LUNCHBOX_API Strings getLibraryPaths(); 103 | 104 | /** Save binary to file. @return true on success, false otherwise. */ 105 | LUNCHBOX_API bool saveBinary(const servus::Serializable& object, 106 | const std::string& filename); 107 | 108 | /** Load from binary file. @return true on success, false otherwise. */ 109 | LUNCHBOX_API bool loadBinary(servus::Serializable& object, 110 | const std::string& filename); 111 | 112 | /** Save ascii (JSON) to file. @return true on success, false otherwise. */ 113 | LUNCHBOX_API bool saveAscii(const servus::Serializable& object, 114 | const std::string& filename); 115 | 116 | /** Load from ascii (JSON) file. @return true on success, false otherwise.*/ 117 | LUNCHBOX_API bool loadAscii(servus::Serializable& object, 118 | const std::string& filename); 119 | } 120 | 121 | #endif // LUNCHBOX_FILE_H 122 | -------------------------------------------------------------------------------- /lunchbox/fork.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2005-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | 23 | namespace lunchbox 24 | { 25 | /** Execute the given command in a new process. @version 1.0 */ 26 | LUNCHBOX_API bool fork(const std::string& command); 27 | } 28 | -------------------------------------------------------------------------------- /lunchbox/futureFunction.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2014, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_FUTUREFUNCTION_H 19 | #define LUNCHBOX_FUTUREFUNCTION_H 20 | 21 | #include 22 | #include // base class 23 | 24 | namespace lunchbox 25 | { 26 | /** 27 | * A Future implementation using a boost::function for fulfilment. 28 | * Not thread safe. 29 | */ 30 | template 31 | class FutureFunction : public FutureImpl 32 | { 33 | public: 34 | typedef boost::function Func; //!< The fulfilling function 35 | 36 | explicit FutureFunction(const Func& func) 37 | : func_(func) 38 | { 39 | } 40 | 41 | protected: 42 | virtual ~FutureFunction() { wait(0); } 43 | T wait(const uint32_t) final 44 | { 45 | if (!func_.empty()) 46 | { 47 | result_ = func_(); 48 | func_.clear(); 49 | } 50 | return result_; 51 | } 52 | 53 | bool isReady() const final { return func_.empty(); } 54 | Func func_; 55 | T result_; 56 | }; 57 | } 58 | #endif // LUNCHBOX_FUTURE_H 59 | -------------------------------------------------------------------------------- /lunchbox/hash.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2005-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_HASH_H 19 | #define LUNCHBOX_HASH_H 20 | 21 | #include 22 | 23 | #include 24 | 25 | namespace lunchbox 26 | { 27 | /** A hash for pointer keys. @version 1.0 */ 28 | template 29 | class PtrHash : public std::unordered_map > 30 | { 31 | }; 32 | 33 | template 34 | struct hashRefPtr 35 | { 36 | size_t operator()(RefPtr key) const 37 | { 38 | return std::hash()(key.get()); 39 | } 40 | }; 41 | 42 | /** A hash for RefPtr keys. @version 1.0 */ 43 | template 44 | class RefPtrHash : public std::unordered_map, T, hashRefPtr > 45 | { 46 | }; 47 | } 48 | #endif // LUNCHBOX_HASH_H 49 | -------------------------------------------------------------------------------- /lunchbox/init.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2008-2016, Stefan Eilemann 3 | * Cedric Stalder 4 | * Daniel Nachbaur 5 | * 6 | * This library is free software; you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License version 2.1 as published 8 | * by the Free Software Foundation. 9 | * 10 | * This library is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | * details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this library; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #include "init.h" 21 | 22 | #include "atomic.h" 23 | #include "file.h" 24 | #include "thread.h" 25 | 26 | #include 27 | #include 28 | #include 29 | 30 | namespace lunchbox 31 | { 32 | namespace 33 | { 34 | static a_int32_t _initialized; 35 | } 36 | 37 | bool init(const int argc, char** argv) 38 | { 39 | for (int i = 1; i < argc; ++i) 40 | { 41 | // verbose options 42 | if (std::string(argv[i]) == "-vv") 43 | Log::level += 2; 44 | else if (std::string(argv[i]) == "-v") 45 | ++Log::level; 46 | else if (std::string(argv[i]) == "--lb-logfile") 47 | { 48 | std::string logfile = getFilename(argv[0]) + ".log"; 49 | if (i + 1 < argc) 50 | logfile = argv[++i]; 51 | Log::setOutput(logfile); 52 | } 53 | } 54 | 55 | if (++_initialized > 1) // not first 56 | return true; 57 | 58 | Log::instance().setThreadName("Main"); 59 | 60 | const time_t now = ::time(0); 61 | #ifdef _WIN32 62 | char* gmtString = ::ctime(&now); 63 | #else 64 | char gmtString[32]; 65 | ::ctime_r(&now, gmtString); 66 | 67 | setenv("AVAHI_COMPAT_NOWARN", "1", 0); // get rid of annoying avahi warning 68 | #endif 69 | 70 | LBDEBUG << "Log level " << Log::getLogLevelString() << " topics " 71 | << Log::topics << " date " << gmtString << std::flush; 72 | return true; 73 | } 74 | 75 | bool exit() 76 | { 77 | if (--_initialized > 0) // not last 78 | return true; 79 | 80 | Log::reset(); 81 | 82 | if (_initialized < 0) 83 | { 84 | LBERROR << "init/exit call mismatch" << std::endl; 85 | _initialized = 0; 86 | return false; 87 | } 88 | return true; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /lunchbox/init.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2008-2016, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_INIT_H 19 | #define LUNCHBOX_INIT_H 20 | 21 | #include 22 | 23 | namespace lunchbox 24 | { 25 | /** 26 | * Initialize the Lunchbox base classes. 27 | * 28 | * exit() should be called independent of the return value of this function. The 29 | * following arguments are parsed: 30 | * * -v[v]: Increase log verbosity 31 | * * --lb-logfile [filename]: redirect log to the given file or to 32 | * ApplicationName.log 33 | * 34 | * @param argc the command line argument count. 35 | * @param argv the command line argument values. 36 | * @return true if the library was successfully initialised, false otherwise 37 | * @version 1.0 38 | */ 39 | LUNCHBOX_API bool init(const int argc, char** argv); 40 | 41 | /** 42 | * De-initialize the Lunchbox base classes. 43 | * 44 | * @return true if the library was successfully de-initialised, false otherwise 45 | * @version 1.0 46 | */ 47 | LUNCHBOX_API bool exit(); 48 | } 49 | #endif // LUNCHBOX_INIT_H 50 | -------------------------------------------------------------------------------- /lunchbox/intervalSet.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2008-2016, Juan Hernando 3 | * Daniel Nachbaur 4 | * 5 | * This library is free software; you can redistribute it and/or modify it under 6 | * the terms of the GNU Lesser General Public License version 2.1 as published 7 | * by the Free Software Foundation. 8 | * 9 | * This library is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | #ifndef LUNCHBOX_INTERVALSET_H 20 | #define LUNCHBOX_INTERVALSET_H 21 | 22 | #include 23 | #include 24 | 25 | namespace lunchbox 26 | { 27 | /** 28 | * A container to store intervals of elements efficently. 29 | * 30 | * The type can be any class or typename which has the semantics of natural 31 | * numbers for addition and comparison operations. Not thread-safe. 32 | * 33 | * Example: @include tests/IntervalSet.cpp 34 | */ 35 | template 36 | class IntervalSet 37 | { 38 | public: 39 | /** Element iterator which points to a current element of type T. */ 40 | class const_iterator; 41 | 42 | /** Construct a new interval set. @version 1.7.1 */ 43 | IntervalSet(); 44 | 45 | /** Insert a new element. @version 1.7.1 */ 46 | void insert(const T& element); 47 | 48 | /** Insert a new closed interval of elements. @version 1.7.1 */ 49 | void insert(const T& startElement, const T& endElement); 50 | 51 | /** Insert another interval set into this. @version 1.7.1 */ 52 | void insert(const IntervalSet& rhs); 53 | 54 | /** Remove the given element. @version 1.7.1 */ 55 | void erase(const T& element); 56 | 57 | /** Remove all element inside the given closed interval. @version 1.7.1 */ 58 | void erase(const T& startElement, const T& endElement); 59 | 60 | /** Remove all stored elements. @version 1.7.1 */ 61 | void clear(); 62 | 63 | /** Swap this container with another one. @version 1.7.1 */ 64 | void swap(IntervalSet& rhs); 65 | 66 | /** @return true if element exists. @version 1.7.1 */ 67 | bool exists(const T& element) const; 68 | 69 | /** 70 | * @return an iterator to element if stored, end() otherwise. 71 | * @version 1.7.1 72 | */ 73 | const_iterator find(const T& element) const; 74 | 75 | /** @return an iterator to the first element. @version 1.7.1 */ 76 | const_iterator begin() const; 77 | 78 | /** @return an iterator to the end of the interval set. @version 1.7.1 */ 79 | const_iterator end() const; 80 | 81 | /** @return the number of elements in the stored intervals. @version 1.7.1*/ 82 | size_t size() const; 83 | 84 | /** @return true if container is empty. @version 1.7.1 */ 85 | bool empty() const; 86 | 87 | private: 88 | typedef std::pair Edge; 89 | 90 | struct EdgeCompare 91 | { 92 | bool operator()(const Edge& p1, const Edge& p2) const 93 | { 94 | if (p1.first < p2.first) 95 | return true; 96 | if (p1.first == p2.first) 97 | return p1.second && !p2.second; 98 | return false; 99 | } 100 | }; 101 | 102 | // The first element of the pair is the edge value, the second element is 103 | // true for the start of an interval and false for the end. 104 | typedef std::multiset EdgeSet; 105 | EdgeSet _intervals; 106 | size_t _size; 107 | }; 108 | } 109 | 110 | #include "intervalSet.ipp" // template implementation 111 | 112 | #endif // LUNCHBOX_INTERVALSET_H 113 | -------------------------------------------------------------------------------- /lunchbox/lfQueue.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2014, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_LFQUEUE_H 19 | #define LUNCHBOX_LFQUEUE_H 20 | 21 | #include // member 22 | #include // used in inline method 23 | #include // thread-safety checks 24 | 25 | #include 26 | 27 | namespace lunchbox 28 | { 29 | /** 30 | * A thread-safe, lock-free queue with non-blocking access. 31 | * 32 | * Typically used for caches and non-blocking communication between two threads. 33 | * 34 | * Current implementation constraints: 35 | * * One reader thread 36 | * * One writer thread 37 | * * Fixed maximum size (writes may fail) 38 | * * Not copyable 39 | * 40 | * Example: @include tests/lfQueue.cpp 41 | */ 42 | template 43 | class LFQueue : public boost::noncopyable 44 | { 45 | public: 46 | /** Construct a new queue. @version 1.0 */ 47 | explicit LFQueue(const int32_t size) 48 | : _data(size + 1) 49 | , _readPos(0) 50 | , _writePos(0) 51 | { 52 | } 53 | 54 | /** Destruct this queue. @version 1.0 */ 55 | ~LFQueue() {} 56 | /** @return true if the queue is empty, false otherwise. @version 1.0 */ 57 | bool isEmpty() const { return _readPos == _writePos; } 58 | /** Reset (empty) the queue. @version 1.0 */ 59 | void clear(); 60 | 61 | /** 62 | * Resize and reset the queue. 63 | * 64 | * This method is not thread-safe. The queue has to be empty. 65 | * @version 1.0 66 | */ 67 | void resize(const int32_t size); 68 | 69 | /** 70 | * Retrieve and pop the front element from the queue. 71 | * 72 | * @param result the front value or unmodified 73 | * @return true if an element was placed in result, false if the queue 74 | * is empty. 75 | * @version 1.0 76 | */ 77 | bool pop(T& result); 78 | 79 | /** 80 | * Retrieve the front element from the queue. 81 | * 82 | * @param result the front value or unmodified 83 | * @return true if an element was placed in result, false if the queue 84 | * is empty. 85 | * @version 1.0 86 | */ 87 | bool getFront(T& result); 88 | 89 | /** 90 | * Push a new element to the back of the queue. 91 | * 92 | * @param element the element to add. 93 | * @return true if the element was placed, false if the queue is full 94 | * @version 1.0 95 | */ 96 | bool push(const T& element); 97 | 98 | /** 99 | * @return the maximum number of elements held by the queue. 100 | * @version 1.0 101 | */ 102 | size_t getCapacity() const { return _data.size() - 1; } 103 | private: 104 | std::vector _data; 105 | a_int32_t _readPos; 106 | a_int32_t _writePos; 107 | 108 | LB_TS_VAR(_reader); 109 | LB_TS_VAR(_writer); 110 | }; 111 | } 112 | 113 | #include "lfQueue.ipp" // template implementation 114 | 115 | #endif // LUNCHBOX_LFQUEUE_H 116 | -------------------------------------------------------------------------------- /lunchbox/lfQueue.ipp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2013, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | namespace lunchbox 19 | { 20 | template 21 | void LFQueue::clear() 22 | { 23 | LB_TS_SCOPED(_reader); 24 | _readPos = 0; 25 | _writePos = 0; 26 | } 27 | 28 | template 29 | void LFQueue::resize(const int32_t size) 30 | { 31 | LBASSERT(isEmpty()); 32 | _readPos = 0; 33 | _writePos = 0; 34 | _data.resize(size + 1); 35 | } 36 | 37 | template 38 | bool LFQueue::pop(T& result) 39 | { 40 | LB_TS_SCOPED(_reader); 41 | if (_readPos == _writePos) 42 | return false; 43 | 44 | result = _data[_readPos]; 45 | _readPos = (_readPos + 1) % _data.size(); 46 | return true; 47 | } 48 | 49 | template 50 | bool LFQueue::getFront(T& result) 51 | { 52 | LB_TS_SCOPED(_reader); 53 | if (_readPos == _writePos) 54 | return false; 55 | 56 | result = _data[_readPos]; 57 | return true; 58 | } 59 | 60 | template 61 | bool LFQueue::push(const T& element) 62 | { 63 | LB_TS_SCOPED(_writer); 64 | int32_t nextPos = (_writePos + 1) % _data.size(); 65 | if (nextPos == _readPos) 66 | return false; 67 | 68 | _data[_writePos] = element; 69 | _writePos = nextPos; 70 | return true; 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /lunchbox/lfVectorIterator.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2011-2013, EPFL/Blue Brain Project 3 | * Stefan Eilemann 4 | * 5 | * This file is part of Lunchbox 6 | * 7 | * This library is free software; you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License version 3.0 as published 9 | * by the Free Software Foundation. 10 | * 11 | * This library is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this library; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | */ 20 | 21 | #ifndef LUNCHBOX_LFVECTOR_ITERATOR_H 22 | #define LUNCHBOX_LFVECTOR_ITERATOR_H 23 | 24 | #include 25 | 26 | namespace lunchbox 27 | { 28 | /** 29 | * An iterator for LFVector. 30 | * 31 | * @tparam V the LFVector type 32 | * @tparam T the LFVector element type 33 | */ 34 | template 35 | class LFVectorIterator : public IndexIterator, V, T> 36 | { 37 | typedef IndexIterator, V, T> Super; 38 | 39 | public: 40 | /** Construct an iterator for a given vector and position. @version 1.8 */ 41 | LFVectorIterator(V* vector, size_t i) 42 | : Super(vector, i) 43 | { 44 | } 45 | 46 | /** Copy-construct an iterator. @version 1.8 */ 47 | template 48 | LFVectorIterator(const LFVectorIterator& from) 49 | : Super(from) 50 | { 51 | } 52 | 53 | /** Dereference the element at the current position. @version 1.8 */ 54 | T& operator*() const { return (*Super::container_)[Super::i_]; } 55 | /** Address the element at the current position. @version 1.8 */ 56 | T* operator->() const { return &(*Super::container_)[Super::i_]; } 57 | /** Address the element at the given position. @version 1.8 */ 58 | T& operator[](const size_t& n) const 59 | { 60 | return (*Super::container_)[Super::i_ + n]; 61 | } 62 | 63 | private: 64 | template 65 | friend class LFVector; // LFVector::erase 66 | }; 67 | } 68 | 69 | #endif // LUNCHBOX_LFVECTOR_ITERATOR_H 70 | -------------------------------------------------------------------------------- /lunchbox/lockable.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2009-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_LOCKABLE_H 19 | #define LUNCHBOX_LOCKABLE_H 20 | 21 | #include // used inline 22 | 23 | #include 24 | #include 25 | #include 26 | 27 | namespace lunchbox 28 | { 29 | /** 30 | * A convenience structure to hold data together with a lock for access. 31 | * 32 | * Locking the data still has to be done manually, e.g, using a ScopedMutex. 33 | */ 34 | template 35 | class Lockable : public boost::noncopyable 36 | { 37 | public: 38 | /** Construct a new lockable data structure. @version 1.0 */ 39 | Lockable() {} 40 | /** Construct and initialize a new data structure. @version 1.0 */ 41 | explicit Lockable(const D& value) 42 | : data(value) 43 | { 44 | } 45 | 46 | /** Construct and initialize a new data structure. @version 1.3.2 */ 47 | template 48 | Lockable(const P1& p1) 49 | : data(p1) 50 | { 51 | } 52 | 53 | /** Access the held data. @version 1.0 */ 54 | D* operator->() { return &data; } 55 | /** Access the held data. @version 1.0 */ 56 | const D* operator->() const { return &data; } 57 | /** Access the held data. @version 1.1.5 */ 58 | D& operator*() { return data; } 59 | /** Access the held data. @version 1.1.5 */ 60 | const D& operator*() const { return data; } 61 | /** @return true if the data is equal to the rhs object. @version 1.0*/ 62 | bool operator==(const D& rhs) const { return (data == rhs); } 63 | /** Assign another value to the data. @version 1.0 */ 64 | Lockable& operator=(const D& rhs) 65 | { 66 | data = rhs; 67 | return *this; 68 | } 69 | 70 | D data; 71 | mutable L lock; 72 | }; 73 | 74 | /** Print the data to the given output stream. */ 75 | template 76 | inline std::ostream& operator<<(std::ostream& os, const Lockable& l) 77 | { 78 | return os << disableFlush << "<" << l.lock.isSet() << " " << l.data << ">" 79 | << enableFlush; 80 | } 81 | } 82 | #endif // LUNCHBOX_LOCKABLE_H 83 | -------------------------------------------------------------------------------- /lunchbox/os.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2014, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "os.h" 19 | 20 | // for NI_MAXHOST 21 | #ifdef _WIN32 22 | #include 23 | #else 24 | #include 25 | #endif 26 | 27 | namespace lunchbox 28 | { 29 | std::string getHostname() 30 | { 31 | char hostname[NI_MAXHOST + 1] = {0}; 32 | gethostname(hostname, NI_MAXHOST); 33 | hostname[NI_MAXHOST] = '\0'; 34 | return std::string(hostname); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lunchbox/os.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2005-2018, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | /** Includes key system header files and defines essential base macros. */ 19 | #ifndef LUNCHBOX_OS_H 20 | #define LUNCHBOX_OS_H 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | #ifdef _WIN32 27 | #ifndef WIN32 28 | #define WIN32 29 | #endif 30 | #ifndef WIN32_API 31 | #define WIN32_API 32 | #endif 33 | #ifndef _MSC_VER 34 | #define USE_SYS_TYPES_FD_SET 35 | #endif 36 | #ifndef _WIN32_WINNT // Hopefully to higher than 0x500... 37 | #define _WIN32_WINNT 0x501 // => XP, for WM_XBUTTONDOWN and others 38 | #endif 39 | #ifndef _USE_MATH_DEFINES 40 | #define _USE_MATH_DEFINES 41 | #endif 42 | #ifndef WIN32_LEAN_AND_MEAN 43 | #define WIN32_LEAN_AND_MEAN 44 | #endif 45 | #ifndef NOMINMAX 46 | #define NOMINMAX 47 | #endif 48 | #include 49 | #include 50 | #endif 51 | 52 | #include 53 | #include 54 | #include 55 | #include 56 | 57 | #ifndef _MSC_VER 58 | #include 59 | #include 60 | #include // for MIN/MAX 61 | #endif 62 | 63 | #ifdef __APPLE__ 64 | #include 65 | #define environ (*_NSGetEnviron()) 66 | #elif !defined(_WIN32) 67 | extern "C" char** environ; 68 | #endif 69 | 70 | namespace lunchbox 71 | { 72 | /** OS-independent call to bzero(3). @version 1.7.1 */ 73 | static inline void setZero(void* ptr, const size_t size) 74 | { 75 | #ifdef _WIN32 76 | ::memset(ptr, 0, size); 77 | #else 78 | ::bzero(ptr, size); 79 | #endif 80 | } 81 | 82 | /** @return the local hostname. @version 1.9.2 */ 83 | LUNCHBOX_API std::string getHostname(); 84 | } 85 | 86 | #endif // LUNCHBOX_OS_H 87 | -------------------------------------------------------------------------------- /lunchbox/perThread.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2005-2016, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_PERTHREAD_H 19 | #define LUNCHBOX_PERTHREAD_H 20 | 21 | #include // deprecated macro 22 | #include // LBASSERTINFO 23 | #include // member 24 | 25 | namespace lunchbox 26 | { 27 | namespace detail 28 | { 29 | class PerThread; 30 | } 31 | 32 | /** Default PerThread destructor deleting the object. @version 1.1.2 */ 33 | template 34 | void perThreadDelete(T* object) 35 | { 36 | delete object; 37 | } 38 | 39 | /** Empty PerThread destructor. @version 1.1.2 */ 40 | template 41 | void perThreadNoDelete(T*) 42 | { 43 | } 44 | 45 | /** 46 | * Implements thread-specific storage for C++ objects. 47 | * 48 | * The default destructor function deletes the object on thread exit. 49 | * 50 | * @param T the type of data to store in thread-local storage 51 | * @param D the destructor callback function. 52 | * @deprecated Use boost::thread_specific_ptr 53 | * 54 | * Example: @include tests/perThread.cpp 55 | */ 56 | template > 57 | class PerThread 58 | { 59 | public: 60 | /** Construct a new per-thread variable. @version 1.0 */ 61 | PerThread(); 62 | /** Destruct the per-thread variable. @version 1.0 */ 63 | ~PerThread(); 64 | 65 | /** Assign an object to the thread-local storage. @version 1.0 */ 66 | PerThread& operator=(const T* data); 67 | /** Assign an object from another thread-local storage. @version 1.0 */ 68 | PerThread& operator=(const PerThread& rhs); 69 | 70 | /** @return the held object pointer. @version 1.0 */ 71 | T* get(); 72 | /** @return the held object pointer. @version 1.0 */ 73 | const T* get() const; 74 | /** Access the thread-local object. @version 1.0 */ 75 | T* operator->(); 76 | /** Access the thread-local object. @version 1.0 */ 77 | const T* operator->() const; 78 | 79 | /** @return the held object reference. @version 1.0 */ 80 | T& operator*() 81 | { 82 | LBASSERTINFO(get(), className(this)); 83 | return *get(); 84 | } 85 | /** @return the held object reference. @version 1.0 */ 86 | const T& operator*() const 87 | { 88 | LBASSERTINFO(get(), className(this)); 89 | return *get(); 90 | } 91 | 92 | /** 93 | * @return true if the thread-local variables hold the same object. 94 | * @version 1.0 95 | */ 96 | bool operator==(const PerThread& rhs) const { return (get() == rhs.get()); } 97 | /** 98 | * @return true if the thread-local variable holds the same object. 99 | * @version 1.0 100 | */ 101 | bool operator==(const T* rhs) const { return (get() == rhs); } 102 | /** 103 | * @return true if the thread-local variable holds another object. 104 | * @version 1.0 105 | */ 106 | bool operator!=(const T* rhs) const { return (get() != rhs); } 107 | /** 108 | * @return true if the thread-local storage holds a 0 pointer. 109 | * @version 1.0 110 | */ 111 | bool operator!() const; 112 | 113 | /** 114 | * @return true if the thread-local storage holds a non-0 pointer. 115 | * @version 1.0 116 | */ 117 | bool isValid() const; 118 | 119 | private: 120 | TLS tls_; 121 | PerThread(const PerThread&) = delete; 122 | PerThread(PerThread&&) = delete; 123 | PerThread& operator=(const PerThread&&) = delete; 124 | }; 125 | } 126 | 127 | #include "perThread.ipp" // template implementation 128 | 129 | #endif // LUNCHBOX_PERTHREAD_H 130 | -------------------------------------------------------------------------------- /lunchbox/perThread.ipp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2005-2013, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | namespace lunchbox 19 | { 20 | template 21 | PerThread::PerThread() 22 | : tls_((TLS::ThreadDestructor_t)D) 23 | { 24 | } 25 | 26 | template 27 | PerThread::~PerThread() 28 | { 29 | } 30 | 31 | template 32 | PerThread& PerThread::operator=(const T* data) 33 | { 34 | tls_.set(static_cast(data)); 35 | return *this; 36 | } 37 | 38 | template 39 | PerThread& PerThread::operator=(const PerThread& rhs) 40 | { 41 | tls_.set(rhs.tls_.get()); 42 | return *this; 43 | } 44 | 45 | template 46 | T* PerThread::get() 47 | { 48 | return static_cast(tls_.get()); 49 | } 50 | 51 | template 52 | const T* PerThread::get() const 53 | { 54 | return static_cast(tls_.get()); 55 | } 56 | 57 | template 58 | T* PerThread::operator->() 59 | { 60 | return static_cast(tls_.get()); 61 | } 62 | 63 | template 64 | const T* PerThread::operator->() const 65 | { 66 | return static_cast(tls_.get()); 67 | } 68 | 69 | template 70 | bool PerThread::operator!() const 71 | { 72 | return tls_.get() == 0; 73 | } 74 | 75 | template 76 | bool PerThread::isValid() const 77 | { 78 | return tls_.get() != 0; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lunchbox/plugin.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2016, EPFL/Blue Brain Project 3 | * Raphael Dumusc 4 | * Stefan.Eilemann@epfl.ch 5 | * 6 | * This file is part of Lunchbox 7 | * 8 | * This library is free software; you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License version 2.1 as published 10 | * by the Free Software Foundation. 11 | * 12 | * This library is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 | * details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this library; if not, write to the Free Software Foundation, Inc., 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | */ 21 | 22 | #ifndef LUNCHBOX_PLUGIN_H 23 | #define LUNCHBOX_PLUGIN_H 24 | 25 | #include 26 | #include // member 27 | 28 | namespace lunchbox 29 | { 30 | /** @internal */ 31 | template 32 | class Plugin 33 | { 34 | public: 35 | /** The constructor method for Plugin objects. @version 1.11.0 */ 36 | using Constructor = std::function; 37 | 38 | /** 39 | * The method to check if the plugin can handle a given initData. 40 | * @version 1.11.0 41 | */ 42 | using HandlesFunc = std::function; 43 | 44 | /** The method to get the plugin's description. @version 1.16 */ 45 | using DescriptionFunc = std::function; 46 | 47 | /** 48 | * Construct a new Plugin. 49 | * @param constructor The constructor method for Plugin objects. 50 | * @param handles_ The method to check if the plugin can handle the 51 | * initData. 52 | * @param description method to get the the help for the plugin 53 | * @version 1.11.0 54 | */ 55 | Plugin(const Constructor& constructor, const HandlesFunc& handles_, 56 | const DescriptionFunc& description) 57 | : _constructor(constructor) 58 | , _handles(handles_) 59 | , _description(description) 60 | { 61 | } 62 | 63 | /** Construct a new plugin instance. @version 1.14 */ 64 | T* construct(const typename T::InitDataT& data) const 65 | { 66 | return _constructor(data); 67 | } 68 | 69 | /** @return true if this plugin handles the given request. @version 1.14 */ 70 | bool handles(const typename T::InitDataT& data) const 71 | { 72 | return _handles(data); 73 | } 74 | 75 | /** @return the plugin's description. @version 1.17 */ 76 | std::string getDescription() const { return _description(); } 77 | bool operator==(const Plugin& rhs) const // TEST 78 | { 79 | return &_constructor == &rhs._constructor && 80 | &_handles == &rhs._handles && 81 | _description() == rhs._description(); 82 | } 83 | 84 | bool operator!=(const Plugin& rhs) const // TEST 85 | { 86 | return !(*this == rhs); 87 | } 88 | 89 | private: 90 | Constructor _constructor; 91 | HandlesFunc _handles; 92 | DescriptionFunc _description; 93 | }; 94 | } 95 | 96 | #endif 97 | -------------------------------------------------------------------------------- /lunchbox/pluginRegisterer.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2017, EPFL/Blue Brain Project 3 | * Raphael Dumusc 4 | * Stefan.Eilemann@epfl.ch 5 | * 6 | * This file is part of Lunchbox 7 | * 8 | * This library is free software; you can redistribute it and/or modify it under 9 | * the terms of the GNU Lesser General Public License version 2.1 as published 10 | * by the Free Software Foundation. 11 | * 12 | * This library is distributed in the hope that it will be useful, but WITHOUT 13 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 15 | * details. 16 | * 17 | * You should have received a copy of the GNU Lesser General Public License 18 | * along with this library; if not, write to the Free Software Foundation, Inc., 19 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 20 | */ 21 | 22 | #ifndef LUNCHBOX_PLUGINREGISTERER_H 23 | #define LUNCHBOX_PLUGINREGISTERER_H 24 | 25 | #include // used inline 26 | #include // used inline 27 | 28 | #include 29 | #include 30 | 31 | namespace lunchbox 32 | { 33 | /** 34 | * Helper class to statically register derived plugin classes. 35 | * 36 | * The following code can be placed in a plugin's cpp file: 37 | * @code 38 | * namespace 39 | * { 40 | * PluginRegisterer< MyPlugin > registerer; 41 | * } 42 | * @endcode 43 | * 44 | * The plugin needs to conform to the following API: 45 | * @code 46 | * class MyPluginInterface 47 | * { 48 | * public: 49 | * typedef MyPluginInterface InterfaceT; 50 | * typedef MyPluginInitData InitDataT; 51 | * }; 52 | * 53 | * class MyPlugin : public MyPluginInterface 54 | * { 55 | * public: 56 | * MyPlugin( const InitDataT& data ); 57 | * static bool handles( const InitDataT& data ); 58 | * static std::string getDescription(); 59 | * }; 60 | * @endcode 61 | * 62 | * @version 1.11.0 63 | */ 64 | 65 | template 66 | class PluginRegisterer 67 | { 68 | public: 69 | /** Construct and register the Plugin< T > class. @version 1.11.0 */ 70 | PluginRegisterer() 71 | { 72 | PluginFactory::getInstance().register_( 73 | {std::bind(boost::factory(), std::placeholders::_1), 74 | std::bind(&T::handles, std::placeholders::_1), 75 | std::bind(&T::getDescription)}); 76 | } 77 | }; 78 | } 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /lunchbox/pool.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_POOL_H 19 | #define LUNCHBOX_POOL_H 20 | 21 | #include // member 22 | #include // member 23 | #include // thread-safety checks 24 | 25 | namespace lunchbox 26 | { 27 | /** A thread-safe object allocation pool. */ 28 | template 29 | class Pool : public boost::noncopyable 30 | { 31 | public: 32 | /** Construct a new pool. @version 1.0 */ 33 | Pool() {} 34 | /** Destruct this pool. @version 1.0 */ 35 | virtual ~Pool() { flush(); } 36 | /** @return a reusable or new item. @version 1.0 */ 37 | T* alloc() 38 | { 39 | ScopedFastWrite mutex(_lock); 40 | if (_cache.empty()) 41 | return new T; 42 | 43 | T* item = _cache.back(); 44 | _cache.pop_back(); 45 | return item; 46 | } 47 | 48 | /** Release an item for reuse. @version 1.0 */ 49 | void release(T* item) 50 | { 51 | ScopedFastWrite mutex(_lock); 52 | _cache.push_back(item); 53 | } 54 | 55 | /** Delete all cached items. @version 1.0 */ 56 | void flush() 57 | { 58 | ScopedFastWrite mutex(_lock); 59 | while (!_cache.empty()) 60 | { 61 | delete _cache.back(); 62 | _cache.pop_back(); 63 | } 64 | } 65 | 66 | private: 67 | SpinLock _lock; 68 | std::vector _cache; 69 | }; 70 | } 71 | #endif // LUNCHBOX_POOL_H 72 | -------------------------------------------------------------------------------- /lunchbox/readyFuture.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2014, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_READYFUTURE_H 19 | #define LUNCHBOX_READYFUTURE_H 20 | 21 | #include // base class 22 | 23 | namespace lunchbox 24 | { 25 | /** A boolean future with a known value. Fully thread safe. */ 26 | template 27 | class FutureBool : public FutureImpl 28 | { 29 | protected: 30 | bool wait(const uint32_t) final { return value; } 31 | bool isReady() const final { return true; } 32 | }; 33 | 34 | /** @return a boolean future being true. */ 35 | inline Future makeTrueFuture() 36 | { 37 | return Future(new FutureBool); 38 | } 39 | 40 | /** @return a boolean future being false. */ 41 | inline Future makeFalseFuture() 42 | { 43 | return Future(new FutureBool); 44 | } 45 | } 46 | #endif // LUNCHBOX_READYFUTURE_H 47 | -------------------------------------------------------------------------------- /lunchbox/referenced.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2009-2013, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "referenced.h" 19 | #include "refPtr.h" // first - debug macros 20 | 21 | namespace lunchbox 22 | { 23 | Referenced::Referenced() 24 | : _refCount(0) 25 | , _hasBeenDeleted(false) 26 | { 27 | } 28 | 29 | Referenced::~Referenced() 30 | { 31 | LBASSERT(!_hasBeenDeleted); 32 | _hasBeenDeleted = true; 33 | LBASSERTINFO(_refCount == 0, "Deleting object with ref count " 34 | << _refCount); 35 | } 36 | 37 | void Referenced::notifyFree() 38 | { 39 | // Don't inline referenced destruction 40 | delete this; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lunchbox/result.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_RESULT_H 19 | #define LUNCHBOX_RESULT_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include 26 | 27 | namespace lunchbox 28 | { 29 | /** A result returns an error code and behaves like a boolean. */ 30 | class Result 31 | { 32 | typedef void (Result::*bool_t)() const; 33 | void bool_true() const {} 34 | public: 35 | static const int32_t SUCCESS = 0; 36 | 37 | /** Construct a new result. @version 1.9.1 */ 38 | explicit Result(const int32_t code) 39 | : code_(code) 40 | { 41 | } 42 | 43 | /** Destruct the result. @version 1.9.1 */ 44 | virtual ~Result() {} 45 | /** @return true if no error occured, false otherwise. @version 1.9.1 */ 46 | operator bool_t() const 47 | { 48 | return code_ == SUCCESS ? &Result::bool_true : 0; 49 | } 50 | 51 | /** @return true if an error occured, false otherwise. @version 1.9.1 */ 52 | bool operator!() const { return code_ != SUCCESS; } 53 | /** @return true if the result is equal to the given value. @version 1.9.1*/ 54 | bool operator==(const int32_t code) const { return code_ == code; } 55 | /** @return true if the result is not equal to the rhs. @version 1.9.1*/ 56 | bool operator!=(const int32_t code) const { return code != code_; } 57 | /** @return the result code. @version 1.9.1 */ 58 | int32_t getCode() const { return code_; } 59 | /** @return the result string. @version 1.9.1 */ 60 | virtual std::string getString() const 61 | { 62 | return code_ == SUCCESS ? "success" : "result"; 63 | } 64 | 65 | protected: 66 | int32_t code_; 67 | }; 68 | 69 | inline std::ostream& operator<<(std::ostream& os, const Result& result) 70 | { 71 | return os << result.getString() << " (" << result.getCode() << ")"; 72 | } 73 | } 74 | #endif // LUNCHBOX_RESULT_H 75 | -------------------------------------------------------------------------------- /lunchbox/rng.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2015, Stefan Eilemann 3 | * Daniel Nachbaur 4 | * 5 | * This library is free software; you can redistribute it and/or modify it under 6 | * the terms of the GNU Lesser General Public License version 2.1 as published 7 | * by the Free Software Foundation. 8 | * 9 | * This library is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | #include "rng.h" 20 | 21 | #pragma warning(push) 22 | #pragma warning(disable : 4985) // inconsistent decl of ceil 23 | 24 | #ifdef _WIN32 25 | #ifndef NOMINMAX 26 | #define NOMINMAX 27 | #endif 28 | #include 29 | #include 30 | #pragma comment(lib, "advapi32.lib") 31 | #else 32 | #include 33 | #endif 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | #pragma warning(pop) 40 | 41 | namespace lunchbox 42 | { 43 | namespace 44 | { 45 | #ifdef __linux__ 46 | 47 | static int _fd = -1; 48 | 49 | void _exit() 50 | { 51 | if (_fd >= 0) 52 | { 53 | ::close(_fd); 54 | _fd = -1; 55 | } 56 | } 57 | 58 | int _init() 59 | { 60 | const int fd = ::open("/dev/urandom", O_RDONLY); 61 | if (fd >= 0) 62 | ::atexit(_exit); 63 | else 64 | { 65 | LBERROR << "Failed to open /dev/urandom: " << sysError << std::endl; 66 | return -1; 67 | } 68 | _fd = fd; 69 | return fd; 70 | } 71 | 72 | #elif defined _MSC_VER 73 | static HCRYPTPROV _provider = 0; 74 | 75 | void _exit() 76 | { 77 | if (_provider && !CryptReleaseContext(_provider, 0)) 78 | LBERROR << "Failed to release crypto context: " << sysError 79 | << std::endl; 80 | _provider = 0; 81 | } 82 | 83 | HCRYPTPROV _init() 84 | { 85 | HCRYPTPROV provider = 0; 86 | if (CryptAcquireContext(&provider, 0, 0, PROV_RSA_FULL, 87 | CRYPT_VERIFYCONTEXT) || 88 | !provider) 89 | { 90 | ::atexit(_exit); 91 | } 92 | else 93 | { 94 | LBERROR << "Failed to acquire crypto context: " << sysError 95 | << std::endl; 96 | return 0; 97 | } 98 | 99 | _provider = provider; 100 | return provider; 101 | } 102 | #endif 103 | } 104 | 105 | RNG::RNG() 106 | { 107 | #ifdef __APPLE__ 108 | srandomdev(); 109 | #endif 110 | } 111 | 112 | RNG::~RNG() 113 | { 114 | } 115 | 116 | bool RNG::_get(void* data, const size_t size) 117 | { 118 | #ifdef __linux__ 119 | static int fd = _init(); 120 | int read = ::read(fd, data, size); 121 | LBASSERTINFO(read == ssize_t(size), read << " != " << size << ": " 122 | << sysError); 123 | if (read != ssize_t(size)) 124 | { 125 | LBERROR << "random number generator not working" << std::endl; 126 | return false; 127 | } 128 | 129 | #elif defined _MSC_VER 130 | static HCRYPTPROV provider = _init(); 131 | if (!CryptGenRandom(provider, (DWORD)size, (BYTE*)data)) 132 | { 133 | LBERROR << "random number generator not working" << std::endl; 134 | return false; 135 | } 136 | #else // __APPLE__ 137 | uint8_t* ptr = reinterpret_cast(data); 138 | for (size_t i = 0; i < size; ++i) 139 | ptr[i] = (random() & 0xff); 140 | #endif 141 | return true; 142 | } 143 | } 144 | -------------------------------------------------------------------------------- /lunchbox/rng.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2007-2014, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_RNG_H 19 | #define LUNCHBOX_RNG_H 20 | 21 | #include 22 | #include 23 | #include // for LBASSERT 24 | #include // friend function 25 | #include 26 | 27 | namespace lunchbox 28 | { 29 | namespace detail 30 | { 31 | class RNG; 32 | } 33 | 34 | /** 35 | * A random number generator. 36 | * 37 | * Generates a set of random, or if not supported by the operating system, 38 | * pseudo-random numbers. Each instance creates its own series of numbers. 39 | * @deprecated Use Boost.Random 40 | * 41 | * Example: @include tests/rng.cpp 42 | */ 43 | class RNG : public boost::noncopyable 44 | { 45 | public: 46 | /** Construct a new random number generator. @version 1.0 */ 47 | LUNCHBOX_API RNG(); 48 | 49 | /** Destruct the random number generator. @version 1.0 */ 50 | LUNCHBOX_API ~RNG(); 51 | 52 | /** 53 | * Generate a random number. 54 | * 55 | * The returned number is between min..max for integer types, and 56 | * between 0..1 for floating-point types. 57 | * @return a random number. 58 | * @version 1.0 59 | */ 60 | template 61 | T get() 62 | { 63 | T value; 64 | if (!_get(&value, sizeof(T))) 65 | return T(); 66 | return value; 67 | } 68 | 69 | private: 70 | LUNCHBOX_API bool _get(void* data, size_t size); 71 | }; 72 | 73 | template <> 74 | inline float RNG::get() 75 | { 76 | const float max_limits = 77 | static_cast(std::numeric_limits::max()); 78 | return ((float)get() / max_limits); 79 | } 80 | 81 | template <> 82 | inline double RNG::get() 83 | { 84 | const double max_limits = 85 | static_cast(std::numeric_limits::max()); 86 | return ((double)get() / max_limits); 87 | } 88 | 89 | template <> 90 | inline bool RNG::get() 91 | { 92 | return (get() & 1); 93 | } 94 | } 95 | #endif // LUNCHBOX_RNG_H 96 | -------------------------------------------------------------------------------- /lunchbox/scopedMutex.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2006-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_SCOPEDMUTEX_H 19 | #define LUNCHBOX_SCOPEDMUTEX_H 20 | 21 | #include // used in inline method 22 | #include 23 | #include 24 | 25 | namespace lunchbox 26 | { 27 | /** 28 | * A scoped shared mutex. 29 | * 30 | * The mutex is automatically set upon creation, and released when the scoped 31 | * mutex is destroyed, e.g., when the scope is left. The scoped mutex does 32 | * nothing if a nullptr for the lock is passed. 33 | */ 34 | template 35 | class UniqueSharedLock 36 | { 37 | public: 38 | explicit UniqueSharedLock(L& lock) 39 | : _lock(&lock) 40 | { 41 | lock.lock_shared(); 42 | } 43 | 44 | explicit UniqueSharedLock(L* lock) 45 | : _lock(lock) 46 | { 47 | if (lock) 48 | lock->lock_shared(); 49 | } 50 | 51 | template 52 | explicit UniqueSharedLock(const LB& lockable) 53 | : UniqueSharedLock(lockable.lock) 54 | { 55 | } 56 | 57 | /** Destruct the scoped mutex and unset the mutex. @version 1.0 */ 58 | ~UniqueSharedLock() 59 | { 60 | if (_lock) 61 | _lock->unlock_shared(); 62 | } 63 | 64 | private: 65 | UniqueSharedLock() = delete; 66 | UniqueSharedLock(const UniqueSharedLock&) = delete; 67 | UniqueSharedLock(UniqueSharedLock&&) = delete; 68 | UniqueSharedLock& operator=(const UniqueSharedLock&) = delete; 69 | UniqueSharedLock& operator=(UniqueSharedLock&&) = delete; 70 | 71 | L* const _lock; 72 | }; 73 | 74 | /** 75 | * A scoped mutex. 76 | * 77 | * The mutex is automatically set upon creation, and released when the scoped 78 | * mutex is destroyed, e.g., when the scope is left. The scoped mutex does 79 | * nothing if a nullptr for the lock is passed. 80 | */ 81 | template 82 | class UniqueLock : public std::unique_lock 83 | { 84 | public: 85 | UniqueLock(L* lock_) 86 | : std::unique_lock(lock_ ? std::unique_lock(*lock_) 87 | : std::unique_lock()) 88 | { 89 | } 90 | 91 | UniqueLock(L& lock_) 92 | : std::unique_lock(lock_) 93 | { 94 | } 95 | 96 | template 97 | explicit UniqueLock(const LB& lockable) 98 | : UniqueLock(lockable.lock) 99 | { 100 | } 101 | 102 | private: 103 | UniqueLock() = delete; 104 | UniqueLock(const UniqueLock&) = delete; 105 | UniqueLock& operator=(const UniqueLock&) = delete; 106 | }; 107 | 108 | /** A scoped mutex for a fast uncontended read operation. @version 1.1.2 */ 109 | using ScopedFastRead = UniqueSharedLock; 110 | 111 | /** A scoped mutex for a fast uncontended write operation. @version 1.1.2 */ 112 | using ScopedFastWrite = UniqueLock; 113 | 114 | /** A scoped mutex for a read operation. @version 1.1.5 */ 115 | using ScopedRead = UniqueLock; 116 | 117 | /** A scoped mutex for a write operation. @version 1.1.5 */ 118 | using ScopedWrite = UniqueLock; 119 | } 120 | #endif // LUNCHBOX_SCOPEDMUTEX_H 121 | -------------------------------------------------------------------------------- /lunchbox/serializable.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012-2013, EPFL/Blue Brain Project 3 | * Daniel Nachbaur 4 | * 5 | * This file is part of Lunchbox 6 | * 7 | * This library is free software; you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License version 3.0 as published 9 | * by the Free Software Foundation. 10 | * 11 | * This library is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this library; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | */ 20 | 21 | #ifndef LUNCHBOX_SERIALIZABLE_H 22 | #define LUNCHBOX_SERIALIZABLE_H 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | /** Makes a class to be serializable using boost.serialization. */ 30 | #define LB_SERIALIZABLE \ 31 | friend class boost::serialization::access; \ 32 | template \ 33 | void save(Archive& ar, const unsigned int version) const; \ 34 | template \ 35 | void load(Archive& ar, const unsigned int version); \ 36 | BOOST_SERIALIZATION_SPLIT_MEMBER() 37 | 38 | #endif // LUNCHBOX_SERIALIZABLE_H 39 | -------------------------------------------------------------------------------- /lunchbox/servus.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012-2015, Stefan Eilemann 3 | * 4 | * This file is part of Lunchbox 5 | * 6 | * This library is free software; you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License version 2.1 as published 8 | * by the Free Software Foundation. 9 | * 10 | * This library is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | * details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this library; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef LUNCHBOX_SERVUS_H 21 | #define LUNCHBOX_SERVUS_H 22 | 23 | #include 24 | 25 | #ifdef LUNCHBOX_USE_V1_API 26 | #include 27 | 28 | namespace lunchbox 29 | { 30 | using servus::Servus; // In case types.h is not included 31 | } 32 | #else 33 | #error "This header file may not be included in API version 2" 34 | #endif 35 | 36 | #endif // LUNCHBOX_SERVUS_H 37 | -------------------------------------------------------------------------------- /lunchbox/sleep.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2011-2012, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "sleep.h" 19 | 20 | #include "os.h" 21 | #include "time.h" 22 | #include 23 | 24 | namespace lunchbox 25 | { 26 | void sleep(const uint32_t milliSeconds) 27 | { 28 | #ifdef _WIN32 //_MSC_VER 29 | ::Sleep(milliSeconds); 30 | #else 31 | timespec ts = convertToTimespec(milliSeconds); 32 | while (::nanosleep(&ts, &ts) != 0) // -1 on signal (#4) 33 | if (ts.tv_sec <= 0 && ts.tv_nsec <= 0) 34 | return; 35 | #endif 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /lunchbox/sleep.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2008-2014, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_SLEEP_H 19 | #define LUNCHBOX_SLEEP_H 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | namespace lunchbox 26 | { 27 | /** 28 | * Sleep the current thread for a number of milliseconds. 29 | * @version 1.0 30 | * @deprecated Use boost::this_thread::sleep() 31 | */ 32 | LUNCHBOX_API void sleep(const uint32_t milliSeconds); 33 | } 34 | #endif // LUNCHBOX_SLEEP_H 35 | -------------------------------------------------------------------------------- /lunchbox/spinLock.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "spinLock.h" 19 | #include 20 | #include 21 | 22 | namespace lunchbox 23 | { 24 | namespace 25 | { 26 | static const long _writelocked = -1; 27 | static const long _unlocked = 0; 28 | } 29 | 30 | class SpinLock::Impl 31 | { 32 | public: 33 | Impl() 34 | : _state(_unlocked) 35 | { 36 | } 37 | 38 | ~Impl() { _state = _unlocked; } 39 | 40 | inline void set() 41 | { 42 | while (true) 43 | { 44 | if (trySet()) 45 | return; 46 | lunchbox::Thread::yield(); 47 | } 48 | } 49 | 50 | inline void unset() 51 | { 52 | LBASSERT(_state == _writelocked); 53 | _state = _unlocked; 54 | } 55 | 56 | inline bool trySet() 57 | { 58 | if (!_state.compareAndSwap(_unlocked, _writelocked)) 59 | return false; 60 | LBASSERTINFO(isSetWrite(), _state); 61 | return true; 62 | } 63 | 64 | inline void setRead() 65 | { 66 | while (true) 67 | { 68 | if (trySetRead()) 69 | return; 70 | lunchbox::Thread::yield(); 71 | } 72 | } 73 | 74 | inline void unsetRead() 75 | { 76 | while (true) 77 | { 78 | LBASSERT(_state > _unlocked); 79 | memoryBarrier(); 80 | const int32_t expected = _state; 81 | if (_state.compareAndSwap(expected, expected - 1)) 82 | return; 83 | } 84 | } 85 | 86 | inline bool trySetRead() 87 | { 88 | memoryBarrier(); 89 | const int32_t state = _state; 90 | // Note: 0 used here since using _unlocked unexplicably gives 91 | // 'undefined reference to lunchbox::SpinLock::_unlocked' 92 | const int32_t expected = (state == _writelocked) ? 0 : state; 93 | 94 | if (!_state.compareAndSwap(expected, expected + 1)) 95 | return false; 96 | 97 | LBASSERTINFO(isSetRead(), _state << ", " << expected); 98 | return true; 99 | } 100 | 101 | inline bool isSet() { return (_state != _unlocked); } 102 | inline bool isSetWrite() { return (_state == _writelocked); } 103 | inline bool isSetRead() { return (_state > _unlocked); } 104 | 105 | private: 106 | a_int32_t _state; 107 | }; 108 | 109 | SpinLock::SpinLock() 110 | : _impl(new SpinLock::Impl) 111 | { 112 | } 113 | 114 | SpinLock::~SpinLock() 115 | { 116 | } 117 | 118 | void SpinLock::set() 119 | { 120 | _impl->set(); 121 | } 122 | 123 | void SpinLock::unset() 124 | { 125 | _impl->unset(); 126 | } 127 | 128 | bool SpinLock::trySet() 129 | { 130 | return _impl->trySet(); 131 | } 132 | 133 | void SpinLock::setRead() 134 | { 135 | _impl->setRead(); 136 | } 137 | 138 | void SpinLock::unsetRead() 139 | { 140 | _impl->unsetRead(); 141 | } 142 | 143 | bool SpinLock::trySetRead() 144 | { 145 | return _impl->trySetRead(); 146 | } 147 | 148 | bool SpinLock::isSet() 149 | { 150 | return _impl->isSet(); 151 | } 152 | 153 | bool SpinLock::isSetWrite() 154 | { 155 | return _impl->isSetWrite(); 156 | } 157 | 158 | bool SpinLock::isSetRead() 159 | { 160 | return _impl->isSetRead(); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /lunchbox/spinLock.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_SPINLOCK_H 19 | #define LUNCHBOX_SPINLOCK_H 20 | 21 | #include // member 22 | #include // used in inline method 23 | 24 | #include 25 | 26 | namespace lunchbox 27 | { 28 | /** 29 | * A fast lock for uncontended memory access. 30 | * 31 | * If Thread::yield() does not work, priority inversion is possible. If used as 32 | * a read-write lock, readers or writers will starve on high contention. 33 | * 34 | * @sa ScopedMutex 35 | * 36 | * Example: @include tests/perf/lock.cpp 37 | */ 38 | class SpinLock : public boost::noncopyable 39 | { 40 | public: 41 | /** Construct a new lock. @version 1.0 */ 42 | LUNCHBOX_API SpinLock(); 43 | 44 | /** Destruct the lock. @version 1.0 */ 45 | LUNCHBOX_API ~SpinLock(); 46 | 47 | /** Acquire the lock exclusively. @version 1.0 */ 48 | LUNCHBOX_API void set(); 49 | void lock() { set(); } 50 | /** Release an exclusive lock. @version 1.0 */ 51 | LUNCHBOX_API void unset(); 52 | void unlock() { unset(); } 53 | /** 54 | * Attempt to acquire the lock exclusively. 55 | * 56 | * @return true if the lock was set, false if it was not set. 57 | * @version 1.0 58 | */ 59 | LUNCHBOX_API bool trySet(); 60 | 61 | /** Acquire the lock shared with other readers. @version 1.1.2 */ 62 | LUNCHBOX_API void setRead(); 63 | void lock_shared() { setRead(); } 64 | /** Release a shared read lock. @version 1.1.2 */ 65 | LUNCHBOX_API void unsetRead(); 66 | void unlock_shared() { unsetRead(); } 67 | /** 68 | * Attempt to acquire the lock shared with other readers. 69 | * 70 | * @return true if the lock was set, false if it was not set. 71 | * @version 1.1.2 72 | */ 73 | LUNCHBOX_API bool trySetRead(); 74 | 75 | /** 76 | * Test if the lock is set. 77 | * 78 | * @return true if the lock is set, false if it is not set. 79 | * @version 1.0 80 | */ 81 | LUNCHBOX_API bool isSet(); 82 | 83 | /** 84 | * Test if the lock is set exclusively. 85 | * 86 | * @return true if the lock is set, false if it is not set. 87 | * @version 1.1.2 88 | */ 89 | LUNCHBOX_API bool isSetWrite(); 90 | 91 | /** 92 | * Test if the lock is set shared. 93 | * 94 | * @return true if the lock is set, false if it is not set. 95 | * @version 1.1.2 96 | */ 97 | LUNCHBOX_API bool isSetRead(); 98 | 99 | private: 100 | class Impl; 101 | std::unique_ptr _impl; 102 | 103 | SpinLock(const SpinLock&) = delete; 104 | SpinLock(SpinLock&&) = delete; 105 | SpinLock& operator=(const SpinLock&) = delete; 106 | SpinLock& operator=(SpinLock&&) = delete; 107 | }; 108 | } 109 | #endif // LUNCHBOX_SPINLOCK_H 110 | -------------------------------------------------------------------------------- /lunchbox/string.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2017, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #pragma once 19 | #include 20 | 21 | namespace lunchbox 22 | { 23 | namespace string 24 | { 25 | /** 26 | * Prepend each line of the given input with the given text. 27 | * 28 | * @param input the input string to add the prepended text 29 | * @param text text to prepend 30 | * @return the prepended string 31 | * @version 1.16 32 | */ 33 | inline std::string prepend(const std::string& input, const std::string& text) 34 | { 35 | std::string output; 36 | size_t pos = 0; 37 | for (size_t nextPos = input.find('\n', pos); nextPos != std::string::npos; 38 | nextPos = input.find('\n', pos)) 39 | { 40 | output += text + input.substr(pos, nextPos - pos + 1); 41 | pos = nextPos + 1; 42 | } 43 | output += text + input.substr(pos, std::string::npos); 44 | return output; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /lunchbox/term.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2017, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "term.h" 19 | #include "os.h" 20 | 21 | #ifndef _MSC_VER 22 | #include 23 | #include 24 | #include 25 | #endif 26 | 27 | #include 28 | namespace lunchbox 29 | { 30 | namespace term 31 | { 32 | size getSize() 33 | { 34 | #ifdef _MSC_VER 35 | CONSOLE_SCREEN_BUFFER_INFO info; 36 | if (GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info)) 37 | return {info.dwSize.X, info.dwSize.Y}; 38 | #else 39 | struct winsize w; 40 | if (::ioctl(STDOUT_FILENO, TIOCGWINSZ, &w) >= 0) 41 | return {w.ws_col, w.ws_row}; 42 | #endif 43 | return {120, 80}; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lunchbox/term.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2017, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #pragma once 19 | 20 | #include 21 | #include 22 | 23 | namespace lunchbox 24 | { 25 | namespace term 26 | { 27 | /** Terminal sizes in width, height. @version 1.16 */ 28 | using size = std::pair; 29 | 30 | /** 31 | * @return the width and height of the shell running the program. 32 | * @version 1.16 33 | */ 34 | LUNCHBOX_API size getSize(); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lunchbox/threadID.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2013, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "threadID.h" 19 | 20 | #include "log.h" 21 | 22 | #include // for memset 23 | #include 24 | 25 | #include "detail/threadID.h" 26 | 27 | namespace lunchbox 28 | { 29 | ThreadID::ThreadID() 30 | : _impl(new detail::ThreadID) 31 | { 32 | memset(&_impl->pthread, 0, sizeof(pthread_t)); 33 | } 34 | 35 | ThreadID::ThreadID(const ThreadID& from) 36 | : _impl(new detail::ThreadID) 37 | { 38 | _impl->pthread = from._impl->pthread; 39 | } 40 | 41 | ThreadID::~ThreadID() 42 | { 43 | delete _impl; 44 | } 45 | 46 | ThreadID& ThreadID::operator=(const ThreadID& from) 47 | { 48 | _impl->pthread = from._impl->pthread; 49 | return *this; 50 | } 51 | 52 | bool ThreadID::operator==(const ThreadID& rhs) const 53 | { 54 | return pthread_equal(_impl->pthread, rhs._impl->pthread); 55 | } 56 | 57 | bool ThreadID::operator!=(const ThreadID& rhs) const 58 | { 59 | return !pthread_equal(_impl->pthread, rhs._impl->pthread); 60 | } 61 | 62 | bool ThreadID::operator<(const ThreadID& rhs) const 63 | { 64 | #ifdef PTW32_VERSION 65 | return _impl->pthread.p < rhs._impl->pthread.p; 66 | #else 67 | return _impl->pthread < rhs._impl->pthread; 68 | #endif 69 | } 70 | 71 | std::ostream& operator<<(std::ostream& os, const ThreadID& threadID) 72 | { 73 | #ifdef PTW32_VERSION 74 | os << threadID._impl->pthread.p; 75 | #else 76 | os << threadID._impl->pthread; 77 | #endif 78 | return os; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /lunchbox/threadID.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2015, Stefan Eilemann 3 | * Daniel Nachbaur 4 | * 5 | * This library is free software; you can redistribute it and/or modify it under 6 | * the terms of the GNU Lesser General Public License version 2.1 as published 7 | * by the Free Software Foundation. 8 | * 9 | * This library is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | #ifndef LUNCHBOX_THREADID_H 20 | #define LUNCHBOX_THREADID_H 21 | 22 | #include // LUNCHBOX_API definition 23 | #include 24 | 25 | #include 26 | 27 | namespace lunchbox 28 | { 29 | namespace detail 30 | { 31 | class ThreadID; 32 | } 33 | 34 | /** An utility class to wrap OS-specific thread identifiers. */ 35 | class ThreadID 36 | { 37 | public: 38 | /** Construct a new, zero thread identifier. @version 1.0 */ 39 | LUNCHBOX_API ThreadID(); 40 | 41 | /** Construct a copy of a thread identifier. @version 1.0 */ 42 | LUNCHBOX_API ThreadID(const ThreadID& from); 43 | 44 | /** Destruct this thread identifier. @version 1.0 */ 45 | LUNCHBOX_API ~ThreadID(); 46 | 47 | /** Assign another thread identifier. @version 1.0 */ 48 | LUNCHBOX_API ThreadID& operator=(const ThreadID& from); 49 | 50 | /** @return true if the threads are equal, false if not. @version 1.0 */ 51 | LUNCHBOX_API bool operator==(const ThreadID& rhs) const; 52 | 53 | /** 54 | * @return true if the threads are different, false otherwise. 55 | * @version 1.0 56 | */ 57 | LUNCHBOX_API bool operator!=(const ThreadID& rhs) const; 58 | 59 | /** @internal */ 60 | bool operator<(const ThreadID& rhs) const; 61 | 62 | private: 63 | detail::ThreadID* const _impl; 64 | friend class Thread; 65 | 66 | friend LUNCHBOX_API std::ostream& operator<<(std::ostream& os, 67 | const ThreadID&); 68 | }; 69 | 70 | /** Print the thread to the given output stream. */ 71 | LUNCHBOX_API std::ostream& operator<<(std::ostream&, const ThreadID&); 72 | } 73 | #endif // LUNCHBOX_THREADID_H 74 | -------------------------------------------------------------------------------- /lunchbox/threadPool.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016-2017, Mohamed-Ghaith Kaabi 2 | * 3 | * This library is free software; you can redistribute it and/or modify it under 4 | * the terms of the GNU Lesser General Public License version 2.1 as published 5 | * by the Free Software Foundation. 6 | * 7 | * This library is distributed in the hope that it will be useful, but WITHOUT 8 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 9 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 10 | * details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this library; if not, write to the Free Software Foundation, Inc., 14 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 15 | */ 16 | 17 | #include "threadPool.h" 18 | 19 | namespace lunchbox 20 | { 21 | ThreadPool& ThreadPool::getInstance() 22 | { 23 | static ThreadPool pool(std::thread::hardware_concurrency()); 24 | return pool; 25 | } 26 | 27 | ThreadPool::ThreadPool(const size_t size) 28 | : _stop(false) 29 | { 30 | for (size_t i = 0; i < size; ++i) 31 | _threads.emplace_back([this] { this->work(); }); 32 | } 33 | 34 | ThreadPool::~ThreadPool() 35 | { 36 | { 37 | std::unique_lock lock(_mutex); 38 | _stop = true; 39 | _condition.notify_all(); 40 | } 41 | joinAll(); 42 | } 43 | 44 | size_t ThreadPool::getSize() const 45 | { 46 | return _threads.size(); 47 | } 48 | 49 | bool ThreadPool::hasPendingJobs() const 50 | { 51 | std::unique_lock lock(_mutex); 52 | return !_tasks.empty(); 53 | } 54 | 55 | void ThreadPool::joinAll() 56 | { 57 | for (auto& thread : _threads) 58 | thread.join(); 59 | } 60 | 61 | void ThreadPool::work() 62 | { 63 | for (;;) 64 | { 65 | std::function task; 66 | { 67 | std::unique_lock lock(_mutex); 68 | _condition.wait(lock, [this] { return _stop || !_tasks.empty(); }); 69 | if (_stop) 70 | return; 71 | task = std::move(_tasks.front()); 72 | _tasks.pop(); 73 | } 74 | task(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /lunchbox/threadPool.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2016-2017, Mohamed-Ghaith Kaabi 2 | * 3 | * This library is free software; you can redistribute it and/or modify it under 4 | * the terms of the GNU Lesser General Public License version 2.1 as published 5 | * by the Free Software Foundation. 6 | * 7 | * This library is distributed in the hope that it will be useful, but WITHOUT 8 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 9 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 10 | * details. 11 | * 12 | * You should have received a copy of the GNU Lesser General Public License 13 | * along with this library; if not, write to the Free Software Foundation, Inc., 14 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 15 | */ 16 | 17 | #pragma once 18 | 19 | #include 20 | 21 | #include // member 22 | #include 23 | #include // inline return value 24 | #include // member 25 | #include // member 26 | #include // member 27 | 28 | namespace lunchbox 29 | { 30 | /** 31 | * Thread pool for tasks execution. 32 | * A task is a callable object taking no arguments and returing a value or void. 33 | * All the member methods are thread safe. 34 | * 35 | * Example: @include tests/threadPool.cpp 36 | */ 37 | class ThreadPool 38 | { 39 | public: 40 | /** @return the application-global thread pool. */ 41 | static LUNCHBOX_API ThreadPool& getInstance(); 42 | 43 | /** 44 | * Construct a new ThreadPool. 45 | * 46 | * @param size number of threads in the thread pool 47 | * @sa getInstance() for the recommended thread pool. 48 | */ 49 | LUNCHBOX_API ThreadPool(const size_t size); 50 | /** 51 | * Destroy this thread pool. 52 | * Will block until all the tasks are done. 53 | */ 54 | LUNCHBOX_API ~ThreadPool(); 55 | 56 | /** 57 | * @return the number of threads used in the thread pool 58 | */ 59 | LUNCHBOX_API size_t getSize() const; 60 | 61 | /** 62 | * Post a new task in the thread pool. 63 | * @return a std::future containing the future result. 64 | */ 65 | template 66 | inline std::future::type> post(F&& f); 67 | 68 | /** 69 | * Post a detached task in the thread pool. 70 | * The result of this task is not monitored. 71 | */ 72 | template 73 | inline void postDetached(F&& f); 74 | 75 | /** @return true if there are pending tasks to be executed. */ 76 | LUNCHBOX_API bool hasPendingJobs() const; 77 | 78 | private: 79 | ThreadPool(const ThreadPool&) = delete; 80 | ThreadPool(ThreadPool&&) = delete; 81 | ThreadPool& operator=(const ThreadPool&) = delete; 82 | ThreadPool& operator=(ThreadPool&&) = delete; 83 | 84 | LUNCHBOX_API void joinAll(); 85 | LUNCHBOX_API void work(); 86 | 87 | std::vector _threads; 88 | std::queue > _tasks; 89 | mutable std::mutex _mutex; 90 | std::condition_variable _condition; 91 | bool _stop; 92 | }; 93 | 94 | template 95 | std::future::type> ThreadPool::post(F&& f) 96 | { 97 | using ReturnType = typename std::result_of::type; 98 | 99 | auto task = 100 | std::make_shared >(std::forward(f)); 101 | 102 | auto res = task->get_future(); 103 | { 104 | std::unique_lock lock(_mutex); 105 | _tasks.emplace([task]() { (*task)(); }); 106 | } 107 | _condition.notify_one(); 108 | return res; 109 | } 110 | 111 | template 112 | void ThreadPool::postDetached(F&& f) 113 | { 114 | { 115 | std::unique_lock lock(_mutex); 116 | _tasks.emplace(f); 117 | } 118 | _condition.notify_one(); 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /lunchbox/time.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_TIME_H 19 | #define LUNCHBOX_TIME_H 20 | 21 | namespace lunchbox 22 | { 23 | #ifndef _MSC_VER 24 | /** @internal @return a millisecond time as a unix timespec. */ 25 | inline timespec convertToTimespec(const uint32_t milliSeconds) 26 | { 27 | timespec ts = {0, 0}; 28 | ts.tv_sec = static_cast(milliSeconds / 1000); 29 | ts.tv_nsec = (milliSeconds - ts.tv_sec * 1000) * 1000000; 30 | return ts; 31 | } 32 | #endif 33 | } 34 | #endif // LUNCHBOX_TIME_H 35 | -------------------------------------------------------------------------------- /lunchbox/tls.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "tls.h" 19 | #include "debug.h" 20 | #include 21 | #include 22 | 23 | namespace lunchbox 24 | { 25 | namespace detail 26 | { 27 | class TLS 28 | { 29 | public: 30 | explicit TLS(lunchbox::TLS::ThreadDestructor_t df) 31 | : dtorFunc(df) 32 | { 33 | } 34 | 35 | pthread_key_t key; 36 | const lunchbox::TLS::ThreadDestructor_t dtorFunc; 37 | }; 38 | } 39 | 40 | TLS::TLS(ThreadDestructor_t dtorFunc) 41 | : impl_(new detail::TLS(dtorFunc)) 42 | { 43 | const int error = pthread_key_create(&impl_->key, dtorFunc); 44 | if (error) 45 | { 46 | LBERROR << "Can't create thread-specific key: " << strerror(error) 47 | << std::endl; 48 | LBASSERT(!error); 49 | } 50 | } 51 | 52 | TLS::~TLS() 53 | { 54 | void* data = get(); 55 | if (data && impl_->dtorFunc) 56 | impl_->dtorFunc(data); 57 | 58 | pthread_key_delete(impl_->key); 59 | delete impl_; 60 | } 61 | 62 | void TLS::set(const void* data) 63 | { 64 | pthread_setspecific(impl_->key, data); 65 | } 66 | 67 | void* TLS::get() 68 | { 69 | return pthread_getspecific(impl_->key); 70 | } 71 | 72 | const void* TLS::get() const 73 | { 74 | return pthread_getspecific(impl_->key); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /lunchbox/tls.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2016, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_TLS_H 19 | #define LUNCHBOX_TLS_H 20 | 21 | #include 22 | 23 | namespace lunchbox 24 | { 25 | namespace detail 26 | { 27 | class TLS; 28 | } 29 | 30 | /** Provides thread-local storage API used by PerThread and PerThreadRef. */ 31 | class TLS 32 | { 33 | public: 34 | typedef void (*ThreadDestructor_t)(void*); 35 | 36 | /** 37 | * Construct a new per-thread storage. 38 | * 39 | * @param dtorFunc the destructor function called to destroy thread-local 40 | * storage, not called if 0. 41 | * @version 1.7.2 42 | */ 43 | LUNCHBOX_API explicit TLS(ThreadDestructor_t dtorFunc); 44 | 45 | /** Destruct the per-thread storage. @version 1.7.2 */ 46 | LUNCHBOX_API ~TLS(); 47 | 48 | /** Set the data for this thread-local storage. @version 1.7.2 */ 49 | LUNCHBOX_API void set(const void* data); 50 | 51 | /** @return the data for this thread-local storage. @version 1.7.2 */ 52 | LUNCHBOX_API void* get(); 53 | 54 | /** @return the data for this thread-local storage. @version 1.7.2 */ 55 | LUNCHBOX_API const void* get() const; 56 | 57 | private: 58 | detail::TLS* const impl_; 59 | 60 | TLS(const TLS&) = delete; 61 | TLS(TLS&&) = delete; 62 | TLS& operator=(const TLS&) = delete; 63 | TLS& operator=(const TLS&&) = delete; 64 | }; 65 | } 66 | 67 | #endif // LUNCHBOX_TLS_H 68 | -------------------------------------------------------------------------------- /lunchbox/uint128_t.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010, Cedric Stalder 3 | * 2010-2014, Stefan Eilemann 4 | * 2010-2012, Daniel Nachbaur 5 | * 6 | * This library is free software; you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License version 2.1 as published 8 | * by the Free Software Foundation. 9 | * 10 | * This library is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | * details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this library; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef LUNCHBOX_UINT128_H 21 | #define LUNCHBOX_UINT128_H 22 | 23 | #include 24 | 25 | #ifdef LUNCHBOX_USE_V1_API 26 | #include 27 | 28 | namespace lunchbox 29 | { 30 | using servus::uint128_t; 31 | using servus::make_uint128; 32 | using servus::make_UUID; 33 | } 34 | #else 35 | #error "This header file may not be included in API version 2" 36 | #endif 37 | 38 | #endif // LUNCHBOX_UINT128_H 39 | -------------------------------------------------------------------------------- /lunchbox/uri.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2013-2015, Ahmet.Bilgili@epfl.ch 2 | * , Stefan.Eilemann@epfl.ch 3 | * 4 | * This file is part of Lunchbox 5 | * 6 | * This library is free software; you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License version 2.1 as published 8 | * by the Free Software Foundation. 9 | * 10 | * This library is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | * details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this library; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef LUNCHBOX_URI_H 21 | #define LUNCHBOX_URI_H 22 | 23 | #include 24 | 25 | #ifdef LUNCHBOX_USE_V1_API 26 | #include 27 | 28 | namespace lunchbox 29 | { 30 | using servus::URI; // In case types.h is not included 31 | } 32 | #else 33 | #error "This header file may not be included in API version 2" 34 | #endif 35 | 36 | #endif // LUNCHBOX_URI_H 37 | -------------------------------------------------------------------------------- /lunchbox/visitorResult.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2009-2013, Stefan Eilemann 3 | * 4 | * This file is part of Lunchbox 5 | * 6 | * This library is free software; you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License version 2.1 as published 8 | * by the Free Software Foundation. 9 | * 10 | * This library is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | * details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this library; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #ifndef LUNCHBOX_VISITORRESULT_H 21 | #define LUNCHBOX_VISITORRESULT_H 22 | 23 | #include 24 | #include 25 | 26 | namespace lunchbox 27 | { 28 | /** The result code from any visit operation. */ 29 | enum VisitorResult 30 | { 31 | TRAVERSE_CONTINUE, //!< continue the traversal 32 | TRAVERSE_TERMINATE, //!< abort the traversal 33 | TRAVERSE_PRUNE //!< do not traverse current entity downwards 34 | }; 35 | 36 | inline std::ostream& operator<<(std::ostream& os, const VisitorResult& result) 37 | { 38 | switch (result) 39 | { 40 | case TRAVERSE_CONTINUE: 41 | return os << "continue"; 42 | case TRAVERSE_TERMINATE: 43 | return os << "terminate"; 44 | case TRAVERSE_PRUNE: 45 | return os << "prune"; 46 | default: 47 | return os << "ERROR"; 48 | } 49 | } 50 | } 51 | #endif // LUNCHBOX_VISITORRESULT_H 52 | -------------------------------------------------------------------------------- /pthreads/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010 Daniel Pfeifer 2 | # 2011-2013 Stefan Eilemann 3 | 4 | find_package(Threads REQUIRED QUIET) 5 | 6 | set(PTHREAD_LIBRARIES pthread) 7 | 8 | if(CMAKE_USE_PTHREADS_INIT) 9 | return() 10 | endif() 11 | 12 | IF(NOT WIN32) 13 | message(FATAL_ERROR "Lunchbox requires pthreads.") 14 | ENDIF(NOT WIN32) 15 | 16 | message(STATUS "Pthreads-win32 will be built by Lunchbox.") 17 | 18 | set(PTHREADS_NAME pthreads-w32-2011-03-16) 19 | set(PTHREADS_TGZ ${CMAKE_CURRENT_SOURCE_DIR}/pthreads/${PTHREADS_NAME}.tar.gz) 20 | set(PTHREADS_DIR ${CMAKE_BINARY_DIR}/${PTHREADS_NAME}) 21 | 22 | if(NOT EXISTS ${PTHREADS_DIR}) 23 | execute_process(COMMAND ${CMAKE_COMMAND} -E tar xzf 24 | ${PTHREADS_TGZ} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}) 25 | endif() 26 | 27 | file(COPY ${PTHREADS_DIR}/pthread.h ${PTHREADS_DIR}/sched.h 28 | DESTINATION ${PROJECT_BINARY_DIR}/include) 29 | 30 | add_definitions(/wd4267) # conversion from 'size_t' to 'long' 31 | 32 | add_library(pthread SHARED 33 | ${PTHREADS_DIR}/attr.c 34 | ${PTHREADS_DIR}/barrier.c 35 | ${PTHREADS_DIR}/cancel.c 36 | ${PTHREADS_DIR}/cleanup.c 37 | ${PTHREADS_DIR}/condvar.c 38 | ${PTHREADS_DIR}/create.c 39 | ${PTHREADS_DIR}/dll.c 40 | ${PTHREADS_DIR}/exit.c 41 | ${PTHREADS_DIR}/fork.c 42 | ${PTHREADS_DIR}/global.c 43 | ${PTHREADS_DIR}/misc.c 44 | ${PTHREADS_DIR}/mutex.c 45 | ${PTHREADS_DIR}/private.c 46 | ${PTHREADS_DIR}/rwlock.c 47 | ${PTHREADS_DIR}/sched.c 48 | ${PTHREADS_DIR}/semaphore.c 49 | ${PTHREADS_DIR}/spin.c 50 | ${PTHREADS_DIR}/sync.c 51 | ${PTHREADS_DIR}/tsd.c 52 | ${PTHREADS_DIR}/nonportable.c 53 | ) 54 | 55 | set_target_properties(pthread PROPERTIES COMPILE_DEFINITIONS PTW32_BUILD=1 56 | FOLDER "${PROJECT_NAME}") 57 | target_include_directories(pthread PRIVATE ${PTHREADS_DIR}) 58 | target_link_libraries(pthread ws2_32) 59 | 60 | install(TARGETS pthread 61 | EXPORT LunchboxTargets 62 | ARCHIVE DESTINATION lib COMPONENT codev 63 | LIBRARY DESTINATION lib COMPONENT codev 64 | RUNTIME DESTINATION bin COMPONENT colib 65 | ) 66 | -------------------------------------------------------------------------------- /pthreads/pthreads-w32-2011-03-16.tar.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Eyescale/Lunchbox/bd98844ec4206ee34b04f0609995d2e20b83196d/pthreads/pthreads-w32-2011-03-16.tar.gz -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2010-2017, Daniel Pfeifer 2 | # Stefan Eilemann 3 | # 4 | # Change this number when adding tests to force a CMake run: 1 5 | 6 | include(InstallFiles) 7 | include_directories(${PROJECT_SOURCE_DIR}/tests) 8 | 9 | set(TEST_LIBRARIES Lunchbox ${Boost_LIBRARIES}) 10 | if(MSVC) 11 | list(APPEND TEST_LIBRARIES ${PTHREAD_LIBRARIES}) 12 | endif() 13 | if(COVERAGE AND TRAVIS) 14 | list(APPEND EXCLUDE_FROM_TESTS anySerialization.cpp) #timeout in lcov gather 15 | endif() 16 | 17 | include(CommonCTest) 18 | install_files(share/Lunchbox/tests FILES ${TEST_FILES} COMPONENT examples) 19 | -------------------------------------------------------------------------------- /tests/any.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012, Daniel Nachbaur 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | int main(int, char**) 23 | { 24 | lunchbox::Any any; 25 | lunchbox::Any otherAny; 26 | TEST(any.empty()); 27 | TEST(any.type() == typeid(void)); 28 | TEST(any == otherAny); 29 | 30 | any = 5; 31 | otherAny = any; 32 | TEST(lunchbox::any_cast(any) == 5); 33 | TEST(any.type() == typeid(int)); 34 | TEST(any == otherAny); 35 | 36 | any = 42; 37 | otherAny = 42; 38 | TEST(lunchbox::any_cast(any) == 42); 39 | TEST(any == otherAny); 40 | 41 | any = std::string("blablub"); 42 | TEST(lunchbox::any_cast(any) == "blablub"); 43 | TEST(any.type() == typeid(std::string)); 44 | TEST(any != otherAny); 45 | 46 | try 47 | { 48 | TEST(lunchbox::any_cast(any) != 42); 49 | } 50 | catch (const lunchbox::bad_any_cast&) 51 | { 52 | } 53 | 54 | return EXIT_SUCCESS; 55 | } 56 | -------------------------------------------------------------------------------- /tests/anySerialization.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012, Daniel Nachbaur 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include "serialize.h" 19 | #include 20 | 21 | #include 22 | 23 | int main(int, char**) 24 | { 25 | std::list testValues; 26 | testValues.push_back(int8_t(-1)); 27 | testValues.push_back(uint8_t(1)); 28 | testValues.push_back(int16_t(-10)); 29 | testValues.push_back(uint16_t(10)); 30 | testValues.push_back(int32_t(-100)); 31 | testValues.push_back(uint32_t(100)); 32 | testValues.push_back(int64_t(-1000)); 33 | testValues.push_back(uint64_t(1000)); 34 | testValues.push_back(bool(false)); 35 | testValues.push_back(float(5.42f)); 36 | testValues.push_back(double(17.56789)); 37 | testValues.push_back(std::string("blablub")); 38 | testValues.push_back(servus::uint128_t(servus::make_uint128("bla"))); 39 | Foo foo = {42, 1.5f, false, "blablub"}; 40 | testValues.push_back(foo); 41 | 42 | BOOST_FOREACH (const lunchbox::Any& any, testValues) 43 | { 44 | textSerializeAndTest(any); 45 | binarySerializeAndTest(any); 46 | } 47 | 48 | return EXIT_SUCCESS; 49 | } 50 | -------------------------------------------------------------------------------- /tests/bitOperation.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2011-2012, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | int main(int, char**) 22 | { 23 | TESTINFO(lunchbox::getIndexOfLastBit(0u) == -1, 24 | lunchbox::getIndexOfLastBit(0u)); 25 | TESTINFO(lunchbox::getIndexOfLastBit(42u) == 5, 26 | lunchbox::getIndexOfLastBit(42u)); 27 | TESTINFO(lunchbox::getIndexOfLastBit(LB_BIT12) == 11, 28 | lunchbox::getIndexOfLastBit(LB_BIT12)); 29 | TESTINFO(lunchbox::getIndexOfLastBit(LB_BIT48) == 47, 30 | lunchbox::getIndexOfLastBit(LB_BIT48)); 31 | 32 | uint16_t twoByte = 1; 33 | lunchbox::byteswap(twoByte); 34 | TESTINFO(twoByte == LB_BIT9, twoByte); 35 | 36 | uint32_t fourByte = 1; 37 | lunchbox::byteswap(fourByte); 38 | TESTINFO(fourByte == LB_BIT25, fourByte); 39 | 40 | uint64_t eightByte = 1; 41 | lunchbox::byteswap(eightByte); 42 | TESTINFO(eightByte == LB_BIT57, eightByte); 43 | 44 | return EXIT_SUCCESS; 45 | } 46 | -------------------------------------------------------------------------------- /tests/buffer.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2017, Daniel.Nachbaur@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #define BOOST_TEST_MODULE Buffer 19 | #include 20 | 21 | #include 22 | 23 | BOOST_AUTO_TEST_CASE(copy_construct_from_empty_buffer) 24 | { 25 | lunchbox::Bufferb empty; 26 | lunchbox::Bufferb newBuffer(empty); 27 | BOOST_CHECK_EQUAL(newBuffer.getData(), empty.getData()); 28 | BOOST_CHECK_EQUAL(newBuffer.getSize(), empty.getSize()); 29 | } 30 | -------------------------------------------------------------------------------- /tests/clock.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2014, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | int main(int, char**) 24 | { 25 | lunchbox::Clock clock; 26 | lunchbox::Clock copy(clock); 27 | 28 | TEST(clock.getTimef() - copy.getTimef() <= 0.f); 29 | TEST(clock.getTimef() - copy.getTimef() > -1.f); 30 | 31 | lunchbox::sleep(10.f); 32 | TEST(clock.resetTimef() > 0.f); 33 | lunchbox::sleep(1000.f); 34 | TEST(clock.getTimef() > 990.f); 35 | TEST(clock.getTimef() < 1100.f); 36 | TEST(clock.getTimed() < 1100.f); 37 | 38 | return EXIT_SUCCESS; 39 | } 40 | -------------------------------------------------------------------------------- /tests/debug.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2014, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | int main(int, char**) 23 | { 24 | #if !defined(_MSC_VER) || !defined(NDEBUG) 25 | const std::string& backtrace = lunchbox::backtrace(0); 26 | TEST(backtrace.find("testMain") != std::string::npos); 27 | #endif 28 | return EXIT_SUCCESS; 29 | } 30 | -------------------------------------------------------------------------------- /tests/dso.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2014-2016, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #ifdef __linux__ 23 | #include 24 | #endif 25 | 26 | #ifdef _WIN32 27 | #include 28 | #define libraryFunc CreateThread 29 | const std::string funcName("CreateThread"); 30 | #else 31 | #define libraryFunc malloc 32 | const std::string funcName("malloc"); 33 | #endif 34 | 35 | namespace fs = boost::filesystem; 36 | 37 | int main(int, char**) 38 | { 39 | lunchbox::Strings libraries; 40 | #ifdef _WIN32 41 | libraries.push_back("Kernel32.dll"); 42 | libraries.push_back("Ws2_32.dll"); 43 | #elif defined(Darwin) 44 | libraries.push_back("/usr/lib/libc.dylib"); 45 | libraries.push_back("/usr/lib/libtermcap.dylib"); 46 | #else 47 | libraries.push_back(LIBC_SO); 48 | libraries.push_back(LIBM_SO); 49 | #endif 50 | 51 | lunchbox::DSO one(libraries[0]); 52 | lunchbox::DSO two(libraries[1]); 53 | lunchbox::DSO three; 54 | 55 | TEST(one.isOpen()); 56 | TEST(two.isOpen()); 57 | TEST(!three.isOpen()); 58 | 59 | TEST(one != two); 60 | TEST(one != three); 61 | TEST(three.open(libraries[0])); 62 | TEST(one == three); 63 | TEST(!three.open(libraries[0])); 64 | TEST(one == three); 65 | 66 | TEST(one.getFunctionPointer(funcName)); 67 | TESTINFO(one.getFunctionPointer(funcName) == &libraryFunc, 68 | one.getFunctionPointer(funcName) << " != " << (void*)&libraryFunc); 69 | TEST(!one.getFunctionPointer("fooBar")); 70 | 71 | one.close(); 72 | TEST(one != two); 73 | TEST(one != three); 74 | TEST(!one.getFunctionPointer(funcName)); 75 | 76 | two.close(); 77 | TEST(one == two); 78 | TEST(one != three); 79 | 80 | return EXIT_SUCCESS; 81 | } 82 | -------------------------------------------------------------------------------- /tests/file.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2014-2016, Daniel.Nachbaur@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | int main(int, char** argv) 25 | { 26 | const boost::filesystem::path path(argv[0]); 27 | const std::string argvPath(path.parent_path().generic_string()); 28 | const boost::filesystem::path execPath(lunchbox::getExecutableDir()); 29 | TEST(boost::algorithm::ends_with(execPath.generic_string(), argvPath)); 30 | 31 | boost::filesystem::path referenceRootPath(execPath); 32 | referenceRootPath = referenceRootPath.parent_path(); 33 | #ifdef _MSC_VER 34 | const lunchbox::Strings buildTypes{"debug", "relwithdebinfo", "release", 35 | "minsizerel"}; 36 | std::string buildType(path.stem().string()); 37 | std::transform(buildType.begin(), buildType.end(), buildType.begin(), 38 | ::tolower); 39 | if (std::find(buildTypes.begin(), buildTypes.end(), buildType) != 40 | buildTypes.end()) 41 | { 42 | referenceRootPath = referenceRootPath.parent_path(); 43 | } 44 | #endif 45 | TEST(lunchbox::getRootDir() == referenceRootPath.string()); 46 | TEST(lunchbox::getExecutableDir() == lunchbox::getWorkDir()); 47 | 48 | const std::string filename = path.filename().generic_string(); 49 | TEST(filename == lunchbox::getFilename(argv[0])); 50 | 51 | const lunchbox::Strings files = lunchbox::searchDirectory(argvPath, ".*"); 52 | TEST(files.size() > 1); 53 | TEST(std::find(files.begin(), files.end(), filename) != files.end()); 54 | 55 | return EXIT_SUCCESS; 56 | } 57 | -------------------------------------------------------------------------------- /tests/future.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2014, Stefan.Eilemann@epfl.ch 3 | * 4 | * This file is part of Lunchbox 5 | * 6 | * This library is free software; you can redistribute it and/or modify it under 7 | * the terms of the GNU Lesser General Public License version 2.1 as published 8 | * by the Free Software Foundation. 9 | * 10 | * This library is distributed in the hope that it will be useful, but WITHOUT 11 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 12 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 13 | * details. 14 | * 15 | * You should have received a copy of the GNU Lesser General Public License 16 | * along with this library; if not, write to the Free Software Foundation, Inc., 17 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18 | */ 19 | 20 | #define BOOST_TEST_MODULE Future 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | BOOST_AUTO_TEST_CASE(readyFutures) 27 | { 28 | lunchbox::f_bool_t ok = lunchbox::makeTrueFuture(); 29 | BOOST_CHECK(ok == true); 30 | BOOST_CHECK(ok.isReady()); 31 | 32 | lunchbox::f_bool_t nok = lunchbox::makeFalseFuture(); 33 | BOOST_CHECK(nok == false); 34 | BOOST_CHECK(nok.isReady()); 35 | } 36 | 37 | static lunchbox::f_bool_t futureFunction() 38 | { 39 | return lunchbox::makeTrueFuture(); 40 | ; 41 | } 42 | 43 | static bool presentFunction() 44 | { 45 | return true; 46 | } 47 | 48 | BOOST_AUTO_TEST_CASE(perfFuture) 49 | { 50 | static const size_t nLoops = 1000000; 51 | 52 | lunchbox::Clock clock; 53 | for (size_t i = 0; i < nLoops; ++i) 54 | futureFunction(); 55 | const float futureSync = clock.resetTimef(); 56 | 57 | std::vector futures; 58 | futures.reserve(nLoops); 59 | for (size_t i = 0; i < nLoops; ++i) 60 | futures.push_back(futureFunction()); 61 | futures.clear(); 62 | const float futureASync = clock.resetTimef(); 63 | 64 | for (size_t i = 0; i < nLoops; ++i) 65 | presentFunction(); 66 | const float present = clock.resetTimef(); 67 | 68 | std::cout << nLoops / futureSync / 1000.f << " sync futures, " 69 | << nLoops / futureASync / 1000.f << " async futures, " 70 | << nLoops / present / 1000.f << " normal calls/us" << std::endl; 71 | } 72 | -------------------------------------------------------------------------------- /tests/init.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2016, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | 22 | int main(const int argc, char** argv) 23 | { 24 | TEST(lunchbox::init(0, 0)); 25 | TEST(lunchbox::init(argc, argv)); 26 | TEST(lunchbox::exit()); 27 | TEST(lunchbox::exit()); 28 | TEST(!lunchbox::exit()); 29 | 30 | TEST(lunchbox::init(argc, argv)); 31 | TEST(lunchbox::exit()); 32 | return EXIT_SUCCESS; 33 | } 34 | -------------------------------------------------------------------------------- /tests/intervalSet.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2016, Daniel Nachbaur 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | int main(int, char**) 22 | { 23 | typedef lunchbox::IntervalSet SetType; 24 | SetType set; 25 | TEST(set.empty()); 26 | 27 | set.insert(2); 28 | TEST(set.size() == 1); 29 | 30 | set.insert(1, 5); 31 | TEST(set.exists(3)); 32 | TEST(set.size() == 5); 33 | 34 | set.insert(1, 5); 35 | TEST(set.size() == 5); 36 | 37 | set.insert(2, 4); 38 | TEST(set.size() == 5); 39 | 40 | TEST(set.find(0) == set.end()); 41 | TEST(*set.find(3) == 3); 42 | TEST(set.find(6) == set.end()); 43 | 44 | size_t i = 1; 45 | for (SetType::const_iterator it = set.begin(); it != set.end(); ++it, ++i) 46 | TEST(*it == i); 47 | 48 | set.erase(3, 4); 49 | TEST(set.size() == 3); 50 | 51 | set.erase(2); 52 | TEST(set.size() == 2); 53 | 54 | TEST(set.exists(1)); 55 | TEST(set.exists(5)); 56 | 57 | set.clear(); 58 | TEST(set.empty()); 59 | 60 | set.insert(0, 1); 61 | TEST(set.size() == 2); 62 | set.insert(3, 5); 63 | TEST(set.size() == 5); 64 | SetType::const_iterator it = set.begin(); 65 | TEST(*it == 0); 66 | ++it; 67 | TEST(*it == 1); 68 | ++it; 69 | TEST(*it == 3); 70 | ++it; 71 | TEST(*it == 4); 72 | ++it; 73 | TEST(*it == 5); 74 | 75 | set.erase(4, 7); 76 | TEST(set.size() == 3); 77 | 78 | set.erase(40, 70); 79 | TEST(set.size() == 3); 80 | 81 | return EXIT_SUCCESS; 82 | } 83 | -------------------------------------------------------------------------------- /tests/issue1.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012-2014, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #define TEST_RUNTIME 300 // seconds 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #define NLOOPS 200000 28 | 29 | using servus::uint128_t; 30 | 31 | lunchbox::Monitor monitor; 32 | const uint128_t big(10, 10); 33 | 34 | class Thread : public lunchbox::Thread 35 | { 36 | public: 37 | virtual ~Thread() {} 38 | virtual void run() 39 | { 40 | const uint128_t invalid1(0, 0); 41 | const uint128_t invalid2(1, 1); 42 | 43 | while (monitor != big) 44 | { 45 | const uint128_t& result = monitor.waitLE(big); 46 | TEST(result != invalid1); 47 | TEST(result != invalid2); 48 | TEST(monitor != invalid1); 49 | TEST(monitor != invalid2); 50 | } 51 | } 52 | }; 53 | 54 | int main(int, char**) 55 | { 56 | int64_t nOps = NLOOPS; 57 | const uint128_t valid1(1, 0); 58 | const uint128_t valid2(0, 1); 59 | Thread thread; 60 | 61 | monitor = valid1; 62 | 63 | TEST(thread.start()); 64 | while (--nOps) 65 | { 66 | monitor = valid1; // cppcheck-suppress redundantAssignment 67 | monitor = valid2; 68 | } 69 | monitor = big; 70 | TEST(thread.join()); 71 | 72 | return EXIT_SUCCESS; 73 | } 74 | -------------------------------------------------------------------------------- /tests/lfQueue.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2011, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define RUNTIME 1000 /*ms*/ 25 | 26 | lunchbox::LFQueue queue(1024); 27 | 28 | class ReadThread : public lunchbox::Thread 29 | { 30 | public: 31 | virtual ~ReadThread() {} 32 | virtual void run() 33 | { 34 | uint64_t nOps = 0; 35 | uint64_t nEmpty = 0; 36 | uint64_t item = 0xffffffffffffffffull; 37 | 38 | lunchbox::Clock clock; 39 | while (clock.getTime64() < RUNTIME) 40 | { 41 | if (queue.getFront(item)) 42 | { 43 | TEST(item == nOps); 44 | uint64_t item2 = 0xffffffffffffffffull; 45 | TEST(queue.pop(item2)); 46 | TEST(item2 == item); 47 | ++nOps; 48 | } 49 | TEST(item + 1 == nOps); 50 | ++nEmpty; 51 | } 52 | const float time = clock.getTimef(); 53 | std::cout << 2 * nOps / time << " reads/ms, " << nEmpty / time 54 | << " empty/ms" << std::endl; 55 | } 56 | }; 57 | 58 | int main(int, char**) 59 | { 60 | ReadThread reader; 61 | uint64_t nOps = 0; 62 | uint64_t nEmpty = 0; 63 | 64 | TEST(reader.start()); 65 | 66 | lunchbox::Clock clock; 67 | while (clock.getTime64() < RUNTIME) 68 | { 69 | while (queue.push(nOps)) 70 | ++nOps; 71 | ++nEmpty; 72 | } 73 | const float time = clock.getTimef(); 74 | 75 | TEST(reader.join()); 76 | std::cout << nOps / time << " writes/ms, " << nEmpty / time << " full/ms" 77 | << std::endl; 78 | 79 | return EXIT_SUCCESS; 80 | } 81 | -------------------------------------------------------------------------------- /tests/memoryMap.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2017 Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #define BOOST_TEST_MODULE MemoryMap 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define MAP_SIZE LB_10MB 25 | #define STRIDE 23721 26 | 27 | BOOST_AUTO_TEST_CASE(write_read) 28 | { 29 | lunchbox::MemoryMap map("foo.mmap", MAP_SIZE); 30 | BOOST_CHECK_EQUAL(map.getSize(), MAP_SIZE); 31 | 32 | BOOST_CHECK(map.recreate("foo.mmap", MAP_SIZE / 2)); 33 | uint8_t* writePtr = map.getAddress(); 34 | BOOST_CHECK(writePtr); 35 | 36 | size_t i = 0; 37 | for (; i < MAP_SIZE / 2; i += STRIDE) 38 | writePtr[i] = uint8_t(i); 39 | 40 | BOOST_CHECK(map.resize(MAP_SIZE)); 41 | writePtr = map.getAddress(); 42 | for (; i < MAP_SIZE; i += STRIDE) 43 | writePtr[i] = uint8_t(i); 44 | map.unmap(); 45 | 46 | const void* noPtr = map.map("foo.map"); 47 | BOOST_CHECK(!noPtr); 48 | BOOST_CHECK_EQUAL(map.getSize(), 0); 49 | 50 | BOOST_CHECK(map.map("foo.mmap")); 51 | BOOST_CHECK(!map.map("foo.mmap")); 52 | BOOST_CHECK(map.remap("foo.mmap")); 53 | const uint8_t* readPtr = map.getAddress(); 54 | BOOST_CHECK(readPtr); 55 | BOOST_CHECK_EQUAL(map.getSize(), MAP_SIZE); 56 | 57 | for (i = 0; i < MAP_SIZE; i += STRIDE) 58 | BOOST_CHECK_EQUAL(readPtr[i], uint8_t(i)); 59 | } 60 | 61 | BOOST_AUTO_TEST_CASE(exceptions) 62 | { 63 | BOOST_CHECK_THROW(lunchbox::MemoryMap("doesnotexist"), std::runtime_error); 64 | BOOST_CHECK_THROW(lunchbox::MemoryMap("/doesnotexist", 42), 65 | std::runtime_error); 66 | } 67 | -------------------------------------------------------------------------------- /tests/mtQueue.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2010-2013, Stefan Eilemann 3 | * 2012, Daniel Nachbaur 4 | * 5 | * This library is free software; you can redistribute it and/or modify it under 6 | * the terms of the GNU Lesser General Public License version 2.1 as published 7 | * by the Free Software Foundation. 8 | * 9 | * This library is distributed in the hope that it will be useful, but WITHOUT 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 11 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 12 | * details. 13 | * 14 | * You should have received a copy of the GNU Lesser General Public License 15 | * along with this library; if not, write to the Free Software Foundation, Inc., 16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 17 | */ 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #define NOPS 100000 28 | #define NTHREADS 4 29 | 30 | lunchbox::MTQueue queue; 31 | lunchbox::MTQueue::Group group(NTHREADS + 1); 32 | 33 | #ifdef LB_GCC_4_6_OR_LATER 34 | #pragma GCC diagnostic ignored "-Wunused-but-set-variable" 35 | #endif 36 | class ReadThread : public lunchbox::Thread 37 | { 38 | public: 39 | virtual ~ReadThread() {} 40 | virtual void run() { run_(); } 41 | static void run_() 42 | { 43 | uint64_t item = 0xffffffffffffffffull; 44 | #ifndef NDEBUG 45 | uint64_t last = 0; 46 | #endif 47 | while (queue.popBarrier(item, group)) 48 | { 49 | #ifndef NDEBUG 50 | TESTINFO(last < item, last << " >= " << item); 51 | last = item; 52 | #endif 53 | } 54 | TEST(queue.isEmpty()); 55 | } 56 | }; 57 | 58 | int main(int, char**) 59 | { 60 | ReadThread reader[NTHREADS]; 61 | for (size_t i = 0; i < NTHREADS; ++i) 62 | TEST(reader[i].start()); 63 | 64 | lunchbox::Clock clock; 65 | for (size_t i = 1; i < NOPS; ++i) 66 | queue.push(i); 67 | const float time = clock.getTimef(); 68 | 69 | ReadThread::run_(); 70 | 71 | for (size_t i = 0; i < NTHREADS; ++i) 72 | TEST(reader[i].join()); 73 | 74 | std::cout << NOPS / time << " writes/ms" << std::endl; 75 | return EXIT_SUCCESS; 76 | } 77 | -------------------------------------------------------------------------------- /tests/perThread.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2011-2014, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #define NTHREADS 1024 27 | 28 | lunchbox::a_int32_t _threads; 29 | 30 | void destructor(size_t*) 31 | { 32 | --_threads; 33 | } 34 | 35 | lunchbox::PerThread _tls1; 36 | lunchbox::PerThread _tls2; 37 | lunchbox::PerThread _tls3; 38 | 39 | class Thread : public lunchbox::Thread 40 | { 41 | public: 42 | virtual ~Thread() {} 43 | virtual void run() 44 | { 45 | ++_threads; 46 | lunchbox::RNG rng; 47 | 48 | size_t i = rng.get(); 49 | size_t* data = new size_t(i); 50 | _tls1 = data; 51 | _tls2 = data; 52 | _tls3 = _tls1; 53 | 54 | TEST(_tls1.get() == data); 55 | TEST(*_tls1 == i); 56 | TEST(_tls2.get() == data); 57 | TEST(*_tls2 == i); 58 | TEST(*_tls1 == *_tls2); 59 | TEST(*_tls1 == *_tls3); 60 | 61 | _tls3 = 0; 62 | TEST(_tls3 == 0); 63 | } 64 | }; 65 | 66 | int main(int argc, char** argv) 67 | { 68 | TEST(lunchbox::init(argc, argv)); 69 | 70 | Thread threads[NTHREADS]; 71 | TESTINFO(_threads == 0, _threads); 72 | 73 | for (size_t i = 0; i < NTHREADS; ++i) 74 | TEST(threads[i].start()); 75 | for (size_t i = 0; i < NTHREADS; ++i) 76 | TEST(threads[i].join()); 77 | 78 | lunchbox::sleep(10); // ms, needed for tls exit handlers to run 79 | TESTINFO(_threads == 0, _threads); 80 | TEST(lunchbox::exit()); 81 | return EXIT_SUCCESS; 82 | } 83 | -------------------------------------------------------------------------------- /tests/perf/mutex.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2016-2017, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #define TEST_RUNTIME 600 // seconds, needed for NighlyMemoryCheck 19 | #include 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | #define MAXTHREADS 256 30 | #define TIME 500 // ms 31 | 32 | lunchbox::Clock _clock; 33 | bool _running = false; 34 | 35 | template 36 | class Thread : public lunchbox::Thread 37 | { 38 | public: 39 | Thread() 40 | : mutex(0) 41 | , ops(0) 42 | { 43 | } 44 | 45 | T* mutex; 46 | size_t ops; 47 | 48 | virtual void run() 49 | { 50 | ops = 0; 51 | while (LB_LIKELY(_running)) 52 | { 53 | mutex->lock(); 54 | mutex->unlock(); 55 | ++ops; 56 | } 57 | } 58 | }; 59 | 60 | template 61 | void _test() 62 | { 63 | const size_t nThreads = 16; 64 | 65 | T mutex; 66 | mutex.lock(); 67 | 68 | Thread threads[MAXTHREADS]; 69 | for (size_t i = 1; i <= nThreads; i = i << 1) 70 | { 71 | _running = true; 72 | for (size_t j = 0; j < i; ++j) 73 | { 74 | threads[j].mutex = &mutex; 75 | TEST(threads[j].start()); 76 | } 77 | lunchbox::sleep(10); // let threads initialize 78 | 79 | _clock.reset(); 80 | mutex.unlock(); 81 | lunchbox::sleep(TIME); // let threads run 82 | _running = false; 83 | 84 | for (size_t j = 0; j < i; ++j) 85 | TEST(threads[j].join()); 86 | const float time = _clock.getTimef(); 87 | 88 | mutex.lock(); 89 | 90 | size_t ops = 0; 91 | for (size_t j = 0; j < nThreads; ++j) 92 | ops += threads[j].ops; 93 | 94 | std::cout << std::setw(20) << lunchbox::className(mutex) << ", " 95 | << std::setw(12) << /*set, test, unset*/ 3 * ops / time 96 | << ", " << std::setw(3) << i << std::endl; 97 | } 98 | std::cout << std::endl; 99 | } 100 | 101 | int main(int argc, char** argv) 102 | { 103 | TEST(lunchbox::init(argc, argv)); 104 | 105 | std::cout << " Class, ops/ms, threads" << std::endl; 106 | _test(); 107 | _test(); 108 | _test(); 109 | 110 | TEST(lunchbox::exit()); 111 | return EXIT_SUCCESS; 112 | } 113 | -------------------------------------------------------------------------------- /tests/pluginFactory.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2017, EPFL/Blue Brain Project 3 | * Raphael Dumusc 4 | * 5 | * This file is part of Lunchbox 6 | * 7 | * This library is free software; you can redistribute it and/or modify it under 8 | * the terms of the GNU Lesser General Public License version 2.1 as published 9 | * by the Free Software Foundation. 10 | * 11 | * This library is distributed in the hope that it will be useful, but WITHOUT 12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 13 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 14 | * details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this library; if not, write to the Free Software Foundation, Inc., 18 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 19 | */ 20 | 21 | #define BOOST_TEST_MODULE PluginFactory 22 | 23 | #include 24 | struct InitData; 25 | namespace std 26 | { 27 | string to_string(const InitData&); 28 | } 29 | 30 | #include 31 | #include 32 | #include 33 | 34 | #include 35 | 36 | #define VALID_VALUE 10 37 | #define INVALID_VALUE 0 38 | 39 | struct InitData 40 | { 41 | InitData() 42 | : uri("test://uri") 43 | { 44 | } 45 | servus::URI uri; 46 | }; 47 | 48 | namespace std 49 | { 50 | inline std::string to_string(const InitData& data) 51 | { 52 | return std::to_string(data.uri); 53 | } 54 | } 55 | 56 | class PluginInterface 57 | { 58 | public: 59 | typedef InitData InitDataT; 60 | typedef PluginInterface InterfaceT; 61 | 62 | virtual ~PluginInterface() {} 63 | virtual int getValue() = 0; 64 | }; 65 | 66 | class Plugin : public PluginInterface 67 | { 68 | public: 69 | explicit Plugin(const InitData&) {} 70 | static bool handles(const InitData&) { return true; } 71 | static std::string getDescription() { return "I am a test plugin"; } 72 | int getValue() final { return VALID_VALUE; } 73 | }; 74 | 75 | class FalsePlugin : public PluginInterface 76 | { 77 | public: 78 | explicit FalsePlugin(const InitData&) {} 79 | static bool handles(const InitData&) { return false; } 80 | static std::string getDescription() { return "I am a lazy plugin"; } 81 | int getValue() final { return INVALID_VALUE; } 82 | }; 83 | 84 | typedef lunchbox::PluginFactory PluginFactory; 85 | typedef std::shared_ptr PluginInterfacePtr; 86 | 87 | PluginInterfacePtr createPlugin() 88 | { 89 | return PluginInterfacePtr(PluginFactory::getInstance().create(InitData())); 90 | } 91 | 92 | BOOST_AUTO_TEST_CASE(throwNoneRegistered) 93 | { 94 | PluginFactory::getInstance().deregisterAll(); 95 | BOOST_CHECK_THROW(createPlugin(), std::runtime_error); 96 | } 97 | 98 | BOOST_AUTO_TEST_CASE(creation) 99 | { 100 | auto& factory = PluginFactory::getInstance(); 101 | factory.deregisterAll(); 102 | lunchbox::PluginRegisterer registerer; 103 | PluginInterfacePtr plugin = createPlugin(); 104 | 105 | BOOST_CHECK(plugin); 106 | BOOST_CHECK_EQUAL(plugin->getValue(), VALID_VALUE); 107 | BOOST_CHECK_EQUAL(factory.getDescriptions(), "I am a test plugin"); 108 | } 109 | 110 | BOOST_AUTO_TEST_CASE(throwHandlesFailure) 111 | { 112 | PluginFactory::getInstance().deregisterAll(); 113 | lunchbox::PluginRegisterer registerer; 114 | 115 | BOOST_CHECK_THROW(createPlugin(), std::runtime_error); 116 | } 117 | 118 | BOOST_AUTO_TEST_CASE(createCorrectVariant) 119 | { 120 | auto& factory = PluginFactory::getInstance(); 121 | factory.deregisterAll(); 122 | lunchbox::PluginRegisterer registerer1; 123 | lunchbox::PluginRegisterer registerer2; 124 | PluginInterfacePtr plugin = createPlugin(); 125 | 126 | BOOST_CHECK(plugin); 127 | BOOST_CHECK_EQUAL(plugin->getValue(), VALID_VALUE); 128 | BOOST_CHECK_EQUAL(factory.getDescriptions(), 129 | "I am a lazy plugin\n\nI am a test plugin"); 130 | } 131 | -------------------------------------------------------------------------------- /tests/requestHandler.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2013-2014, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | using servus::uint128_t; 27 | 28 | lunchbox::RequestHandler handler_; 29 | lunchbox::MTQueue requestQ_; 30 | const uint128_t uuid = servus::make_UUID(); 31 | 32 | class Thread : public lunchbox::Thread 33 | { 34 | public: 35 | virtual void run() final 36 | { 37 | const bool boolIn = true; 38 | uint8_t* payload = (uint8_t*)42; 39 | 40 | uint32_t request = requestQ_.pop(); 41 | TEST(handler_.getRequestData(request) == ++payload); 42 | handler_.serveRequest(request, boolIn); 43 | 44 | const uint32_t uint32In = 0xC0FFEE; 45 | request = requestQ_.pop(); 46 | TEST(handler_.getRequestData(request) == ++payload); 47 | handler_.serveRequest(request, uint32In); 48 | 49 | request = requestQ_.pop(); 50 | TEST(handler_.getRequestData(request) == ++payload); 51 | handler_.serveRequest(request); 52 | 53 | request = requestQ_.pop(); 54 | TESTINFO(handler_.getRequestData(request) == ++payload, 55 | (size_t)handler_.getRequestData(request) << " for " 56 | << request); 57 | handler_.serveRequest(request); 58 | 59 | request = requestQ_.pop(); 60 | TEST(handler_.getRequestData(request) == ++payload); 61 | handler_.serveRequest(request, uuid); 62 | 63 | request = requestQ_.pop(); 64 | TEST(handler_.getRequestData(request) == ++payload); 65 | handler_.serveRequest(request); 66 | } 67 | }; 68 | 69 | int main(int, char**) 70 | { 71 | uint8_t* payload = (uint8_t*)42; 72 | Thread thread; 73 | thread.start(); 74 | 75 | uint32_t request = handler_.registerRequest(++payload); 76 | requestQ_.push(request); 77 | bool boolOut = false; 78 | TEST(handler_.waitRequest(request, boolOut)); 79 | TEST(boolOut == true); 80 | 81 | lunchbox::Request future = 82 | handler_.registerRequest(++payload); 83 | requestQ_.push(future.getID()); 84 | 85 | request = handler_.registerRequest(++payload); 86 | requestQ_.push(request); 87 | TEST(handler_.waitRequest(request)); 88 | 89 | lunchbox::Request voidFuture = 90 | handler_.registerRequest(++payload); 91 | lunchbox::Request uint128Future = 92 | handler_.registerRequest(++payload); 93 | 94 | requestQ_.push(voidFuture.getID()); 95 | requestQ_.push(uint128Future.getID()); 96 | 97 | TEST(future.wait() == 0xC0FFEE); 98 | TEST(future.wait()); 99 | TEST(uint128Future.wait() == uuid); 100 | TEST(voidFuture.isReady()); 101 | voidFuture.wait(); 102 | 103 | { 104 | lunchbox::Request waitAtDestructor = 105 | handler_.registerRequest(++payload); 106 | requestQ_.push(waitAtDestructor.getID()); 107 | } 108 | 109 | { 110 | lunchbox::Request wontBeServed = 111 | handler_.registerRequest(++payload); 112 | try 113 | { 114 | wontBeServed.wait(1); 115 | lunchbox::abort(); 116 | } 117 | catch (const lunchbox::FutureTimeout&) 118 | { 119 | } 120 | 121 | TEST(handler_.hasPendingRequests()) 122 | wontBeServed.unregister(); 123 | TEST(!handler_.hasPendingRequests()) 124 | 125 | try 126 | { 127 | wontBeServed.wait(); 128 | lunchbox::abort(); 129 | } 130 | catch (const lunchbox::UnregisteredRequest&) 131 | { 132 | } 133 | } 134 | 135 | TEST(thread.join()); 136 | return EXIT_SUCCESS; 137 | } 138 | -------------------------------------------------------------------------------- /tests/result.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2014, Daniel Nachbaur 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | int main(int, char**) 22 | { 23 | const lunchbox::Result success(lunchbox::Result::SUCCESS); 24 | const lunchbox::Result failure(lunchbox::Result::SUCCESS + 1); 25 | 26 | TEST(success); 27 | TEST(!failure); 28 | 29 | if (!success) 30 | TEST(false) 31 | 32 | if (failure) 33 | TEST(false) 34 | 35 | return EXIT_SUCCESS; 36 | } 37 | -------------------------------------------------------------------------------- /tests/rng.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2007-2012, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | // Tests the functionality of the random number generator 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #define MAXLOOPS 100000 28 | 29 | #define TESTLOOP(type, min, max) \ 30 | { \ 31 | size_t i = MAXLOOPS; \ 32 | while (--i) \ 33 | if (rng.get() <= (min)) \ 34 | break; \ 35 | TESTINFO(i, "Did never get value below " << std::to_string(min) \ 36 | << " for " << #type); \ 37 | i = MAXLOOPS; \ 38 | while (--i) \ 39 | if (rng.get() >= (max)) \ 40 | break; \ 41 | TESTINFO(i, "Did never get value above " << std::to_string(max) \ 42 | << " for " << #type); \ 43 | { \ 44 | const type value = rng.get(); \ 45 | i = MAXLOOPS; \ 46 | while (--i) \ 47 | if (rng.get() != value) \ 48 | break; \ 49 | TESTINFO(i, "Always get the same value " << value << " for " \ 50 | << #type); \ 51 | } \ 52 | } 53 | 54 | template 55 | void testSpeed() 56 | { 57 | lunchbox::RNG rng; 58 | lunchbox::Clock clock; 59 | for (size_t i = 0; i < MAXLOOPS; ++i) 60 | rng.get(); 61 | std::cout << float(MAXLOOPS) * sizeof(T) / clock.getTimef() 62 | << " byte/ms in " << sizeof(T) << " byte reads" << std::endl; 63 | } 64 | 65 | int main(int argc, char **argv) 66 | { 67 | TEST(lunchbox::init(argc, argv)); 68 | 69 | lunchbox::RNG rng; 70 | 71 | TESTLOOP(uint8_t, 0, 255); 72 | TESTLOOP(uint16_t, 50, 65000); 73 | TESTLOOP(uint32_t, 1 << 20, 1u << 12); 74 | TESTLOOP(uint64_t, 1ull << 52, 1ull << 12); 75 | 76 | TESTLOOP(int8_t, -126, 127); 77 | TESTLOOP(int16_t, -32000, 32000); 78 | TESTLOOP(int32_t, -(1 << 5), 1 << 5); 79 | TESTLOOP(int64_t, -(1 << 10), 1 << 10); 80 | 81 | TESTLOOP(float, 0.1f, 0.9f); 82 | TESTLOOP(double, 0.1, 0.9); 83 | 84 | testSpeed(); 85 | testSpeed(); 86 | testSpeed(); 87 | testSpeed(); 88 | testSpeed(); 89 | 90 | TEST(lunchbox::exit()); 91 | return EXIT_SUCCESS; 92 | } 93 | -------------------------------------------------------------------------------- /tests/serialize.h: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2012, Daniel Nachbaur 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #ifndef LUNCHBOX_SERIALIZE_H 19 | #define LUNCHBOX_SERIALIZE_H 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | 27 | #include 28 | #include 29 | 30 | #pragma warning(push) 31 | #pragma warning(disable : 4996) 32 | #include 33 | #include 34 | #pragma warning(pop) 35 | 36 | template 37 | void textSave(const T& object, std::ostream& os) 38 | { 39 | lunchbox::saveAny(object, os); 40 | } 41 | 42 | template 43 | void textLoad(T& object, std::istream& is) 44 | { 45 | lunchbox::loadAny(object, is); 46 | } 47 | 48 | template 49 | void binarySave(const T& object, std::ostream& os) 50 | { 51 | lunchbox::saveAny(object, os); 52 | } 53 | 54 | template 55 | void binaryLoad(T& object, std::istream& is) 56 | { 57 | lunchbox::loadAny(object, is); 58 | } 59 | 60 | template 61 | void textSerialize(const T& object, T& loadedObject) 62 | { 63 | std::stringstream stream; 64 | textSave(object, stream); 65 | textLoad(loadedObject, stream); 66 | } 67 | 68 | template 69 | void textSerializeAndTest(const T& object) 70 | { 71 | T loadedObject; 72 | textSerialize(object, loadedObject); 73 | TEST(object == loadedObject); 74 | } 75 | 76 | template 77 | void binarySerialize(const T& object, T& loadedObject) 78 | { 79 | std::stringstream stream; 80 | binarySave(object, stream); 81 | binaryLoad(loadedObject, stream); 82 | } 83 | 84 | template 85 | void binarySerializeAndTest(const T& object) 86 | { 87 | T loadedObject; 88 | binarySerialize(object, loadedObject); 89 | TEST(object == loadedObject); 90 | } 91 | 92 | struct Foo 93 | { 94 | bool operator==(const Foo& rhs) const 95 | { 96 | if (this == &rhs) 97 | return true; 98 | 99 | return i == rhs.i && f == rhs.f && b == rhs.b && s == rhs.s; 100 | } 101 | 102 | bool operator!=(const Foo& rhs) const { return !(*this == rhs); } 103 | int i; 104 | float f; 105 | bool b; 106 | std::string s; 107 | 108 | template 109 | void serialize(Archive& ar, const unsigned int /*version*/) 110 | { 111 | ar& i; 112 | ar& f; 113 | ar& b; 114 | ar& s; 115 | } 116 | }; 117 | 118 | SERIALIZABLEANY(Foo) 119 | 120 | #endif 121 | -------------------------------------------------------------------------------- /tests/string.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2017, Stefan.Eilemann@epfl.ch 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | int main(int, char**) 22 | { 23 | TEST(lunchbox::string::prepend("", " ") == " "); 24 | TEST(lunchbox::string::prepend("foo", " ") == " foo"); 25 | TEST(lunchbox::string::prepend("foo\nbar", " ") == " foo\n bar"); 26 | TEST(lunchbox::string::prepend("\nfoo\nbar", " ") == " \n foo\n bar"); 27 | TEST(lunchbox::string::prepend("\nfoo\nbar", "") == "\nfoo\nbar"); 28 | TEST(lunchbox::string::prepend("\nfoo\nbar", "deine mutter ") == 29 | "deine mutter \ndeine mutter foo\ndeine mutter bar"); 30 | return EXIT_SUCCESS; 31 | } 32 | -------------------------------------------------------------------------------- /tests/thread.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2006-2014, Stefan Eilemann 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #define NTHREADS 256 25 | 26 | class LoadThread : public lunchbox::Thread 27 | { 28 | public: 29 | virtual ~LoadThread() {} 30 | virtual void run() {} 31 | }; 32 | 33 | class InitThread : public LoadThread 34 | { 35 | public: 36 | InitThread() 37 | : initLeft(false) 38 | { 39 | } 40 | virtual ~InitThread() {} 41 | virtual bool init() 42 | { 43 | lunchbox::sleep(10); 44 | initLeft = true; 45 | return true; 46 | } 47 | 48 | virtual void run() 49 | { 50 | TEST(!join()); 51 | exit(); 52 | } 53 | 54 | bool initLeft; 55 | }; 56 | 57 | class FailThread : public InitThread 58 | { 59 | public: 60 | virtual ~FailThread() {} 61 | virtual bool init() { return false; } 62 | }; 63 | 64 | int main(int, char**) 65 | { 66 | LoadThread loadThreads[NTHREADS]; 67 | lunchbox::Clock clock; 68 | 69 | for (size_t i = 0; i < NTHREADS; ++i) 70 | TEST(loadThreads[i].start()); 71 | 72 | for (size_t i = 0; i < NTHREADS; ++i) 73 | TEST(loadThreads[i].join()); 74 | const float time = clock.getTimef(); 75 | std::cout << "Spawned and joined " << NTHREADS << " loadThreads in " << time 76 | << " ms (" << (NTHREADS / time) << " threads/ms)" << std::endl; 77 | 78 | for (size_t i = 0; i < NTHREADS; ++i) 79 | TEST(loadThreads[i].isStopped()); 80 | 81 | InitThread initThreads[NTHREADS]; 82 | 83 | clock.reset(); 84 | for (size_t i = 0; i < NTHREADS; ++i) 85 | { 86 | TEST(initThreads[i].start()); 87 | TEST(initThreads[i].initLeft == true); 88 | } 89 | #ifdef _MSC_VER // resolution of Sleep is not high enough... 90 | TESTINFO(clock.getTimef() + 1.f > NTHREADS * 10, clock.getTimef()); 91 | #else 92 | TESTINFO(clock.getTimef() > NTHREADS * 10, clock.getTimef()); 93 | #endif 94 | 95 | for (size_t i = 0; i < NTHREADS; ++i) 96 | TEST(initThreads[i].join()); 97 | 98 | FailThread failThread; 99 | TEST(!failThread.start()); 100 | TEST(!failThread.isRunning()); 101 | TEST(failThread.isStopped()); 102 | TEST(!failThread.join()); 103 | 104 | return EXIT_SUCCESS; 105 | } 106 | -------------------------------------------------------------------------------- /tests/threadPool.cpp: -------------------------------------------------------------------------------- 1 | 2 | /* Copyright (c) 2016-2017, Mohamed-Ghaith Kaabi 3 | * 4 | * This library is free software; you can redistribute it and/or modify it under 5 | * the terms of the GNU Lesser General Public License version 2.1 as published 6 | * by the Free Software Foundation. 7 | * 8 | * This library is distributed in the hope that it will be useful, but WITHOUT 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 10 | * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 11 | * details. 12 | * 13 | * You should have received a copy of the GNU Lesser General Public License 14 | * along with this library; if not, write to the Free Software Foundation, Inc., 15 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 | */ 17 | #define BOOST_TEST_MODULE ThreadPool 18 | #include 19 | 20 | #include 21 | 22 | BOOST_AUTO_TEST_CASE(size) 23 | { 24 | lunchbox::ThreadPool threadPool{3}; 25 | BOOST_CHECK(threadPool.getSize() == 3); 26 | } 27 | 28 | BOOST_AUTO_TEST_CASE(queue) 29 | { 30 | lunchbox::ThreadPool threadPool{1}; 31 | for (size_t i = 0; i < 10; ++i) 32 | { 33 | threadPool.postDetached([] { 34 | std::this_thread::sleep_for( 35 | std::chrono::milliseconds(50 + rand() % 50)); 36 | }); 37 | } 38 | 39 | // append a dummy task 40 | threadPool.post([]() {}).get(); 41 | BOOST_CHECK(!threadPool.hasPendingJobs()); 42 | } 43 | 44 | BOOST_AUTO_TEST_CASE(dispatcher) 45 | { 46 | std::vector > futures; 47 | 48 | for (size_t i = 0; i < lunchbox::ThreadPool::getInstance().getSize() * 2; 49 | ++i) 50 | { 51 | futures.push_back(lunchbox::ThreadPool::getInstance().post([] { 52 | std::this_thread::sleep_for( 53 | std::chrono::milliseconds(50 + rand() % 50)); 54 | return 42; 55 | })); 56 | } 57 | 58 | BOOST_CHECK(lunchbox::ThreadPool::getInstance().hasPendingJobs()); 59 | 60 | for (auto& future : futures) 61 | { 62 | BOOST_CHECK(future.get() == 42); 63 | } 64 | } 65 | 66 | int task() 67 | { 68 | std::this_thread::sleep_for(std::chrono::milliseconds(50 + rand() % 50)); 69 | return 42; 70 | } 71 | 72 | BOOST_AUTO_TEST_CASE(join) 73 | { 74 | std::vector > futures; 75 | 76 | { 77 | lunchbox::ThreadPool threadPool{4}; 78 | for (size_t i = 0; i < 100; ++i) 79 | { 80 | futures.push_back(threadPool.post(task)); 81 | } 82 | } // blocks until all tasks are done 83 | 84 | for (const std::future& future : futures) 85 | { 86 | BOOST_CHECK(future.wait_for(std::chrono::milliseconds(0)) == 87 | std::future_status::ready); 88 | } 89 | } 90 | --------------------------------------------------------------------------------