[PATCH v3] eal: add seqlock
Mattias Rönnblom
hofors at lysator.liu.se
Sun Apr 3 08:33:58 CEST 2022
I missed some of your comments.
On 2022-04-02 02:21, Honnappa Nagarahalli wrote:
<snip>
>> + * Example usage:
>> + * @code{.c}
>> + * #define MAX_Y_LEN (16)
>> + * // Application-defined example data structure, protected by a seqlock.
>> + * struct config {
>> + * rte_seqlock_t lock;
>> + * int param_x;
>> + * char param_y[MAX_Y_LEN];
>> + * };
>> + *
>> + * // Accessor function for reading config fields.
>> + * void
>> + * config_read(const struct config *config, int *param_x, char
>> +*param_y)
>> + * {
>> + * // Temporary variables, just to improve readability.
> I think the above comment is not necessary. It is beneficial to copy the protected data to keep the read side critical section small.
>
The data here would be copied into the buffers supplied by config_read()
anyways, so it's a copy regardless.
>> + * int tentative_x;
>> + * char tentative_y[MAX_Y_LEN];
>> + * uint32_t sn;
>> + *
>> + * sn = rte_seqlock_read_lock(&config->lock);
>> + * do {
>> + * // Loads may be atomic or non-atomic, as in this example.
>> + * tentative_x = config->param_x;
>> + * strcpy(tentative_y, config->param_y);
>> + * } while (!rte_seqlock_read_tryunlock(&config->lock, &sn));
>> + * // An application could skip retrying, and try again later, if
>> + * // progress is possible without the data.
>> + *
>> + * *param_x = tentative_x;
>> + * strcpy(param_y, tentative_y);
>> + * }
>> + *
>> + * // Accessor function for writing config fields.
>> + * void
>> + * config_update(struct config *config, int param_x, const char
>> +*param_y)
>> + * {
>> + * rte_seqlock_write_lock(&config->lock);
>> + * // Stores may be atomic or non-atomic, as in this example.
>> + * config->param_x = param_x;
>> + * strcpy(config->param_y, param_y);
>> + * rte_seqlock_write_unlock(&config->lock);
>> + * }
>> + * @endcode
>> + *
>> + * @see
>> + * https://en.wikipedia.org/wiki/Seqlock.
>> + */
>> +
>> +#include <stdbool.h>
>> +#include <stdint.h>
>> +
>> +#include <rte_atomic.h>
>> +#include <rte_branch_prediction.h>
>> +#include <rte_spinlock.h>
>> +
>> +/**
>> + * The RTE seqlock type.
>> + */
>> +typedef struct {
>> + uint32_t sn; /**< A sequence number for the protected data. */
>> + rte_spinlock_t lock; /**< Spinlock used to serialize writers. */ }
> Suggest using ticket lock for the writer side. It should have low overhead when there is a single writer, but provides better functionality when there are multiple writers.
>
Is a seqlock the synchronization primitive of choice for high-contention
cases? I would say no, but I'm not sure what you would use instead.
<snip>
More information about the dev
mailing list