Remove obsolete m-concurrent.h header

This commit is contained in:
Patrick Pelissier committed 2025-05-07 22:01:38 +02:00
1 parent 25dcdeed69
commit 8c70a1f96c
4 files changed
-1320

No files matched your search

-158
View File
@@ -196,7 +196,6 @@ Finally, headers for compatibility with non C11 compilers:
* [m-thread.h](#m-thread): header for providing a very thin layer across multiple implementation of mutex/threads (C11/PTHREAD/WIN32).
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-mempool.h](#m-mempool): header for creating specialized & fast memory allocator,
Each containers define their iterators (if it is meaningful).
@@ -5276,163 +5275,6 @@ Afterwards, `list2` is emptied.
_________________
### M-CONCURRENT
> [!NOTE]
> This header is obsolete: M-SHARED-PTR should be used instead.
This header is for transforming a standard container (`LIST`, `ARRAY`, `DICT`, `DEQUE`, ...)
into an equivalent container but compatible with concurrent access by different threads.
In practice, it puts a mutex lock to access the container.
As such it is quite generic. However, it is less efficient than containers
specially tuned for multiple threads.
There is also no iterators.
#### `CONCURRENT_DEF(name, type[, oplist])`
#### `CONCURRENT_DEF_AS(name, name_t, type[, oplist])`
Define the concurrent container `name` based on container `type` of oplist `oplist`,
and define the associated methods to handle it as `static inline` functions.
`name` shall be a C identifier that will be used to identify the concurrent container.
It will be used to create all the types (including the iterator)
and functions to handle the container.
This definition shall be done once per name and per compilation unit.
It scans the `oplist` of the type to create equivalent function,
so the exact generated methods depend on explicitly the exported methods in the oplist.
The init method is only defined if the base container exports the `INIT` operator,
same for the clear method and the `CLEAR` operator,
and so on for all created methods.
In the description below,
`subtype_t` is the type of the element within the given container `type` (if it exists),
`key_t` is the key type of the element within the given container `type` (if it exists),
`value_t` is the value type of the element within the given container `type` (if it exists).
`CONCURRENT_DEF_AS` is the same as `CONCURRENT_DEF` except the name of the type `name_t`
is provided.
Example:
```C
/* Define a stack container (STACK)*/
ARRAY_DEF(array1, int)
CONCURRENT_DEF(parray1, array1_t, ARRAY_OPLIST(array1))
/* Define a queue container (FIFO) */
DEQUE_DEF(deque_uint, unsigned int)
CONCURRENT_DEF(cdeque_uint, deque_uint_t, M_OPEXTEND(DEQUE_OPLIST(deque_uint, M_BASIC_OPLIST), PUSH(deque_uint_push_front)))
extern parray1_t x1;
extern cdeque_uint_t x2;
void f(void) {
parray1_push (x1, 17);
cdeque_uint_push (x2, 17);
}
```
#### Created types
The following types are automatically defined by the previous definition macro if not provided by the user:
##### `name_t`
Type of the concurrent container of `type`.
#### Common methods
The following methods of the common interface are defined (See [Common interface](#Common-Interface) for details):
```C
void name_init(name_t concurrent)
void name_init_set(name_t concurrent, const name_t src)
void name_init_move(name_t concurrent, name_t src)
void name_set(name_t concurrent, const name_t src)
void name_move(name_t concurrent, name_t src)
void name_reset(name_t concurrent)
void name_clear(name_t concurrent)
void name_swap(name_t concurrent1, name_t concurrent2)
bool name_empty_p(const name_t concurrent)
void name_set_at(name_t concurrent, key_t key, value_t value)
bool name_erase(name_t concurrent, const key_t key)
void name_push(name_t concurrent, const subtype_t data)
void name_push_move(name_t concurrent, subtype_t *data)
void name_pop_move(subtype_t *data, name_t concurrent)
void name_get_str(string_t str, name_t concurrent, bool append)
void name_out_str(FILE *file, name_t concurrent)
bool name_parse_str(name_t concurrent, const char str[], const char **end)
bool name_in_str(name_t concurrent, FILE *file)
m_serial_return_code_t name_out_serial(m_serial_write_t serial, const name_t container)
m_serial_return_code_t name_in_str(name_t container, m_serial_read_t serial)
bool name_equal_p(name_t concurrent1, name_t concurrent2)
size_t name_hash(name_t concurrent)
```
Returns true in case of success, false otherwise.
#### Specialized methods
The following specialized methods are automatically created by the previous definition macro:
##### `bool name_get_copy(value_t *value, name_t concurrent, key_t key)`
Read the value associated to the key `key`.
If it exists, it sets `*value` to it and returns true.
Otherwise it returns false (`*value` is unchanged).
This method is only defined if the base container exports the `GET_KEY` operator.
##### `void name_safe_get_copy(value_t *value, name_t concurrent, key_t key)`
Read the value associated to the key `key`.
If it exists, it sets `*value` to it.
Otherwise, it creates a new value (default constructor) and sets `*value` to it.
This method is only defined if the base container exports the `SAFE_GET_KEY` operator.
##### `void name_pop(subtype_t *data, name_t concurrent)`
Pop data from the container and set it in `*data`.
There shall be at least one data to pop.
Testing with the operator `EMPTY_P` before calling this function is not enough
as there can be some concurrent scenario where another thread pop the last value.
`name_pop_blocking` should be used instead.
This method is only defined if the base container exports the `POP` operator.
##### `bool name_get_blocking(value_t *value, name_t concurrent, key_t key, bool blocking)`
Read the value associated to the key `key`.
If it exists, it sets `*value` to it and returns true.
Otherwise, if blocking is true, it waits for the data to be filled.
After the wait, it sets `*value` to it and returns true.
Otherwise, if blocking is false, it returns false.
This method is only defined if the base container exports the `GET_KEY` operator.
##### `bool name_pop_blocking(type_t *data, name_t concurrent, bool blocking)`
Pop a value from the container and set `*data` with it.
If the container is not empty, it sets `*data` and return true.
Otherwise, if blocking is true, it waits for the data to be pushed.
After the wait, it sets `*data` to it and returns true.
Otherwise, if blocking is false, it returns false.
This method is only defined if the base container exports the `POP` and `EMPTY_P` operators.
##### `bool name_pop_move_blocking(type_t *data, name_t concurrent, bool blocking)`
Pop a value from the container and initialize and set `*data` with it.
If the container is not empty, it initializes and sets `*data` and return true.
Otherwise if blocking is true, it waits for the data to be pushed.
After the wait, it initializes and sets `*data` to it and returns true.
Otherwise, if blocking is false, it returns false.
> [!WARNING]
> `*data` remains uninitialized!
This method is only defined if the base container exports the `POP_MOVE` and `EMPTY_P` operators.
_________________
### M-BITSET
This header is for using bitset.