Commit 39ca8a68 authored by Adam Wujek's avatar Adam Wujek 💬

Merge branch 'adam-shmem'

Uplift shmem from wr-switch-sw repo.
Fix previous uplift of shmem and improve debug printout.
Signed-off-by: Adam Wujek's avatarAdam Wujek <adam.wujek@cern.ch>
parents 1edcf5c4 669743b9
...@@ -61,19 +61,21 @@ void wrs_shm_set_path(char *new_path); ...@@ -61,19 +61,21 @@ void wrs_shm_set_path(char *new_path);
void wrs_shm_ignore_flag_locked(int ignore_flag); void wrs_shm_ignore_flag_locked(int ignore_flag);
/* get vs. put, like in the kernel. Errors are in errno (see source) */ /* get vs. put, like in the kernel. Errors are in errno (see source) */
void *wrs_shm_get(enum wrs_shm_name name_id, char *name, unsigned long flags); struct wrs_shm_head *wrs_shm_get(enum wrs_shm_name name_id, char *name,
int wrs_shm_put(void *headptr); unsigned long flags);
int wrs_shm_put(struct wrs_shm_head *head);
/* A reader may wait for the writer (polling on version field) */ /* A reader may wait for the writer (polling on version field) */
void wrs_shm_wait(void *headptr, int msec_step, int retries, FILE *msg); void wrs_shm_wait(struct wrs_shm_head *head, int msec_step, int retries,
FILE *msg);
int wrs_shm_get_and_check(enum wrs_shm_name shm_name, int wrs_shm_get_and_check(enum wrs_shm_name shm_name,
struct wrs_shm_head **head); struct wrs_shm_head **head);
/* The writer can allocate structures that live in the area itself */ /* The writer can allocate structures that live in the area itself */
void *wrs_shm_alloc(void *headptr, size_t size); void *wrs_shm_alloc(struct wrs_shm_head *head, size_t size);
/* The reader can track writer's pointers, if they are in the area */ /* The reader can track writer's pointers, if they are in the area */
void *wrs_shm_follow(void *headptr, void *ptr); void *wrs_shm_follow(struct wrs_shm_head *head, void *ptr);
/* Before and after writing a chunk of data, act on sequence and stamp */ /* Before and after writing a chunk of data, act on sequence and stamp */
#define WRS_SHM_WRITE_BEGIN 1 #define WRS_SHM_WRITE_BEGIN 1
...@@ -82,16 +84,17 @@ void *wrs_shm_follow(void *headptr, void *ptr); ...@@ -82,16 +84,17 @@ void *wrs_shm_follow(void *headptr, void *ptr);
/* A helper to pass the name of caller function */ /* A helper to pass the name of caller function */
#define wrs_shm_write(headptr, flags) wrs_shm_write_caller(headptr, flags, \ #define wrs_shm_write(headptr, flags) wrs_shm_write_caller(headptr, flags, \
__func__) __func__)
extern void wrs_shm_write_caller(void *headptr, int flags, const char *caller); extern void wrs_shm_write_caller(struct wrs_shm_head *head, int flags,
const char *caller);
/* A reader can rely on the sequence number (in the <linux/seqlock.h> way) */ /* A reader can rely on the sequence number (in the <linux/seqlock.h> way) */
extern unsigned wrs_shm_seqbegin(void *headptr); extern unsigned wrs_shm_seqbegin(struct wrs_shm_head *head);
extern int wrs_shm_seqretry(void *headptr, unsigned start); extern int wrs_shm_seqretry(struct wrs_shm_head *head, unsigned start);
/* A reader can check wether information is current enough */ /* A reader can check wether information is current enough */
extern int wrs_shm_age(void *headptr); extern int wrs_shm_age(struct wrs_shm_head *head);
/* A reader can get the information pointer, for a specific version, or NULL */ /* A reader can get the information pointer, for a specific version, or NULL */
extern void *wrs_shm_data(void *headptr, unsigned version); extern void *wrs_shm_data(struct wrs_shm_head *head, unsigned version);
#endif /* __WRS_SHM_H__ */ #endif /* __WRS_SHM_H__ */
...@@ -39,7 +39,8 @@ void wrs_shm_ignore_flag_locked(int ignore_flag) ...@@ -39,7 +39,8 @@ void wrs_shm_ignore_flag_locked(int ignore_flag)
/* Get wrs shared memory */ /* Get wrs shared memory */
/* return NULL and set errno on error */ /* return NULL and set errno on error */
void *wrs_shm_get(enum wrs_shm_name name_id, char *name, unsigned long flags) struct wrs_shm_head *wrs_shm_get(enum wrs_shm_name name_id, char *name,
unsigned long flags)
{ {
struct wrs_shm_head *head; struct wrs_shm_head *head;
struct stat stbuf; struct stat stbuf;
...@@ -120,20 +121,19 @@ void *wrs_shm_get(enum wrs_shm_name name_id, char *name, unsigned long flags) ...@@ -120,20 +121,19 @@ void *wrs_shm_get(enum wrs_shm_name name_id, char *name, unsigned long flags)
head->pidsequence++; head->pidsequence++;
/* version and size are up to the user (or to allocation) */ /* version and size are up to the user (or to allocation) */
return map; return (struct wrs_shm_head *) map;
} }
/* Put wrs shared memory */ /* Put wrs shared memory */
/* return 0 on success, !0 on error */ /* return 0 on success, !0 on error */
int wrs_shm_put(void *headptr) int wrs_shm_put(struct wrs_shm_head *head)
{ {
struct wrs_shm_head *head = headptr;
int err; int err;
if (head->pid == getpid()) { if (head->pid == getpid()) {
head->pid = 0; /* mark that we are not writers any more */ head->pid = 0; /* mark that we are not writers any more */
close(head->fd); close(head->fd);
} }
if ((err = munmap(headptr, WRS_SHM_MAX_SIZE)) < 0) if ((err = munmap(head, WRS_SHM_MAX_SIZE)) < 0)
return err; return err;
return 0; return 0;
} }
...@@ -175,9 +175,9 @@ int wrs_shm_get_and_check(enum wrs_shm_name shm_name, ...@@ -175,9 +175,9 @@ int wrs_shm_get_and_check(enum wrs_shm_name shm_name,
} }
/* The writer can allocate structures that live in the area itself */ /* The writer can allocate structures that live in the area itself */
void *wrs_shm_alloc(void *headptr, size_t size) void *wrs_shm_alloc(struct wrs_shm_head *head, size_t size)
{ {
struct wrs_shm_head *head = headptr; void *headptr = (void *) head;
void *nextptr; void *nextptr;
if (head->pid != getpid()) if (head->pid != getpid())
...@@ -196,73 +196,77 @@ void *wrs_shm_alloc(void *headptr, size_t size) ...@@ -196,73 +196,77 @@ void *wrs_shm_alloc(void *headptr, size_t size)
} }
/* The reader can track writer's pointers, if they are in the area */ /* The reader can track writer's pointers, if they are in the area */
void *wrs_shm_follow(void *headptr, void *ptr) void *wrs_shm_follow(struct wrs_shm_head *head, void *ptr)
{ {
struct wrs_shm_head *head = headptr; void *headptr = (void *) head;
if (ptr < head->mapbase || ptr > head->mapbase + WRS_SHM_MAX_SIZE) if (ptr < head->mapbase || ptr > head->mapbase + WRS_SHM_MAX_SIZE)
return NULL; /* not in the area */ return NULL; /* not in the area */
return headptr + (ptr - head->mapbase); return headptr + (ptr - head->mapbase);
} }
/* Before and after writing a chunk of data, act on sequence and stamp */ /* Before and after writing a chunk of data, act on sequence and stamp */
void wrs_shm_write_caller(void *headptr, int flags, const char *caller) void wrs_shm_write_caller(struct wrs_shm_head *head, int flags,
const char *caller)
{ {
struct wrs_shm_head *head = headptr; char *msg = "Wrong parameter";
head->sequence++; if (flags == WRS_SHM_WRITE_BEGIN) {
pr_debug("caller: %s\n", caller); msg = "write begin";
}
if (flags == WRS_SHM_WRITE_END) {
msg = "write end";
}
pr_debug("caller of a function wrs_shm_write is %s, called for \"%s\" "
"with the flag \"%s\"\n", caller, head->name, msg);
head->sequence += 2;
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;
} }
/* A reader can rely on the sequence number (in the <linux/seqlock.h> way) */ /* A reader can rely on the sequence number (in the <linux/seqlock.h> way) */
unsigned wrs_shm_seqbegin(void *headptr) unsigned wrs_shm_seqbegin(struct wrs_shm_head *head)
{ {
struct wrs_shm_head *head = headptr;
return head->sequence; return head->sequence;
} }
int wrs_shm_seqretry(void *headptr, unsigned start) int wrs_shm_seqretry(struct wrs_shm_head *head, unsigned start)
{ {
struct wrs_shm_head *head = headptr; if (start & WRS_SHM_LOCK_MASK)
if (start & 1)
return 1; /* it was odd: retry */ return 1; /* it was odd: retry */
return head->sequence != start; return head->sequence != start;
} }
/* A reader can check wether information is current enough */ /* A reader can check wether information is current enough */
int wrs_shm_age(void *headptr) int wrs_shm_age(struct wrs_shm_head *head)
{ {
struct wrs_shm_head *head = headptr;
return get_monotonic_sec() - head->stamp; return get_monotonic_sec() - head->stamp;
} }
/* A reader can get the information pointer, for a specific version, or NULL */ /* A reader can get the information pointer, for a specific version, or NULL */
void *wrs_shm_data(void *headptr, unsigned version) void *wrs_shm_data(struct wrs_shm_head *head, unsigned version)
{ {
struct wrs_shm_head *head = headptr; void *headptr = (void *) head;
if (head->version != version) if (head->version != version)
return NULL; return NULL;
......
...@@ -59,7 +59,7 @@ struct wrs_shm_head *ppsi_head; ...@@ -59,7 +59,7 @@ struct wrs_shm_head *ppsi_head;
* we need to call calloc, to reset all stuff that used to be static, * we need to call calloc, to reset all stuff that used to be static,
* but we'd better have a simple prototype, compatilble with wrs_shm_alloc() * but we'd better have a simple prototype, compatilble with wrs_shm_alloc()
*/ */
static void *local_malloc(void *headptr, size_t size) static void *local_malloc(struct wrs_shm_head *headptr, size_t size)
{ {
void *retval = malloc(size); void *retval = malloc(size);
...@@ -78,7 +78,8 @@ int main(int argc, char **argv) ...@@ -78,7 +78,8 @@ int main(int argc, char **argv)
int i, hal_retries; int i, hal_retries;
struct wrs_shm_head *hal_head; struct wrs_shm_head *hal_head;
struct hal_shmem_header *h; struct hal_shmem_header *h;
void *(*alloc_fn)(void *headptr, size_t size) = local_malloc; void *(*alloc_fn)(struct wrs_shm_head *headptr, size_t size);
alloc_fn = local_malloc;
setbuf(stdout, NULL); setbuf(stdout, NULL);
......
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