trm@cbnews.ATT.COM (Tom R. Mueller) (04/07/89)
Does anyone know of solutions for the problems associated with C++ objects and shared memory in multiple Unix(r) processes. The following problems come to mind: What is a shared object? An obvious answer is an instantiation using 'new' of a class that overloads new so that the storage is allocated from shared memory. Given this answer and assuming that it isn't possible to cause the shared memory to be mapped to the same virtual address in every process, there are some more problems. Shared objects cannot have ordinary pointers inside them. Shared objects cannot have virtual member functions because they are implemented with pointers to functions. These two problems take away many of the benefits afforded by object-orientation when dealing with shared memory. What other definitions of a shared object are there? When two processes both want to access a single shared object, what is the best way to make this come about? Should 'new' be required and then the second process doesn't really get a pointer to a new object but rather a pointer to an already existing object? Should constructors be used and then the constructor doesn't really create a new object. Maybe one process should be required to somehow "pass" the identity of the shared object to the other process. How should the semantics be defined? - Tom Mueller AT&T Bell Laboratories (CB 0D109) (614) 860-5287 6200 East Broad Street ...att!cblpn!trm Columbus, OH 43213 -- - Tom Mueller AT&T Bell Laboratories (CB 0D109) (614) 860-5287 6200 East Broad Street ...att!cblpn!trm Columbus, OH 43213
shopiro@alice.UUCP (Jonathan Shopiro) (04/10/89)
I think the best way to deal with data in shared memory is with what I like to call ``surrogates.'' For example, you might have class Actual_shared_data { // this is an object in shared memory friend class Shared_data; // only data members here // no public data or functions at all }; class Shared_data { // this is the surrogate Actual_shared_data* p; public: Shared_data(); // constructor // the public interface goes here }; Then the constructor Shared_data::Shared_data() is in charge of allocating shared memory, or of finding the address of the appropriate shared memory object. Note that whenever you say ``new Shared_data'' you get a new Shared_data object, even if it points to an old block of shared memory. Storage management schemes that violate this rule are unlikely to win. If you can't have real pointers in shared memory because of address mapping considerations, it is simple to put whatever transformations are necessary between the data in Actual_shared_data and regular pointers into access functions in Shared_data. Shared_data can also have whatever virtual functions are appropriate. In exchange for an extra level of indirection (which you would be likely to need anyway) you can encapsulate all the complexity of dealing with shared memory in Shared_data, which the user treats like any other object. -- Jonathan Shopiro AT&T Bell Laboratories, Warren, NJ 07060-0908 research!shopiro (201) 580-4229
pcg@aber-cs.UUCP (Piercarlo Grandi) (04/10/89)
In article <5462@cbnews.ATT.COM> trm@cbnews.ATT.COM (Tom R. Mueller) writes:
.... Given this answer and assuming that it isn't possible to cause the
shared memory to be mapped to the same virtual address in every process,
there are some more problems.
Shared objects cannot have ordinary pointers inside them.
Shared objects cannot have virtual member functions because they are
implemented with pointers to functions.
Frankly I do not see any problem with C++, or object orientedness. There
are two solutions to your problem, and both do not involve C++ or object
oriented design:
RELATIVE POINTERS
This is an extremely powerful and useful concept, and is missing
from C. It is very useful to handle structures that may be present
at different addresses at different times. What one wants is to
define all pointers in a segment as relative to that segment.
Relative pointers solve neatly also two other problems; segmented
architectures (where they are definitely more general and subsume
near pointers) and saving/restoring data to/from persistent storage,
which is usually done instead by a clumsy process of linearization.
Note that this usual alternative is essentially transforming on save
all pointers to relative pointers, and then on reload transforming
them back to absolute ones.
Relative pointers may be defined in at least three ways (e.g. segmented,
based ala PL/1, relative ala MUPL). I am uncertain as to which I prefer.
Probably the segmented variety is what would serve you best. In it a
pointer declared as relative when dereferenced has the segment number
of ITS address prepended to it automatically.
NO SHARED MEMORY
I reckon that shared memory is absolutely unnecessary, just like
message passing. I have designed and am building an OS nucleus (in C++)
that will have neither; address spaces are going to be persistent, and
threads will be able to jump from one to another. In this way when
two threads communicate they are always in the same address space, and
no portion of address or data space is ever shared (which means that
the address space can be on different machines). By the way, I am also
considering adding relative pointers (or based ones) to C++ as well
(to make save/restore easier, not because of sharing).
--
Piercarlo "Peter" Grandi | ARPA: pcg%cs.aber.ac.uk@nss.cs.ucl.ac.uk
Dept of CS, UCW Aberystwyth | UUCP: ...!mcvax!ukc!aber-cs!pcg
Penglais, Aberystwyth SY23 3BZ, UK | INET: pcg@cs.aber.ac.uk
diamond@diamond.csl.sony.junet (Norman Diamond) (04/11/89)
In article <5462@cbnews.ATT.COM> trm@cbnews.ATT.COM (Tom R. Mueller) writes: >Does anyone know of solutions for the problems associated with >C++ objects and shared memory in multiple Unix(r) processes. >... assuming that it isn't >possible to cause the shared memory to be mapped to the same virtual >address in every process, there are some more problems. >Shared objects cannot have ordinary pointers inside them. >Shared objects cannot have virtual member functions because they are >implemented with pointers to functions. These problems existed in older programming languages and in assembler too, and even before virtual memory. The necessary solution is the same. If some block of memory (or object) has different addresses for access by different processors (or processes), then pointers within the block cannot be absolute (whether real or virtual addresses). They must be offsets of some sort, and the absolute addresses must be computed by the code doing the access. Each offset might be relative to the beginning of the block (e.g. "23 bytes past where you think the object begins") or self-relative (e.g. "152 bytes before me"). Norman Diamond, Sony Computer Science Lab (diamond%csl.sony.jp@relay.cs.net) The above opinions are my own. | Why are programmers criticized for If they're also your opinions, | re-inventing the wheel, when car you're infringing my copyright. | manufacturers are praised for it?
turner@sdti.SDTI.COM (Prescott K. Turner) (04/12/89)
In article <9171@alice.UUCP> shopiro@alice.UUCP (Jonathan Shopiro) writes: >I think the best way to deal with data in shared memory is with >what I like to call ``surrogates.'' ... > >If you can't have real pointers in shared memory because of address >mapping considerations, it is simple to put whatever transformations >are necessary between the data in Actual_shared_data and regular >pointers into access functions in Shared_data. Shared_data can also >have whatever virtual functions are appropriate. At SDTI we have been dealing with a similar problem using a "surrogate" solution. Our most significant objects go in the memory which can't have real pointers. Even though Shared_data can have virtual functions, and can refer to the Actual_shared_data object, it will behave according to how the Shared_data object was constructed, not according to how the Actual_shared_data object was constructed. This has been so restrictive that I wonder if I'm getting any experience with real object-oriented design in my area of application. I've been tempted to hack at Shared_data's constructors. When a Shared_data object is constructed which refers to a pre-existing Actual_shared_data object, the underlying vtbl pointer of the constructed Shared_data object would be modified. It would then refer to the class derived from Shared_data which corresponds correctly to the Actual_share_data object. Anyone care to comment on the level of danger of such a hack? -- Prescott K. Turner, Jr. Software Development Technologies, Inc. P.O. Box 366, Sudbury, MA 01776 USA (508) 443-5779 UUCP: ...{harvard,mit-eddie}!sdti!turner Internet: turner@sdti.sdti.com
ldg@druin.ATT.COM (Doug Gibbons) (04/13/89)
Here's another trick for passing objects with virtual functions through shared memory: 1) Use +e0/+e1 to create a vtbl.c 2) Load vtbl.o at the same place in all a.outs that are to share objects. This can be done simply by passing vtbl.o as the first file to ld. 3) When objects are placed in shared memory, their vtbl ptrs are valid for any a.out address space, even though the contents of the vtbls may be different in each space. -- -------------------------------------------------------------------------------- -- Doug Gibbons | ldg@druhi.ATT.COM or att!druhi!ldg -- AT&T Bell Laboratories -- Denver CO