stl container within shared memory

M

Me

howdy.

Some of this will sound a bit platform specific and a few of you will feel
the need to yell "off-topic" but please refrain because the parts of the
problem I'm asking about are generic enough to be relevant.

I use c++ for embedded applications because my tasks are very complex but
I still need to be able to directly deal with hardware. I've been working
for the past couple of years with a really screwey robotics protocol
called JAUS and I've been violating the standard and doing things my own
way but I now need to investigate a higher level of compatibility with
other systems that more closely adhere to the architecture.

The standard calls for a series of software components that do different
robotics functions and also has very strict message routing rules. It is
these strict message routing rules that make it difficult and inefficient
to implement conforming systems in my POSIX runtime environment. Each
component is a separate process with separate address space. This means
that to follow the architecture I must use IPC to route messages to
applicable components. However, POSIX IPC introduces unacceptable latency
into the system. Depending upon system load I can see measurable 10 to
100ms round trip delay of routed messages when using named pipe IPC. That
isn't adequate when the data payloads are real-time audio/video or command
and control data.

To solve this problem I want to implement a shared memory priority queue
that is accessible by all component processes. The clencher is that I'd
like to be able to insert std::string objects into the queue. This is not
a simple case of multithreaded application since each component runs in
its own address space. What I'm asking is whether there is a relatively
safe way to make the std::string accessible by two or more separate
processes. If I knew that all internal string memory was handled thru new/
delete I presume that I could implement a custom handler to use my shared
memory pool...but if within the string class there are any pointers that
are initialized to process specific address space then the thing will most
certainly blow up.

Someone will undoubtedly bring up the syncronization issue. That is taken
care of by using a platform specific atomic operation on the shared
memory, thus guaranteeing mutually exclusive access as long as the lock is
properly acquired and released.

Thoughts? Has anyone done work that can shed some light on using custom
memory handlers or shared memory with the STL classes?
 
G

Guest

howdy.

Some of this will sound a bit platform specific and a few of you will feel
the need to yell "off-topic" but please refrain because the parts of the
problem I'm asking about are generic enough to be relevant.

I use c++ for embedded applications because my tasks are very complex but
I still need to be able to directly deal with hardware. I've been working
for the past couple of years with a really screwey robotics protocol
called JAUS and I've been violating the standard and doing things my own
way but I now need to investigate a higher level of compatibility with
other systems that more closely adhere to the architecture.

The standard calls for a series of software components that do different
robotics functions and also has very strict message routing rules. It is
these strict message routing rules that make it difficult and inefficient
to implement conforming systems in my POSIX runtime environment. Each
component is a separate process with separate address space. This means
that to follow the architecture I must use IPC to route messages to
applicable components. However, POSIX IPC introduces unacceptable latency
into the system. Depending upon system load I can see measurable 10 to
100ms round trip delay of routed messages when using named pipe IPC. That
isn't adequate when the data payloads are real-time audio/video or command
and control data.

To solve this problem I want to implement a shared memory priority queue
that is accessible by all component processes. The clencher is that I'd
like to be able to insert std::string objects into the queue. This is not
a simple case of multithreaded application since each component runs in
its own address space. What I'm asking is whether there is a relatively
safe way to make the std::string accessible by two or more separate
processes. If I knew that all internal string memory was handled thru new/
delete I presume that I could implement a custom handler to use my shared
memory pool...but if within the string class there are any pointers that
are initialized to process specific address space then the thing will most
certainly blow up.

I believe that a common implementation of strings is to have a small
object that contains data about the string but keeps the actual string
else-where. Actually I can see no other way to implement it while still
allowing a string to be allocated on the stack and later changed (in
length). This might be solvable using a special allocator that uses your
shared memory, but to get that to play nice over several processes might
be a challenge.

You're probably better of using char arrays, you could section of the
shared memory into fixed size segments and put one string per segment.
 
J

jpalecek

howdy.

Some of this will sound a bit platform specific and a few of you will feel
the need to yell "off-topic" but please refrain because the parts of the
problem I'm asking about are generic enough to be relevant.

I use c++ for embedded applications because my tasks are very complex but
I still need to be able to directly deal with hardware. I've been working
for the past couple of years with a really screwey robotics protocol
called JAUS and I've been violating the standard and doing things my own
way but I now need to investigate a higher level of compatibility with
other systems that more closely adhere to the architecture.

The standard calls for a series of software components that do different
robotics functions and also has very strict message routing rules. It is
these strict message routing rules that make it difficult and inefficient
to implement conforming systems in my POSIX runtime environment. Each
component is a separate process with separate address space. This means
that to follow the architecture I must use IPC to route messages to
applicable components. However, POSIX IPC introduces unacceptable latency
into the system. Depending upon system load I can see measurable 10 to
100ms round trip delay of routed messages when using named pipe IPC. That
isn't adequate when the data payloads are real-time audio/video or command
and control data.

To solve this problem I want to implement a shared memory priority queue
that is accessible by all component processes. The clencher is that I'd
like to be able to insert std::string objects into the queue. This is not
a simple case of multithreaded application since each component runs in
its own address space. What I'm asking is whether there is a relatively
safe way to make the std::string accessible by two or more separate
processes. If I knew that all internal string memory was handled thru new/
delete I presume that I could implement a custom handler to use my shared
memory pool...but if within the string class there are any pointers that
are initialized to process specific address space then the thing will most
certainly blow up.

Someone will undoubtedly bring up the syncronization issue. That is taken
care of by using a platform specific atomic operation on the shared
memory, thus guaranteeing mutually exclusive access as long as the lock is
properly acquired and released.

Thoughts? Has anyone done work that can shed some light on using custom
memory handlers or shared memory with the STL classes?

I've never tried anything like this yet, but I suppose you want to
create
a custom allocator, which would allocate the memory from your shared
memory
block. Also, it should have a very special pointer type to dela with
situations when the shm block is mapped to two different addresses in
two
processes.

Regards
Jiri Palecek
 
Y

Yannick Tremblay

howdy.

To solve this problem I want to implement a shared memory priority queue
that is accessible by all component processes. The clencher is that I'd
like to be able to insert std::string objects into the queue. This is not
a simple case of multithreaded application since each component runs in
its own address space. What I'm asking is whether there is a relatively
safe way to make the std::string accessible by two or more separate
processes. If I knew that all internal string memory was handled thru new/
delete I presume that I could implement a custom handler to use my shared
memory pool...but if within the string class there are any pointers that
are initialized to process specific address space then the thing will most
certainly blow up.
[...]

Thoughts? Has anyone done work that can shed some light on using custom
memory handlers or shared memory with the STL classes?

It's should be possible depending on your platform by using custom
allocators.

It's not a simple thing to do from scratch. Fortunately, Boost has
current in development stuff that does it. It's called Interprocess.

It's not currently in "main" boost. However, you can get the headers,
library, docs and example from CVS in boost/libs/interprocess/
Also google boost interprocess for mailing list discussion on the
subject.

Note that this is new boost stuff that might of might not be fully up
to release status and it might or might not work on your platform.
There's quite a lot of test code supplied so you can try it. I'd also
recommend that you do extensive testing of your shared queue design
under soak and stress conditions for possible memory fragmentation or
performance deterioration over time.

Hope this helps

Yan
 
J

Just me

Thoughts? Has anyone done work that can shed some light on using custom
memory handlers or shared memory with the STL classes?

Thanks for the input. I'll have to investigate further. If I could make
custom allocators work properly then that would be my first choice. If
that seems like a jar of worms then I'll look at the boost stuff.
 
J

Jerry Coffin

[ ... ]
I believe that a common implementation of strings is to have a small
object that contains data about the string but keeps the actual string
else-where. Actually I can see no other way to implement it while still
allowing a string to be allocated on the stack and later changed (in
length). This might be solvable using a special allocator that uses your
shared memory, but to get that to play nice over several processes might
be a challenge.

This is partly correct, but there's a wrinkle that would cause a major
problem with using shared memory: quite a few implmentations of
std::basic_string implement an optimization for short strings: to avoid
dynamically allocating space for a short string, they allocate a small
amount of space in the string object itself, and only when/if that
overflows do they allocate space dynamically.
 
J

JohnQ

Jerry Coffin said:
quite a few implmentations of
std::basic_string implement an optimization for short strings: to avoid
dynamically allocating space for a short string, they allocate a small
amount of space in the string object itself, and only when/if that
overflows do they allocate space dynamically.

What size is that first chunk typically?

John
 
C

Chris Thomasson

Me said:
howdy.

Some of this will sound a bit platform specific and a few of you will feel
the need to yell "off-topic" but please refrain because the parts of the
problem I'm asking about are generic enough to be relevant.
[...]

You should post any follow-ups that deal with synchronization over on
comp.programming.threads.
 
M

Michael DOUBEZ

Me a écrit :
howdy.

Some of this will sound a bit platform specific and a few of you will feel
the need to yell "off-topic" but please refrain because the parts of the
problem I'm asking about are generic enough to be relevant.

I use c++ for embedded applications because my tasks are very complex but
I still need to be able to directly deal with hardware. I've been working
for the past couple of years with a really screwey robotics protocol
called JAUS and I've been violating the standard and doing things my own
way but I now need to investigate a higher level of compatibility with
other systems that more closely adhere to the architecture.

The standard calls for a series of software components that do different
robotics functions and also has very strict message routing rules. It is
these strict message routing rules that make it difficult and inefficient
to implement conforming systems in my POSIX runtime environment. Each
component is a separate process with separate address space. This means
that to follow the architecture I must use IPC to route messages to
applicable components. However, POSIX IPC introduces unacceptable latency
into the system. Depending upon system load I can see measurable 10 to
100ms round trip delay of routed messages when using named pipe IPC. That
isn't adequate when the data payloads are real-time audio/video or command
and control data.

To solve this problem I want to implement a shared memory priority queue
that is accessible by all component processes. The clencher is that I'd
like to be able to insert std::string objects into the queue. This is not
a simple case of multithreaded application since each component runs in
its own address space. What I'm asking is whether there is a relatively
safe way to make the std::string accessible by two or more separate
processes. If I knew that all internal string memory was handled thru new/
delete I presume that I could implement a custom handler to use my shared
memory pool...but if within the string class there are any pointers that
are initialized to process specific address space then the thing will most
certainly blow up.

Someone will undoubtedly bring up the syncronization issue. That is taken
care of by using a platform specific atomic operation on the shared
memory, thus guaranteeing mutually exclusive access as long as the lock is
properly acquired and released.

Thoughts? Has anyone done work that can shed some light on using custom
memory handlers or shared memory with the STL classes?

That depends on your string implementation. If it uses pointer (which is
likely), you will have problems because the segment shared between
processes are at different virtual location. You have to implment
everything in terms of offset from the current objet.

There already is a boost library for STL in shared memory called
"interprocess". I don't known it status (there was some refactoring when
I last looked at it).

Michael
 
J

JohnQ

Jerry Coffin said:
Something like 20 characters, IIRC.

I can only assume that the size chosen was completely arbitrary. (I was
going to say that maybe alignment concerns made 20 lucrative for a specific
implementation, but since string isn't a POD, I don't see how it would
matter).

John
 
J

Jerry Coffin

[ ... size of initial chunk when short string optimization is used ]
I can only assume that the size chosen was completely arbitrary. (I was
going to say that maybe alignment concerns made 20 lucrative for a specific
implementation, but since string isn't a POD, I don't see how it would
matter).

I don't think it's completely arbitrary. While I haven't looked at it
directly, there are persistent rumors of a study that showed the vast
majority (90%?) of strings are no more than 20 characters long.
 
J

James Kanze

Jerry Coffin said:
Something like 20 characters, IIRC.

VC++ seems to use 16, judging from the quick test I did.

The optimal value will typically depend somewhat on the
hardware, as well as the utilisation in the application. I
suspect that for some hardware, for example, copying something
that will fit in a single cache line will be a lot faster than
copying something that won't.
 
C

Chris Thomasson

Just me said:
Me said:
howdy.

Some of this will sound a bit platform specific and a few of you will
feel the need to yell "off-topic" but please refrain because the parts
of the problem I'm asking about are generic enough to be relevant.
[...]

You should post any follow-ups that deal with synchronization over on
comp.programming.threads.

Implementing the stl classes within shared memory is more work than I want
to take on so I and my programmers are just implementing some simple
template containers from scratch: just enough to get the job done.

The following post(s)/thread(s) may be of interest to you:

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/b5775d829f3f1259

http://groups.google.com/group/comp.os.linux.development.apps/msg/68ceceba0db5ad73

http://groups.google.com/group/comp.programming.threads/browse_frm/thread/7dda9ad554a976a6

http://groups.google.com/group/comp...omp.programming.threads&q=chris+thomasson+ipc

?
 
C

Chris Thomasson

Chris Thomasson said:
Just me said:
howdy.

Some of this will sound a bit platform specific and a few of you will
feel the need to yell "off-topic" but please refrain because the parts
of the problem I'm asking about are generic enough to be relevant.
[...]

You should post any follow-ups that deal with synchronization over on
comp.programming.threads.

Implementing the stl classes within shared memory is more work than I
want
to take on so I and my programmers are just implementing some simple
template containers from scratch: just enough to get the job done.

The following post(s)/thread(s) may be of interest to you:

Also, the following library can work within shared memory on several
architectures:

http://appcore.home.comcast.net/vzoom/pthread/
 
J

Just me

Me said:
howdy.

Some of this will sound a bit platform specific and a few of you will
feel the need to yell "off-topic" but please refrain because the parts
of the problem I'm asking about are generic enough to be relevant.
[...]

You should post any follow-ups that deal with synchronization over on
comp.programming.threads.

Implementing the stl classes within shared memory is more work than I want
to take on so I and my programmers are just implementing some simple
template containers from scratch: just enough to get the job done.
 
J

Jerry Coffin

[ ... ]
You should post any follow-ups that deal with synchronization over on
comp.programming.threads.

I'm not sure that's necessary. While it's not in the standard yet, I
believe the plan is that C++ 0x will include at least some support for
writing multi-threaded programs. If you want to study the currently-
proposed API, a look through N2094 is likely to be quite helpful.
 
J

JohnQ

Jerry Coffin said:
[ ... size of initial chunk when short string optimization is used ]
I can only assume that the size chosen was completely arbitrary. (I was
going to say that maybe alignment concerns made 20 lucrative for a
specific
implementation, but since string isn't a POD, I don't see how it would
matter).

I don't think it's completely arbitrary. While I haven't looked at it
directly, there are persistent rumors of a study that showed the vast
majority (90%?) of strings are no more than 20 characters long.

I consider that "arbitrary" (bad choice of word) relative to something like
JK mentioned: fitting into a single cache line.

John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top