Remove obsolete m-concurrent.h header
This commit is contained in:
1 parent
25dcdeed69
commit
8c70a1f96c
4 files changed
-1320
No files matched your search
@@ -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.
|
||||
|
||||
Reference in new issue
Block a user