From: queengambit on
Hi people, as the subject title already says I've got trouble with how
to use a linked list in a shared memory between processes. More
specific, initially my linked list would be NULL and it is a doubly
circular linked list. Here is the structure of any element in the
linked list:

typedef struct my_ringnode_st my_ringnode_t;

struct my_ringnode_st {
my_ringnode_t *next;
my_ringnode_t *prev;
};

I would like my linked list to be able to shrink/expand without
running into the coredumb/memory violation. Having looked at other
posts, i know that i have to use offset instead of pointers 'next' &
'prev' to refer to next and previous elements of the linked list; but
still i'm still confused about how to do that, what size initially my
shared memory should be and if the my shared memory is a big chunk of,
say N*sizeof(struct my_ringnode_st), then how can i assign the next
block of memory for a new ringnode object?

any response would be much appreciated

Jim

From: Ian Collins on
queengambit wrote:
> Hi people, as the subject title already says I've got trouble with how
> to use a linked list in a shared memory between processes. More
> specific, initially my linked list would be NULL and it is a doubly
> circular linked list. Here is the structure of any element in the
> linked list:
>
> typedef struct my_ringnode_st my_ringnode_t;
>
> struct my_ringnode_st {
> my_ringnode_t *next;
> my_ringnode_t *prev;
> };
>
> I would like my linked list to be able to shrink/expand without
> running into the coredumb/memory violation. Having looked at other
> posts, i know that i have to use offset instead of pointers 'next' &
> 'prev' to refer to next and previous elements of the linked list; but
> still i'm still confused about how to do that, what size initially my
> shared memory should be and if the my shared memory is a big chunk of,
> say N*sizeof(struct my_ringnode_st), then how can i assign the next
> block of memory for a new ringnode object?
>
If you can use a fixed mapping address in each process, next and prev
will work. Otherwise you have to store the offset form the base of the
memory segment.

The segment has to be big enough to meet your expected maximum list
size, which will depend the size of the objects you intend to save in
the list.

You will have to provide your own allocation and deallocation routines
(malloc/free replacements) to manage the shared memory.

--
Ian Collins.
From: Bin Chen on
On Feb 26, 7:14 am, "queengambit" <cbp...(a)cs.york.ac.uk> wrote:
> Hi people, as the subject title already says I've got trouble with how
> to use a linked list in a shared memory between processes. More
> specific, initially my linked list would be NULL and it is a doubly
> circular linked list. Here is the structure of any element in the
> linked list:
>
> typedef struct my_ringnode_st my_ringnode_t;
>
> struct my_ringnode_st {
> my_ringnode_t *next;
> my_ringnode_t *prev;
>
> };
>
> I would like my linked list to be able to shrink/expand without
> running into the coredumb/memory violation. Having looked at other
> posts, i know that i have to use offset instead of pointers 'next' &
> 'prev' to refer to next and previous elements of the linked list; but
> still i'm still confused about how to do that, what size initially my
> shared memory should be and if the my shared memory is a big chunk of,
> say N*sizeof(struct my_ringnode_st), then how can i assign the next
> block of memory for a new ringnode object?
>
> any response would be much appreciated
>
> Jim

What you can do simply is replace the direct addressing using '->'
with a function or a macro, such as:

LINK_NEXT(b)

In this macro you manipulate the address using the prior memorized
base address.

From: queengambit on
Good morning Ian, Bin,
I don't think mapping the shared memory to processes at exactly the
same address a good idea as in my wrapper (which is what i have to
write) users are allowed to 'exec' after 'fork'. The method sounds
good is using offset.
ok, let say i already do the following:

struct my_ringnode_st {
my_ringnode_t *next;
my_ringnode_t *prev;
int my_offset[PTHREAD_THREADS_MAX]; /* for offset to nex and prev
elements */
};

shm_unlink(shm_name);
fd = shm_open(mm_name, O_RDWR | O_CREAT | O_EXCL, S_IRWXU);
if (fd ==-1)
perror("error opening file for read and write");

/*set size of the my_shared memory object to sizeof(struct
my_ringnode_st) */
ftruncate(fd, PTHREAD_THREADS_MAX*sizeof(struct my_ringnode_st));

/*in parent */
ptr1 = mmap(NULL, PTHREAD_THREADS_MAX*sizeof(struct my_ringnode_st),
PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (ptr == MAP_FAILED)
{
perror("error mapping the file");
exit(EXIT_FAILURE);
}

/*in child */
ptr2 = ... /* same as parent */

With child, ptr2 = child_base_addr. Now if i want to add a new element
to the linked list in child, which is initially NULL , what do i have
to do? What i'm really confused is how to allocate new block of space
from the shared memory for the new element of the linked list and how
offset works

thank you


From: Ian Collins on
queengambit wrote:
> Good morning Ian, Bin,
> I don't think mapping the shared memory to processes at exactly the
> same address a good idea as in my wrapper (which is what i have to
> write) users are allowed to 'exec' after 'fork'. The method sounds
> good is using offset.

The segment could be mapped with MAP_FIXED.

>
> With child, ptr2 = child_base_addr. Now if i want to add a new element
> to the linked list in child, which is initially NULL , what do i have
> to do? What i'm really confused is how to allocate new block of space
> from the shared memory for the new element of the linked list and how
> offset works
>
As I said, you have to write an allocator for items that are added to
your list, think of it as malloc and free for the list objects. If the
items in the list are all the same size, this is simple (you can
consider the shared memory as an array of objects), if not it gets a
little harder.

In the list, you could use the difference in the addresses of the list
items as net and prev so node+next = address of next node and node-prev
= address of previous node.

--
Ian Collins.