Commit 477f1cef authored by Adam Wujek's avatar Adam Wujek 💬

userspace/libwr: improve locking of shmem

Keep explicitly lock bit in the sequence variable as a LSB bit.
This solution is backward compatible. The difference is only when shmem is
lock twice. Before it was treated as unlocked, now still as a lock.
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parent 656c6559
...@@ -32,7 +32,8 @@ struct wrs_shm_head { ...@@ -32,7 +32,8 @@ struct wrs_shm_head {
int pid; /* The current pid owning the area */ int pid; /* The current pid owning the area */
unsigned pidsequence; /* Each new pid must increments this */ unsigned pidsequence; /* Each new pid must increments this */
unsigned sequence; /* If we need consistency, this is it */ unsigned sequence; /* If we need consistency, this is it. LSB bit
* informs whether shmem is locked already */
unsigned version; /* Version of the data structure */ unsigned version; /* Version of the data structure */
unsigned data_size; /* Size of it (for binary dumps) */ unsigned data_size; /* Size of it (for binary dumps) */
}; };
...@@ -42,6 +43,8 @@ struct wrs_shm_head { ...@@ -42,6 +43,8 @@ struct wrs_shm_head {
#define WRS_SHM_WRITE 0x0001 #define WRS_SHM_WRITE 0x0001
#define WRS_SHM_LOCKED 0x0002 /* at init time: writers locks, readers wait */ #define WRS_SHM_LOCKED 0x0002 /* at init time: writers locks, readers wait */
#define WRS_SHM_LOCK_MASK 0x0001
/* Set custom path for shmem */ /* Set custom path for shmem */
void wrs_shm_set_path(char *new_path); void wrs_shm_set_path(char *new_path);
......
...@@ -202,23 +202,27 @@ void wrs_shm_write_caller(void *headptr, int flags, const char *caller) ...@@ -202,23 +202,27 @@ void wrs_shm_write_caller(void *headptr, int flags, const char *caller)
{ {
struct wrs_shm_head *head = headptr; struct wrs_shm_head *head = headptr;
head->sequence++; head->sequence += 2;
pr_debug("caller: %s\n", caller); pr_debug("caller of a function %s is %s\n", __func__, caller);
if (flags == WRS_SHM_WRITE_BEGIN) {
if (head->sequence & WRS_SHM_LOCK_MASK)
pr_error("Trying to lock already locked shmem on the "
"write end! Sequence number is %d. The caller"
" of wrs_shm_write is %s\n",
head->sequence, caller);
head->sequence |= WRS_SHM_LOCK_MASK;
}
if (flags == WRS_SHM_WRITE_END) { if (flags == WRS_SHM_WRITE_END) {
/* At end-of-writing update the timestamp too */ /* At end-of-writing update the timestamp too */
head->stamp = get_monotonic_sec(); head->stamp = get_monotonic_sec();
if (head->sequence & 1) if (!(head->sequence & WRS_SHM_LOCK_MASK))
pr_error("On the shmem write end the sequence number " pr_error("Trying to unlock already unlocked shmem on "
"(%d) is even (should be odd). The caller of" "the write begin! Sequence number is %d. The "
" wrs_shm_write is %s\n", "caller of wrs_shm_write is %s\n",
head->sequence, caller); head->sequence, caller);
} else { head->sequence &= ~WRS_SHM_LOCK_MASK;
if (!(head->sequence & 1))
pr_error("On the shmem write begin the sequence number"
" (%d) is odd (should be even). The caller of"
" wrs_shm_write is %s\n",
head->sequence, caller);
} }
return; return;
...@@ -236,7 +240,7 @@ int wrs_shm_seqretry(void *headptr, unsigned start) ...@@ -236,7 +240,7 @@ int wrs_shm_seqretry(void *headptr, unsigned start)
{ {
struct wrs_shm_head *head = headptr; struct wrs_shm_head *head = headptr;
if (start & 1) if (start & WRS_SHM_LOCK_MASK)
return 1; /* it was odd: retry */ return 1; /* it was odd: retry */
return head->sequence != start; return head->sequence != start;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment