From: queengambit on 25 Feb 2007 18:14 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 25 Feb 2007 18:30 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 25 Feb 2007 19:06 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 26 Feb 2007 03:36 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 26 Feb 2007 04:50
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. |