From 25dcdeed693cbebc2a8f63ec3ccdc3a6ba08c2ed Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Wed, 7 May 2025 21:57:53 +0200 Subject: [PATCH] Remove obsolete m-i-shared.h header --- README.md | 179 -------------------------- example/ex11-small-name.c | 1 - m-i-shared.h | 258 -------------------------------------- tests/test-mishared.c | 150 ---------------------- 4 files changed, 588 deletions(-) delete mode 100644 m-i-shared.h delete mode 100644 tests/test-mishared.c diff --git a/README.md b/README.md index a08dec67..73ef5970 100644 --- a/README.md +++ b/README.md @@ -197,7 +197,6 @@ Finally, headers for compatibility with non C11 compilers: The following headers are obsolete and will be removed in the next major release: * [m-concurrent.h](#m-concurrent): header for transforming a container into a concurrent container (thread safe), -* [m-i-shared.h](#m-i-shared): header for creating intrusive shared pointer of generic type (Thread Safe). * [m-mempool.h](#m-mempool): header for creating specialized & fast memory allocator, Each containers define their iterators (if it is meaningful). @@ -5085,184 +5084,6 @@ Create a new shared object initialized with its `INIT_SET` operator on the given This method is created only if the `INIT_SET` operator is defined. -_________________ - -### M-I-SHARED - -> [!NOTE] -> This header is obsolete: M-SHARED-PTR should be used instead. - -This header is for creating intrusive shared pointer. - -#### `ISHARED_PTR_INTERFACE(name, type)` - -Extend the definition of the structure of an object of type `type` by adding the -necessary interface to handle it as a shared pointer named `name`. -It shall be put within the structure definition of the object (See example). - -#### `ISHARED_PTR_STATIC_INIT(name, type)` - -Provide the static initialization value of an object defined with a -`ISHARED_PTR_INTERFACE` extra fields. It shall be used only for global -variables with the _init_once function. - -Usage (provided that the interface is used as the first element of the structure): - -```C -struct mystruct variable = { ISHARED_PTR_STATIC_INIT(ishared_double, struct mystruct) }; -``` - -#### `ISHARED_PTR_STATIC_DESIGNATED_INIT(name, type)` - -Provide the static initialization value of an object defined with a -`ISHARED_PTR_INTERFACE` extra fields. It shall be used only for global -variables with the _init_once function. - -It uses designated initializers to set the right fields. - -Usage: - -```C -struct mystruct variable = {ISHARED_PTR_STATIC_DESIGNATED_INIT(ishared_double, struct mystruct) }; -``` - -#### `ISHARED_PTR_DEF(name, type[, oplist])` -#### `ISHARED_PTR_DEF_AS(name, name_t, type[, oplist])` - -Define the associated methods to handle the shared pointer named `name` -as `static inline` functions. -A shared pointer is a mechanism to keep tracks of all `users` of an object -and performs an automatic destruction of the object whenever all users release -their need on this object. - -The destruction of the object is thread safe and occurs when the last user -of the object releases it. The destruction of the object implies: - -* calling the `CLEAR` operator to clear the object, -* calling the `DEL` operator to release the memory used by the object -(if the method has not been disabled). - -The object oplist is expected to have the following operators (`CLEAR` and `DEL`), -otherwise default methods are used. If there is no given oplist, the default -operators are also used. The created methods will use the operators to init, set -and clear the contained object. - -There are designed to work with buffers with policy `BUFFER_PUSH_INIT_POP_MOVE` -to send a shared pointer across multiple threads. - -It is recommended to use the intrusive shared pointer over the standard one if -possible. They are faster and cleaner. - -The default is to use heap allocated entities, which are allocated by `NEW` and -freed by `DEL`. - -It can be used for statically allocated entities. However, in this case, -you shall disable the operator `NEW` and `DEL` when expanding the oplist -so that the destruction doesn't try to free the objects, like this: - -```C -(NEW(0), DEL(0)) -``` - -`NEW` and `DEL` operators shall be either both defined, or both disabled. - -`ISHARED_PTR_DEF_AS` is the same as `ISHARED_PTR_DEF` except the name of the type `name_t` -is provided. - -Example (dynamic): - -```C -typedef struct mystruct_s { - ISHARED_PTR_INTERFACE(ishared_mystruct, struct mystruct_s); - char *message; -} mystruct_t; - -static inline void mystruct_init(mystruct_t *p) { p->message = NULL; } -static inline void mystruct_clear(mystruct_t *p) { free(p->message); } - -ISHARED_PTR_DEF(ishared_mystruct, mystruct_t, (INIT(mystruct_init), CLEAR(mystruct_clear M_IPTR))) - -void f(void) { - mystruct_t *p = ishared_mystruct_init_new(); - p->message = strdup ("Hello"); - buffer_mystruct_push(g_buff1, p); - buffer_mystruct_push(g_buff2, p); - ishared_mystruct_clear(p); -} -``` - -#### Created types - -The following types are automatically defined by the previous definition macro if not provided by the user: - -##### `name_t` - -It will define name_t as a pointer to shared counted object. -This is a synonymous to a pointer to the object. - -#### Specialized methods - -The following specialized methods are automatically created by the previous definition macro: - -##### `name_t name_init(type *object)` - -Return a shared pointer to `object` which owns `object`. -It initializes the private fields of `object` handling the shared pointer, -returning the same pointer to the object from a value point of view, -but with the shared pointer field initialized. - -As a consequence, the shared pointer part of `object` shall not have been initialized yet. -The other part of `object` may or may not be initialized before calling this method. - -##### `name_t name_init_set(name_t shared)` - -Return a new shared pointer to the same object than the one pointed by `shared`, -incrementing the ownership of the object. -This function is thread safe. - -##### `name_t name_init_new(void)` - -Allocate a new object, initialize it and return an initialized shared pointer to it. -The used allocation function is the `NEW` operator. - -This method is only created if the `INIT` and `NEW` methods are provided and not disabled. - -##### `name_t name_init_once(type *object)` - -Initialize the new object `object` and return an initialized shared pointer to it. -The `INIT` operator of `object` is ensured to be called only once, -even if multiple threads try to initialize it at the same time. -Once the object is fully cleared, the initialization function may occur once again. - -`object` shall be a global variable initialized with the -`ISHARED_PTR_STATIC_INIT` macro. - -This method is only created if the `INIT` and `NEW` methods are provided and not disabled. - -##### `void name_clear(name_t shared)` - -Clear the `shared` pointer, releasing ownership of the object -and destroying the shared object if no longer -any other `shared` pointers own it. -This function is thread safe. - -##### `void name_clear_ptr(name_t *shared)` - -Clear the shared pointer `*shared`, releasing ownership of the object -and destroying the shared object if no longer -any other `shared` pointers own it. -This function is thread safe. -Afterwards, `*shared` is set to NULL. - -##### `void name_set(name_t *shared1, name_t shared2)` - -Update the shared pointer `*shared1` to point to the same object than -the shared pointer `shared2`. -Destroy the shared object pointed by `*shared1` if no longer any other shared -pointers own it, set the shared pointer `shared` to the same object -than the one pointed by `src`. -This function is thread safe. - _________________ ### M-I-LIST diff --git a/example/ex11-small-name.c b/example/ex11-small-name.c index 05d955b4..2dac30b2 100644 --- a/example/ex11-small-name.c +++ b/example/ex11-small-name.c @@ -15,7 +15,6 @@ #include "m-generic.h" #include "m-genint.h" #include "m-i-list.h" -#include "m-i-shared.h" #include "m-list.h" #include "m-mempool.h" #include "m-prioqueue.h" diff --git a/m-i-shared.h b/m-i-shared.h deleted file mode 100644 index b9324b14..00000000 --- a/m-i-shared.h +++ /dev/null @@ -1,258 +0,0 @@ -/* - * M*LIB - INTRUSIVE SHARED PTR Module - * - * Copyright (c) 2017-2025, Patrick Pelissier - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * + Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * + Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#ifndef MSTARLIB_I_SHARED_PTR_H -#define MSTARLIB_I_SHARED_PTR_H - -#include "m-core.h" -#include "m-atomic.h" - -#if defined(__STDC_VERSION__) && __STDC_VERSION__ > 201710L -#warning The header m-i-shared.h is obsolete. Use m-shared-ptr header instead. -#endif - -M_BEGIN_PROTECTED_CODE - -/* Define the oplist of a intrusive shared pointer. - USAGE: ISHARED_OPLIST(name [, oplist_of_the_type]) */ -#define M_ISHARED_PTR_OPLIST(...) \ - M_ISHAR3D_PTR_OPLIST_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((__VA_ARGS__, M_BASIC_OPLIST), \ - (__VA_ARGS__ ))) - - -/* Interface to add to a structure to allow intrusive support. - name: name of the intrusive shared pointer. - type: name of the type of the structure (aka. struct test_s) - not used currently. - NOTE: There can be only one interface of this kind in a type! */ -#define M_ISHARED_PTR_INTERFACE(name, type) \ - atomic_int M_F(name, _cpt) - - -/* Value of the interface field for static initialization (Uses C99 designated element). */ -#define M_ISHARED_PTR_STATIC_DESIGNATED_INIT(name, type) \ - .M_F(name, _cpt) = M_ATOMIC_VAR_INIT(0) - -/* Value of the interface field for static initialization (Uses C89 designated element). */ -#define M_ISHARED_PTR_STATIC_INIT(name, type) \ - M_ATOMIC_VAR_INIT(0) - - -/* Define the intrusive shared pointer type and its M_INLINE functions. - USAGE: ISHARED_PTR_DEF(name, type, [, oplist]) */ -#define M_ISHARED_PTR_DEF(name, ...) \ - M_ISHARED_PTR_DEF_AS(name, M_F(name,_t), __VA_ARGS__) - - -/* Define the intrusive shared pointer type and its M_INLINE functions - as the name name_t - USAGE: ISHARED_PTR_DEF_AS(name, name_t, type, [, oplist]) */ -#define M_ISHARED_PTR_DEF_AS(name, name_t, ...) \ - M_BEGIN_PROTECTED_CODE \ - M_ISHAR3D_PTR_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), name_t ), \ - (name, __VA_ARGS__ , name_t ))) \ - M_END_PROTECTED_CODE - - -/*****************************************************************************/ -/******************************** INTERNAL ***********************************/ -/*****************************************************************************/ - -// Deferred evaluation -#define M_ISHAR3D_PTR_OPLIST_P1(arg) M_ISHAR3D_PTR_OPLIST_P2 arg - -/* Validation of the given oplist */ -#define M_ISHAR3D_PTR_OPLIST_P2(name, oplist) \ - M_IF_OPLIST(oplist)(M_ISHAR3D_PTR_OPLIST_P3, M_ISHAR3D_PTR_OPLIST_FAILURE)(name, oplist) - -/* Prepare a clean compilation failure */ -#define M_ISHAR3D_PTR_OPLIST_FAILURE(name, oplist) \ - ((M_LIB_ERROR(ARGUMENT_OF_ISHARED_PTR_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) - -// Define the oplist -#define M_ISHAR3D_PTR_OPLIST_P3(name, oplist) ( \ - INIT(M_INIT_DEFAULT), \ - INIT_SET(API_4(M_F(name, _init_set))), \ - SET(M_F(name, _set) M_IPTR), \ - CLEAR(M_F(name, _clear)), \ - RESET(M_F(name, _reset) M_IPTR), \ - NAME(name), \ - TYPE(M_F(name, _ct)), GENTYPE(struct M_F(name,_s)*), \ - OPLIST(oplist), \ - SUBTYPE(M_F(name, _subtype_ct)) \ - ) - - -/******************************** INTERNAL ***********************************/ - -// Deferred evaluation -#define M_ISHAR3D_PTR_DEF_P1(arg) M_ID( M_ISHAR3D_PTR_DEF_P2 arg ) - -/* Validate the oplist before going further */ -#define M_ISHAR3D_PTR_DEF_P2(name, type, oplist, shared_t) \ - M_IF_OPLIST(oplist)(M_ISHAR3D_PTR_DEF_P3, M_ISHAR3D_PTR_DEF_FAILURE)(name, type, oplist, shared_t) - -/* Stop processing with a compilation failure */ -#define M_ISHAR3D_PTR_DEF_FAILURE(name, type, oplist, shared_t) \ - M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(ISHARED_PTR_DEF): the given argument is not a valid oplist: " #oplist) - -#define M_ISHAR3D_PTR_DEF_P3(name, type, oplist, shared_t) \ - M_ISHAR3D_PTR_DEF_TYPE(name, type, oplist, shared_t) \ - M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ - M_ISHAR3D_PTR_DEF_CORE(name, type, oplist, shared_t) \ - -/* Define the types */ -#define M_ISHAR3D_PTR_DEF_TYPE(name, type, oplist, shared_t) \ - \ - /* The shared pointer is only a pointer to the type */ \ - typedef type *shared_t; \ - \ - /* Define internal types for oplist */ \ - typedef shared_t M_F(name, _ct); \ - typedef type M_F(name, _subtype_ct); \ - -/* Define the core functions */ -#define M_ISHAR3D_PTR_DEF_CORE(name, type, oplist, shared_t) \ - \ - M_INLINE shared_t \ - M_F(name, _init)(type *ptr) \ - { \ - /* Initialize the type referenced by the pointer */ \ - if (M_LIKELY (ptr != NULL)) { \ - atomic_init(&ptr->M_F(name, _cpt), 2); \ - } \ - return ptr; \ - } \ - \ - M_INLINE shared_t \ - M_F(name, _init_set)(shared_t shared) \ - { \ - if (M_LIKELY (shared != NULL)) { \ - int n = atomic_fetch_add(&(shared->M_F(name, _cpt)), 2); \ - (void) n; \ - } \ - return shared; \ - } \ - \ - M_IF_METHOD(INIT, oplist)( \ - M_IF_DISABLED_METHOD(NEW, oplist) \ - ( \ - /* This function is only for static object */ \ - M_INLINE shared_t \ - M_F(name, _init_once)(type *shared) \ - { \ - if (M_LIKELY (shared != NULL)) { \ - /* Pretty much like atomic_add, except the first one increment by 1, others by 2 */ \ - int o = atomic_load(&(shared->M_F(name, _cpt))); \ - int n; \ - do { \ - n = o + 1 + (o != 0); \ - } while (!atomic_compare_exchange_strong(&(shared->M_F(name, _cpt)), &o, n)); \ - if (o == 0) { \ - /* Partial initialization: _cpt is odd */ \ - /* Call the INIT function once */ \ - M_CALL_INIT(oplist, *shared); \ - /* Finish initialization: _cpt is even */ \ - atomic_fetch_add(&(shared->M_F(name, _cpt)), 1); \ - } else if ( (o&1) != 0) { \ - /* Not fully initialized yet: wait for initialization */ \ - m_core_backoff_ct bkoff; \ - m_core_backoff_init(bkoff); \ - /* Wait for _cpt to be _even */ \ - while ((atomic_load(&(shared->M_F(name, _cpt)))&1) != 0 ) { \ - m_core_backoff_wait(bkoff); \ - } \ - } \ - M_ASSERT( (atomic_load(&(shared->M_F(name, _cpt)))&1) == 0); \ - } \ - return shared; \ - } \ - , \ - /* This function is only for dynamic object */ \ - M_INLINE shared_t \ - M_F(name, _init_new)(void) \ - { \ - type *ptr = M_CALL_NEW(oplist, type); \ - if (M_UNLIKELY_NOMEM (ptr == NULL)) { \ - M_MEMORY_FULL(type, 1); \ - } \ - M_CALL_INIT(oplist, *ptr); \ - atomic_init (&ptr->M_F(name, _cpt), 2); \ - return ptr; \ - } \ - /* End of NEW */) \ - , /* End of INIT */) \ - \ - M_INLINE void \ - M_F(name, _clear)(shared_t shared) \ - { \ - if (shared != NULL) { \ - if (atomic_fetch_sub(&(shared->M_F(name, _cpt)), 2) == 2) { \ - M_CALL_CLEAR(oplist, *shared); \ - M_IF_DISABLED_METHOD(DEL, oplist)(, M_CALL_DEL(oplist, shared);) \ - } \ - } \ - } \ - \ - M_INLINE void \ - M_F(name, _clear_ptr)(shared_t *shared) \ - { \ - M_ASSERT(shared != NULL); \ - M_F(name, _clear)(*shared); \ - *shared = NULL; \ - } \ - \ - M_INLINE void \ - M_F(name, _reset)(shared_t *shared) \ - { \ - M_F(name, _clear)(*shared); \ - *shared = NULL; \ - } \ - \ - M_INLINE void \ - M_F(name, _set)(shared_t *ptr, shared_t shared) \ - { \ - M_ASSERT (ptr != NULL); \ - if (M_LIKELY (*ptr != shared)) { \ - M_F(name, _clear)(*ptr); \ - *ptr = M_F(name, _init_set)(shared); \ - } \ - } \ - \ - -M_END_PROTECTED_CODE - -/******************************** INTERNAL ***********************************/ - -#if M_USE_SMALL_NAME -#define ISHARED_PTR_OPLIST M_ISHARED_PTR_OPLIST -#define ISHARED_PTR_INTERFACE M_ISHARED_PTR_INTERFACE -#define ISHARED_PTR_STATIC_DESIGNATED_INIT M_ISHARED_PTR_STATIC_DESIGNATED_INIT -#define ISHARED_PTR_STATIC_INIT M_ISHARED_PTR_STATIC_INIT -#define ISHARED_PTR_DEF M_ISHARED_PTR_DEF -#define ISHARED_PTR_DEF_AS M_ISHARED_PTR_DEF_AS -#endif - -#endif diff --git a/tests/test-mishared.c b/tests/test-mishared.c deleted file mode 100644 index b65fc754..00000000 --- a/tests/test-mishared.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2017-2025, Patrick Pelissier - * All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * + Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * + Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ -#include "test-obj.h" -#include "m-i-shared.h" -#include "m-thread.h" -#include "coverage.h" - -typedef struct ishared_s { - ISHARED_PTR_INTERFACE(ishared1, struct ishared_s); - ISHARED_PTR_INTERFACE(ishared2, struct ishared_s); - int data[100]; -} ishared_t[1]; - -static bool ishared_init_sleep = false; - -static void ishared_init_data(struct ishared_s *x) -{ - for(int i = 0 ; i < 100; i++) - x->data[i] = i * i; - if (ishared_init_sleep) { - // Slow down init - m_thread_sleep(100); - } -} - -static void ishared_test(struct ishared_s *x) -{ - for(int i = 0 ; i < 100; i++) { - assert (x->data[i] == i*i); - } -} - -START_COVERAGE -ISHARED_PTR_DEF(ishared1, struct ishared_s, (INIT(API_2(ishared_init_data)))) -ISHARED_PTR_DEF(ishared2, struct ishared_s, (INIT(API_2(ishared_init_data)), NEW(0), DEL(0)) ) -END_COVERAGE - -/*ISHARED_PTR_DEF_AS(SharedDouble, SharedDouble, double) */ - -static void test_single(void) -{ - ishared1_t p1, p2; - p1 = ishared1_init_new(); - ishared_test(p1); - p2 = ishared1_init_set(p1); - ishared_test(p2); - ishared1_clear(p1); - ishared_test(p2); - - p1 = ishared1_init(NULL); - ishared1_set(&p1, p2); - ishared1_reset(&p2); - assert(p2 == NULL); - ishared_test(p1); - ishared1_clear(p1); - - p1 = ishared1_init_set(p2); - assert(p1 == NULL); - ishared1_clear(p1); - - ishared1_clear(p2); - - struct ishared_s *x = (struct ishared_s *) malloc(sizeof (struct ishared_s)); - assert(x != NULL); - ishared_init_data(x); - p1 = ishared1_init(x); - ishared_test(p1); - ishared1_clear(p1); -} - -static struct ishared_s g_var = { - ISHARED_PTR_STATIC_INIT(ishared1, struct ishared_s), - ISHARED_PTR_STATIC_INIT(ishared2, struct ishared_s), - { 0 } -}; - -static void test_static(void) -{ - ishared2_t p1, p2; - p1 = ishared2_init_once(NULL); - assert(p1 == NULL); - p1 = ishared2_init_once(&g_var); - ishared_test(p1); - p2 = ishared2_init_once(&g_var); - ishared_test(p2); - ishared2_clear(p1); - ishared_test(p2); - ishared2_clear(p2); -} - -#define MAX_THREAD 128 -#define MAX_VAR 5 - -#define VAL(x) { ISHARED_PTR_STATIC_INIT(ishared1, struct ishared_s), ISHARED_PTR_STATIC_INIT(ishared2, struct ishared_s), { 0 } } -static struct ishared_s g_tab[MAX_VAR] = { - M_MAP_C(VAL, M_SEQ(1, MAX_VAR)) -}; - -static void func(void *arg) -{ - int id = (int)(intptr_t) arg; - int v = id % MAX_VAR; - ishared2_t p = ishared2_init_once(&g_tab[v]); - for(int i = 0; i < 100; i++) { - ishared_test(p); - } - ishared2_clear(p); -} - -static void test_shared(void) -{ - m_thread_t id[MAX_THREAD]; - - ishared_init_sleep = true; - for(int i = 0; i < MAX_THREAD; i++) { - m_thread_create(id[i], func, (void*) (intptr_t) i); - } - for(int i = 0; i < MAX_THREAD; i++) { - m_thread_join(id[i]); - } - ishared_init_sleep = false; -} - -int main(void) -{ - test_single(); - test_static(); - test_shared(); - exit(0); -}