10 files changed, 1 insertions(+), 778 deletions(-)
M VERSION
D lfrtm/.gitlab-ci.yml
D lfrtm/COPYING
D lfrtm/README.md
D lfrtm/VERSION
D lfrtm/gitlab-ci/generic.yml
D lfrtm/lfrtm/lfrtm.h
D lfrtm/meson.build
D lfrtm/test/dummy_calloc.c
D lfrtm/test/lfrtm_test.c
M VERSION => VERSION +1 -1
@@ 1,1 1,1 @@
-0.1.6517
+0.1.6535
D lfrtm/.gitlab-ci.yml => lfrtm/.gitlab-ci.yml +0 -2
@@ 1,2 0,0 @@
-include:
- - local: 'gitlab-ci/generic.yml'
D lfrtm/COPYING => lfrtm/COPYING +0 -201
@@ 1,201 0,0 @@
- The Artistic License 2.0
-
- Copyright (c) 2000-2006, The Perl Foundation.
-
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-Preamble
-
-This license establishes the terms under which a given free software
-Package may be copied, modified, distributed, and/or redistributed.
-The intent is that the Copyright Holder maintains some artistic
-control over the development of that Package while still keeping the
-Package available as open source and free software.
-
-You are always permitted to make arrangements wholly outside of this
-license directly with the Copyright Holder of a given Package. If the
-terms of this license do not permit the full use that you propose to
-make of the Package, you should contact the Copyright Holder and seek
-a different licensing arrangement.
-
-Definitions
-
- "Copyright Holder" means the individual(s) or organization(s)
- named in the copyright notice for the entire Package.
-
- "Contributor" means any party that has contributed code or other
- material to the Package, in accordance with the Copyright Holder's
- procedures.
-
- "You" and "your" means any person who would like to copy,
- distribute, or modify the Package.
-
- "Package" means the collection of files distributed by the
- Copyright Holder, and derivatives of that collection and/or of
- those files. A given Package may consist of either the Standard
- Version, or a Modified Version.
-
- "Distribute" means providing a copy of the Package or making it
- accessible to anyone else, or in the case of a company or
- organization, to others outside of your company or organization.
-
- "Distributor Fee" means any fee that you charge for Distributing
- this Package or providing support for this Package to another
- party. It does not mean licensing fees.
-
- "Standard Version" refers to the Package if it has not been
- modified, or has been modified only in ways explicitly requested
- by the Copyright Holder.
-
- "Modified Version" means the Package, if it has been changed, and
- such changes were not explicitly requested by the Copyright
- Holder.
-
- "Original License" means this Artistic License as Distributed with
- the Standard Version of the Package, in its current version or as
- it may be modified by The Perl Foundation in the future.
-
- "Source" form means the source code, documentation source, and
- configuration files for the Package.
-
- "Compiled" form means the compiled bytecode, object code, binary,
- or any other form resulting from mechanical transformation or
- translation of the Source form.
-
-
-Permission for Use and Modification Without Distribution
-
-(1) You are permitted to use the Standard Version and create and use
-Modified Versions for any purpose without restriction, provided that
-you do not Distribute the Modified Version.
-
-
-Permissions for Redistribution of the Standard Version
-
-(2) You may Distribute verbatim copies of the Source form of the
-Standard Version of this Package in any medium without restriction,
-either gratis or for a Distributor Fee, provided that you duplicate
-all of the original copyright notices and associated disclaimers. At
-your discretion, such verbatim copies may or may not include a
-Compiled form of the Package.
-
-(3) You may apply any bug fixes, portability changes, and other
-modifications made available from the Copyright Holder. The resulting
-Package will still be considered the Standard Version, and as such
-will be subject to the Original License.
-
-
-Distribution of Modified Versions of the Package as Source
-
-(4) You may Distribute your Modified Version as Source (either gratis
-or for a Distributor Fee, and with or without a Compiled form of the
-Modified Version) provided that you clearly document how it differs
-from the Standard Version, including, but not limited to, documenting
-any non-standard features, executables, or modules, and provided that
-you do at least ONE of the following:
-
- (a) make the Modified Version available to the Copyright Holder
- of the Standard Version, under the Original License, so that the
- Copyright Holder may include your modifications in the Standard
- Version.
-
- (b) ensure that installation of your Modified Version does not
- prevent the user installing or running the Standard Version. In
- addition, the Modified Version must bear a name that is different
- from the name of the Standard Version.
-
- (c) allow anyone who receives a copy of the Modified Version to
- make the Source form of the Modified Version available to others
- under
-
- (i) the Original License or
-
- (ii) a license that permits the licensee to freely copy,
- modify and redistribute the Modified Version using the same
- licensing terms that apply to the copy that the licensee
- received, and requires that the Source form of the Modified
- Version, and of any works derived from it, be made freely
- available in that license fees are prohibited but Distributor
- Fees are allowed.
-
-
-Distribution of Compiled Forms of the Standard Version
-or Modified Versions without the Source
-
-(5) You may Distribute Compiled forms of the Standard Version without
-the Source, provided that you include complete instructions on how to
-get the Source of the Standard Version. Such instructions must be
-valid at the time of your distribution. If these instructions, at any
-time while you are carrying out such distribution, become invalid, you
-must provide new instructions on demand or cease further distribution.
-If you provide valid instructions or cease distribution within thirty
-days after you become aware that the instructions are invalid, then
-you do not forfeit any of your rights under this license.
-
-(6) You may Distribute a Modified Version in Compiled form without
-the Source, provided that you comply with Section 4 with respect to
-the Source of the Modified Version.
-
-
-Aggregating or Linking the Package
-
-(7) You may aggregate the Package (either the Standard Version or
-Modified Version) with other packages and Distribute the resulting
-aggregation provided that you do not charge a licensing fee for the
-Package. Distributor Fees are permitted, and licensing fees for other
-components in the aggregation are permitted. The terms of this license
-apply to the use and Distribution of the Standard or Modified Versions
-as included in the aggregation.
-
-(8) You are permitted to link Modified and Standard Versions with
-other works, to embed the Package in a larger work of your own, or to
-build stand-alone binary or bytecode versions of applications that
-include the Package, and Distribute the result without restriction,
-provided the result does not expose a direct interface to the Package.
-
-
-Items That are Not Considered Part of a Modified Version
-
-(9) Works (including, but not limited to, modules and scripts) that
-merely extend or make use of the Package, do not, by themselves, cause
-the Package to be a Modified Version. In addition, such works are not
-considered parts of the Package itself, and are not subject to the
-terms of this license.
-
-
-General Provisions
-
-(10) Any use, modification, and distribution of the Standard or
-Modified Versions is governed by this Artistic License. By using,
-modifying or distributing the Package, you accept this license. Do not
-use, modify, or distribute the Package, if you do not accept this
-license.
-
-(11) If your Modified Version has been derived from a Modified
-Version made by someone other than you, you are nevertheless required
-to ensure that your Modified Version complies with the requirements of
-this license.
-
-(12) This license does not grant you the right to use any trademark,
-service mark, tradename, or logo of the Copyright Holder.
-
-(13) This license includes the non-exclusive, worldwide,
-free-of-charge patent license to make, have made, use, offer to sell,
-sell, import and otherwise transfer the Package with respect to any
-patent claims licensable by the Copyright Holder that are necessarily
-infringed by the Package. If you institute patent litigation
-(including a cross-claim or counterclaim) against any party alleging
-that the Package constitutes direct or contributory patent
-infringement, then this Artistic License to you shall terminate on the
-date that such litigation is filed.
-
-(14) Disclaimer of Warranty:
-THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS
-IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED
-WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
-NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL
-LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL
-BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
-DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF
-ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
D lfrtm/README.md => lfrtm/README.md +0 -40
@@ 1,40 0,0 @@
-# lfrtm
-
-## Minimalistic concurrent lock-free realtime-safe memory allocator
-
-### Properties
-
-* Is lock-free
-* Is wait-free
-* Is rt-safe
-* Uses a simplistic API
-
-### Build Status
-
-[![build status](https://gitlab.com/OpenMusicKontrollers/lfrtm/badges/master/build.svg)](https://gitlab.com/OpenMusicKontrollers/lfrtm/commits/master)
-
-### Build / test
-
- git clone https://git.open-music-kontrollers.ch/lv2/lfrtm
- cd lfrtm
- meson build
- cd build
- ninja -j4
- ninja test
-
-### License
-
-Copyright (c) 2018 Hanspeter Portner (dev@open-music-kontrollers.ch)
-
-This is free software: you can redistribute it and/or modify
-it under the terms of the Artistic License 2.0 as published by
-The Perl Foundation.
-
-This source 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
-Artistic License 2.0 for more details.
-
-You should have received a copy of the Artistic License 2.0
-along the source as a COPYING file. If not, obtain it from
-<http://www.perlfoundation.org/artistic_license_2_0>.
D lfrtm/VERSION => lfrtm/VERSION +0 -1
D lfrtm/gitlab-ci/generic.yml => lfrtm/gitlab-ci/generic.yml +0 -106
@@ 1,106 0,0 @@
-stages:
- - build
- - deploy
-
-variables:
- PKG_CONFIG_PATH: "/opt/lv2/lib/pkgconfig:/opt/${CI_BUILD_NAME}/lib/pkgconfig:/usr/lib/${CI_BUILD_NAME}/pkgconfig"
- BUILD_OPTS : ""
-
-.native_template: &native_definition
- stage: build
- script:
- - meson --prefix="${CI_PROJECT_DIR}/${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" -Dlv2libdir="" --cross-file "${CI_BUILD_NAME}" ${BUILD_OPTS} build
- - ninja -C build
- - ninja -C build test
- - ninja -C build install
-
- - scan-build --status-bugs meson --prefix="${CI_PROJECT_DIR}/${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" -Dlv2libdir="" --cross-file "${CI_BUILD_NAME}" ${BUILD_OPTS} scanbuild
- - scan-build --status-bugs ninja -C scanbuild
- - scan-build --status-bugs ninja -C scanbuild test
- artifacts:
- name: "${CI_PROJECT_NAME}-$(cat VERSION)-${CI_BUILD_NAME}"
- paths:
- - "${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}/"
-
-.cross_template: &cross_definition
- stage: build
- script:
- - meson --prefix="${CI_PROJECT_DIR}/${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}" -Dlv2libdir="" --cross-file "${CI_BUILD_NAME}" ${BUILD_OPTS} build
- - ninja -C build
- - ninja -C build test
- - ninja -C build install
- artifacts:
- name: "${CI_PROJECT_NAME}-$(cat VERSION)-${CI_BUILD_NAME}"
- paths:
- - "${CI_PROJECT_NAME}-$(cat VERSION)/${CI_BUILD_NAME}/"
-
-# build
-.universal_linux_template_stretch: &universal_linux_definition_stretch
- image: ventosus/universal-linux-gnu:stretch
- <<: *cross_definition
-
-.universal_linux_template_buster: &universal_linux_definition_buster
- image: ventosus/universal-linux-gnu:buster
- <<: *native_definition
-
-.universal_linux_template_bullseye: &universal_linux_definition_bullseye
- image: ventosus/universal-linux-gnu:bullseye
- <<: *native_definition
-
-.arm_linux_template_stretch: &arm_linux_definition_stretch
- image: ventosus/arm-linux-gnueabihf:stretch
- <<: *cross_definition
-
-.arm_linux_template_buster: &arm_linux_definition_buster
- image: ventosus/arm-linux-gnueabihf:buster
- <<: *cross_definition
-
-.arm_linux_template_bullseye: &arm_linux_definition_bullseye
- image: ventosus/arm-linux-gnueabihf:bullseye
- <<: *cross_definition
-
-# build
-x86_64-linux-gnu-stretch:
- <<: *universal_linux_definition_stretch
-
-x86_64-linux-gnu-buster:
- <<: *universal_linux_definition_buster
-
-x86_64-linux-gnu-bullseye:
- <<: *universal_linux_definition_bullseye
-
-i686-linux-gnu-stretch:
- <<: *universal_linux_definition_stretch
-
-i686-linux-gnu-buster:
- <<: *universal_linux_definition_buster
-
-i686-linux-gnu-bullseye:
- <<: *universal_linux_definition_bullseye
-
-arm-linux-gnueabihf-stretch:
- <<: *arm_linux_definition_stretch
-
-arm-linux-gnueabihf-buster:
- <<: *arm_linux_definition_buster
-
-arm-linux-gnueabihf-bullseye:
- <<: *arm_linux_definition_bullseye
-
-aarch64-linux-gnu-stretch:
- <<: *arm_linux_definition_stretch
-
-aarch64-linux-gnu-buster:
- <<: *arm_linux_definition_buster
-
-aarch64-linux-gnu-bullseye:
- <<: *arm_linux_definition_bullseye
-
-pack:
- stage: deploy
- script:
- - echo 'packing up'
- artifacts:
- name: "${CI_PROJECT_NAME}-$(cat VERSION)"
- paths:
- - "${CI_PROJECT_NAME}-$(cat VERSION)/"
D lfrtm/lfrtm/lfrtm.h => lfrtm/lfrtm/lfrtm.h +0 -227
@@ 1,227 0,0 @@
-/*
- * Copyright (c) 2018 Hanspeter Portner (dev@open-music-kontrollers.ch)
- *
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the Artistic License 2.0 as published by
- * The Perl Foundation.
- *
- * This source 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
- * Artistic License 2.0 for more details.
- *
- * You should have received a copy of the Artistic License 2.0
- * along the source as a COPYING file. If not, obtain it from
- * http://www.perlfoundation.org/artistic_license_2_0.
- */
-
-#ifndef _LFRTM_H
-#define _LFRTM_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <string.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <stdbool.h>
-#include <stdatomic.h>
-
-#ifndef LFRTM_API
-# define LFRTM_API static
-#endif
-
-typedef struct _lfrtm_t lfrtm_t;
-
-// non-rt
-LFRTM_API lfrtm_t *
-lfrtm_new(unsigned num, size_t minimum);
-
-// non-rt
-LFRTM_API int
-lfrtm_free(lfrtm_t *lfrtm);
-
-// non-rt
-LFRTM_API int
-lfrtm_inject(lfrtm_t *lfrtm);
-
-// rt-safe
-LFRTM_API void *
-lfrtm_alloc(lfrtm_t *lfrtm, size_t size, bool *more);
-
-#ifdef LFRTM_IMPLEMENTATION
-
-struct _lfrtm_t {
- unsigned num;
- size_t size;
- size_t shift;
- size_t mask;
- atomic_size_t offset;
- atomic_uintptr_t pools [];
-};
-
-LFRTM_API lfrtm_t *
-lfrtm_new(unsigned num, size_t minimum)
-{
- lfrtm_t *lfrtm = calloc(1, sizeof(lfrtm_t) + num*sizeof(atomic_uintptr_t));
- if(!lfrtm)
- {
- return NULL;
- }
-
- lfrtm->num = num;
-
- for(lfrtm->shift = 0; lfrtm->shift < sizeof(size_t)*8; lfrtm->shift++)
- {
- const size_t sz = 1 << lfrtm->shift;
-
- if(sz < minimum)
- {
- continue;
- }
-
- lfrtm->size = sz;
- lfrtm->mask = sz - 1;
- break;
- }
-
- atomic_init(&lfrtm->offset, 0);
- atomic_init(&lfrtm->pools[0], UINTPTR_MAX);
- for(unsigned i = 1; i < lfrtm->num; i++)
- {
- atomic_init(&lfrtm->pools[i], 0);
- }
-
- if(lfrtm_inject(lfrtm) == 0)
- {
- return lfrtm;
- }
-
- free(lfrtm);
- return NULL;
-}
-
-LFRTM_API int
-lfrtm_free(lfrtm_t *lfrtm)
-{
- if(!lfrtm)
- {
- return -1;
- }
-
- for(unsigned idx = 0; idx < lfrtm->num; idx++)
- {
- uintptr_t pool = atomic_exchange(&lfrtm->pools[idx], 0);
- if( (pool != 0) && (pool != UINTPTR_MAX) )
- {
- free((void *)pool);
- }
- }
-
- free(lfrtm);
- return 0;
-}
-
-LFRTM_API int
-lfrtm_inject(lfrtm_t *lfrtm)
-{
- if(!lfrtm)
- {
- return -1;
- }
-
- void *pool = calloc(lfrtm->size, sizeof(uint8_t));
- if(!pool)
- {
- return -1;
- }
-
- for(unsigned idx = 0; idx < lfrtm->num; idx++)
- {
- const uintptr_t desired = (const uintptr_t)pool;
- uintptr_t expected = UINTPTR_MAX;
- const bool match = atomic_compare_exchange_strong(&lfrtm->pools[idx],
- &expected, desired);
-
- if(match) // we have successfully taken this slot first
- {
- return 0;
- }
- else if(expected == 0) // sentinel, e.g. nothing to do
- {
- break;
- }
- }
-
- free(pool);
- return -1; // double injection
-}
-
-LFRTM_API void *
-lfrtm_alloc(lfrtm_t *lfrtm, size_t size, bool *more)
-{
- if( !lfrtm || (size > lfrtm->size) || !more)
- {
- return NULL;
- }
-
- *more = false;
-
- uintptr_t pool;
- size_t offset;
- unsigned idx;
-
- while(true)
- {
- offset = atomic_fetch_add(&lfrtm->offset, size);
-
- idx = offset >> lfrtm->shift; // number of overflows
- offset &= lfrtm->mask; // remainder
-
- if(idx >= lfrtm->num) // pool overflow
- {
- return NULL;
- }
-
- if(offset + size > lfrtm->size) // size does not fit in pool
- {
- continue; // e.g. skip to next pool
- }
-
- while(true)
- {
- pool = atomic_load(&lfrtm->pools[idx]);
-
- if(pool == UINTPTR_MAX) // injection ongoing
- {
- continue; // waiting for injection
- }
- else if(pool == 0) // missing injection request
- {
- return NULL;
- }
-
- break;
- }
-
- break;
- }
-
- if( (++idx < lfrtm->num) && (atomic_load(&lfrtm->pools[idx]) == 0) )
- {
- const uintptr_t desired = UINTPTR_MAX;
- uintptr_t expected = 0;
- *more = atomic_compare_exchange_strong(&lfrtm->pools[idx], &expected, desired);
- }
-
- return (void *)(pool + offset);
-}
-
-#endif // LFRTM_IMPLEMENTATION
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //_LFRTM_H
D lfrtm/meson.build => lfrtm/meson.build +0 -59
@@ 1,59 0,0 @@
-project('lfrtm', 'c', default_options : [
- 'buildtype=release',
- 'warning_level=3',
- 'werror=true',
- 'b_lto=false',
- 'c_std=c11'])
-
-version = run_command('cat', 'VERSION').stdout().strip()
-
-add_project_arguments('-D_GNU_SOURCE', language : 'c')
-
-conf_data = configuration_data()
-cc = meson.get_compiler('c')
-
-thread_dep = dependency('threads')
-deps = [thread_dep]
-
-c_args = []
-
-if host_machine.system() == 'darwin'
- c_args += '-Wno-deprecated-declarations' # shm_init/destroy
-endif
-
-dummy_calloc = shared_library('dummy_calloc',
- join_paths('test', 'dummy_calloc.c'),
- c_args : c_args,
- dependencies : deps,
- install : false)
-
-lfrtm_test = executable('lfrtm_test',
- join_paths('test', 'lfrtm_test.c'),
- c_args : c_args,
- dependencies : deps,
- install : false)
-
-test(' 1 threads', lfrtm_test,
- args : ['1'],
- timeout : 240)
-test(' 2 threads', lfrtm_test,
- args : ['1'],
- timeout : 240)
-test(' 4 threads', lfrtm_test,
- args : ['1'],
- timeout : 240)
-test(' 8 threads', lfrtm_test,
- args : ['1'],
- timeout : 240)
-if host_machine.system() == 'linux'
- test('16 threads', lfrtm_test,
- args : ['1'],
- timeout : 240)
- test('32 threads', lfrtm_test,
- args : ['1'],
- timeout : 240)
-endif
-#test('dummy alloc', lfrtm_test,
-# args : ['2', '1'],
-# timeout : 240,
-# env : ['LD_PRELOAD='+dummy_calloc.full_path()])
D lfrtm/test/dummy_calloc.c => lfrtm/test/dummy_calloc.c +0 -23
@@ 1,23 0,0 @@
-#include <unistd.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-void *
-calloc(size_t nmemb, size_t size)
-{
- if( (nmemb == 1) && (size == 1) )
- {
- return NULL;
- }
-
- void *data = malloc(nmemb * size);
- if(data)
- {
- memset(data, 0x0, nmemb * size);
- return data;
- }
-
- return NULL;
-}
D lfrtm/test/lfrtm_test.c => lfrtm/test/lfrtm_test.c +0 -118
@@ 1,118 0,0 @@
-/*
- * Copyright (c) 2018 Hanspeter Portner (dev@open-music-kontrollers.ch)
- *
- * This is free software: you can redistribute it and/or modify
- * it under the terms of the Artistic License 2.0 as published by
- * The Perl Foundation.
- *
- * This source 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
- * Artistic License 2.0 for more details.
- *
- * You should have received a copy of the Artistic License 2.0
- * along the source as a COPYING file. If not, obtain it from
- * http://www.perlfoundation.org/artistic_license_2_0.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <pthread.h>
-#include <semaphore.h>
-
-#define LFRTM_IMPLEMENTATION
-#include <lfrtm/lfrtm.h>
-
-#define ITEM_SIZE 32
-#define NUM_POOLS 512
-#define POOL_SIZE 0x100000 // 1M
-
-sem_t sem;
-atomic_uint done = ATOMIC_VAR_INIT(0);
-atomic_bool flag = ATOMIC_VAR_INIT(false);
-
-static const uint8_t empty [ITEM_SIZE] = { 0x0 };
-
-static void *
-_thread(void *data)
-{
- lfrtm_t *lfrtm = data;
-
- for(unsigned i = 0; i < 0x10000; i++)
- {
- const size_t size = i % ITEM_SIZE + 1;
- bool more = false;
- assert(lfrtm_alloc(lfrtm, 0, NULL) == NULL);
- assert(lfrtm_alloc(NULL, 0, &more) == NULL);
- void *mem = lfrtm_alloc(lfrtm, size, &more);
- assert(mem);
-
- assert(memcmp(mem, empty, size) == 0);
- memset(mem, 0xff, size);
-
- if(more)
- {
- atomic_store(&flag, true);
- sem_post(&sem);
- }
- }
-
- atomic_fetch_add(&done, 1);
- sem_post(&sem);
-
- return NULL;
-}
-
-int
-main(int argc, char **argv)
-{
- pthread_t threads [32];
- assert(argc >= 2);
-
- const unsigned num_threads = atoi(argv[1]);
- const bool is_preloaded = (argc == 3) ? atoi(argv[2]) : false;
- assert( (num_threads > 0) && (num_threads <= 32) );
-
- if(is_preloaded)
- {
- // will fail on ldpreloaded calloc
- assert(lfrtm_new(NUM_POOLS, 0) == NULL);
- }
-
- lfrtm_t *lfrtm = lfrtm_new(NUM_POOLS, POOL_SIZE);
- assert(lfrtm);
-
- assert(sem_init(&sem, 0, 1) == 0);
-
- for(unsigned i = 0; i < num_threads; i++)
- {
- assert(pthread_create(&threads[i], NULL, _thread, lfrtm) == 0);
- }
-
- while(atomic_load(&done) != num_threads)
- {
- sem_wait(&sem);
-
- if(atomic_exchange(&flag, false))
- {
- assert(lfrtm_inject(lfrtm) == 0);
- }
- }
-
- // will trigger double injection
- assert(lfrtm_inject(NULL) != 0);
- assert(lfrtm_inject(lfrtm) != 0);
-
- for(unsigned i = 0; i < num_threads; i++)
- {
- assert(pthread_join(threads[i], NULL) == 0);
- }
-
- assert(sem_destroy(&sem) == 0);
-
- assert(lfrtm_free(lfrtm) == 0);
- assert(lfrtm_free(NULL) != 0);
-
- return 0;
-}