Data Structures | Macros | Enumerations | Functions
picotm-lib-rwstate.h File Reference

Contains struct picotm_rwstate and helpers. More...

#include "compiler.h"

Data Structures

struct  picotm_rwstate
 

Macros

#define PICOTM_RWSTATE_INITIALIZER
 Initializer macro for R/W state variables.
 

Enumerations

enum  picotm_rwstate_status { PICOTM_RWSTATE_UNLOCKED, PICOTM_RWSTATE_RDLOCKED, PICOTM_RWSTATE_WRLOCKED }
 

Functions

PICOTM_NOTHROW enum picotm_rwstate_status picotm_rwstate_get_status (const struct picotm_rwstate *self)
 
PICOTM_NOTHROW void picotm_rwstate_init (struct picotm_rwstate *self)
 
PICOTM_NOTHROW void picotm_rwstate_set_status (struct picotm_rwstate *self, enum picotm_rwstate_status status)
 
PICOTM_NOTHROW void picotm_rwstate_try_rdlock (struct picotm_rwstate *self, struct picotm_rwlock *rwlock, struct picotm_error *error)
 
PICOTM_NOTHROW void picotm_rwstate_try_wrlock (struct picotm_rwstate *self, struct picotm_rwlock *rwlock, struct picotm_error *error)
 
PICOTM_NOTHROW void picotm_rwstate_uninit (struct picotm_rwstate *self)
 
PICOTM_NOTHROW void picotm_rwstate_unlock (struct picotm_rwstate *self, struct picotm_rwlock *rwlock)
 

Detailed Description

The data structure struct picotm_rwstate represents a transaction's status wrt. shared state.

For example, shared state might be an integer with an associated reader/writer lock.

int i;
struct picotm_rwlock i_lock;
i = 0;

Each transaction accessing the integer i contains a reader/writer state value of type struct picotm_rwstate. The transaction has to initialize the state value with a call to picotm_rwstate_init().

struct picotm_rwstate i_state;

Alternatively, the macro PICOTM_RWSTATE_INITIALIZER initializes a static or stack-allocated R/W-state variable. If both, function and macro initialization, is possible, the macro form is prefered.

To safely read the value of resource i, a transaction has to acquire the reader lock i_lock.

struct picotm_error error = PICOTM_ERROR_INITIALIZER;
picotm_rwstate_try_rdlock(&i_state, &i_lock, &error);
if (picotm_error_is_set(&error)) {
// perform recovery
}
// read i

A call to picotm_rwstate_try_rdlock() acquires a reader lock and sets the transaction's reader/writer state accordingly. If the reader lock could not be acquired, an error is returned. In this case, the transaction should initiate a recovery.

To safely write, a transaction has to acquire the writer lock i_lock.

picotm_rwstate_try_wrlock(&i_state, &i_lock, &error);
if (picotm_error_is_set(&error)) {
// perform recovery
}
// write i

Depending on the transaction's current reader/writer state, the function picotm_rwstate_try_wrlock() automatically updates a reader lock to a writer lock.

Reader/writer locks can only be acquired once by each transaction, and possibly upgraded once by each transaction. The reader/writer state variable keeps track of the transaction's lock state, so locks can be acquired and upgraded multiple times.

picotm_rwstate_try_wrlock(&i_state, &i_lock, &error);
if (picotm_error_is_set(&error)) {
// perform recovery
}
picotm_rwstate_try_rdlock(&i_state, &i_lock, &error);
if (picotm_error_is_set(&error)) {
// perform recovery
}
picotm_rwstate_try_wrlock(&i_state, &i_lock, &error);
if (picotm_error_is_set(&error)) {
// perform recovery
}

In any case, a reader-writer lock can only be unlocked once, using picotm_rwstate_unlock().

picotm_rwstate_unlock(&i_state, &i_lock);

The current reader/writer state can be queried using picotm_rwstate_get_status(), which returns one of enum picotm_rwstate_status. Using picotm_rwstate_set_status(), the status can also be set explicitly. This might be useful when adopting pre-acquired reader/writer locks, but it's generally preferable to use reader/writer state interfaces for locking and unlocking.

Finally, to uninitialize a reader/writer state the transaction has to call picotm_rwstate_uninit().