[haiku-bugs] Re: [Haiku] #2657: Implement XSI shared memory <sys/shm.h>
- From: "bonefish" <trac@xxxxxxxxxxxx>
- Date: Tue, 04 Jan 2011 23:53:36 -0000
#2657: Implement XSI shared memory <sys/shm.h>
---------------------------+------------------------------
Reporter: kaliber | Owner: emitrax
Type: enhancement | Status: new
Priority: normal | Milestone: R1
Component: System/POSIX | Version: R1/Development
Resolution: | Keywords:
Blocked By: | Has a Patch: 1
Platform: All | Blocking:
---------------------------+------------------------------
Comment (by bonefish):
Replying to [comment:17 0xffea]:
> i tried to correct the style issues and not to use areas in kernel
space.
The coding style looks much better, now. A few issues remain:
* Inconsistent parameter naming in prototypes/implementations of various
related functions:
- `*shmctl()`: `mds`, `memoryDs`, `_buffer`, `buffer`. Unless you come
up with a better fitting name, `buffer` is the best one so far.
- `*shmat()`: `memoryPointer` -> `address`, `rAddress` ->
`_returnAddress`
- `*shmdt()`: `memoryPointer` -> `address`
* Inconsistent pointer style in the `_kern_*()` prototypes. Since both
styles are used in the file, either would be OK, but mixing in one block
or even one function is not so nice. Preferred is `Foo* foo`.
* In `syscalls.h`: `struct shmid_ds` is in wrong line.
* In `xsi_shared_memory.cpp`: The `<kernel/...>` includes block is not
sorted and the `kernel/` part should be omitted. The block should be
joined with the `<vm/...>` and `<util/...>` includes blocks (both are
kernel private includes).
* `MAX_XSI_SHARED_MEMORY_SIZE` definition: Missing spaces between the
operators and operands. Also, the whole expression should be put in
parentheses to prevent potential operator precedence issues where the
macro is expanded.
* In both `*HashTableDefinition` classes:
- Incorrect space after `HashKey`.
- Superfluous `const` of parameter type in `HashKey()` and `Compare()`.
- Superfluous parenthesis in `HashKey()` implementation.
* There are still a few instances of implicit `(foo & bar)` to `bool`
conversions. Also, `!(flags & IPC_CREAT)` should be `(flags & IPC_CREAT)
== 0`.
* Superfluous parenthesis in `if ((ipcKey->Size() < size) && (size !=
0))` (`_user_xsi_shmget()`), besides that, due to `size_t` being unsigned,
the second check is superfluous.
* Incorrect `(void*)` cast spacing in `_user_xsi_shmat()` (2x).
* Inconsistent pointer style in `xsi_shm.cpp`.
> * create a cache with VMCacheFactory::CreateAnonymousCache
> * use VMAddressSpace->CreateArea and VMAddressSpace->InsertArea to
create the area in user space
>
> hope this is the right way to do it. not sure about the proper locking.
Unfortunately things are quite a bit more complicated:
* A `VMAddressSpace` object is reference counted and has a read/write
lock. Holding the write lock is required for any manipulation operation
(creating, deleting, resizing areas) and also for manipulating most
members of the `VMArea` objects contained in the address space. Holding
the read lock guarantees that the respective address space and area
members don't change.
* A `VMCache` object is reference counted and has a simple mutex lock.
The lock must be held for almost all kinds of accesses to the object.
* Locking order is: address space -> area cache -> source cache -> ....
If multiple address spaces need to be locked, a `MultiAddressSpaceLocker`
must be used. There are more locking helper classes in
`src/system/kernel/vm/VMAddressSpaceLocking.h`.
* To map a `VMCache` into an address space, creating an area, the
function of choice is `map_backing_store()` in `vm/vm.cpp`. It gets the
job done with all the bells and whistles (including address and alignment
constraints, unmapping of previously mapped stuff, etc.). Only problem,
it's currently local to that source file. A simple kernel-private wrapper
(e.g. `vm_map_cache()`) could be introduced (prototype in `<vm/vm.h>`).
* When creating an area, it must be marked `B_SHARED_AREA` or it will
have copy-on-write behavior on `fork()`.
Generally I would recommend having a look at `vm/vm.cpp`. There are quite
a few functions that implement functionality similar to what you need.
E.g. `vm_create_anonymous_area()` creates a cache and maps it.
I haven't looked closely at the features the POSIX API requires, but it
might be possible to avoid playing with `VMCache`s altogether by using
memory-mapped files. That would allow for using a higher-lever API,
probably simplifying things quite a bit.
Regarding the tests: Actually using the shared memory is missing and is
definitely something that should be tested, also with multiple processes.
I believe the OpenPosixTestsuite in
`src/tests/system/libroot/posix/posixtestsuite` also has XSI shared memory
tests. Unfortunately some tests of the testing framework use functionality
Haiku is lacking or doesn't implement correctly yet (`clock_*()`,
signals), so the respective tests might not pass anyway, but it certainly
doesn't harm to have a look.
--
Ticket URL: <http://dev.haiku-os.org/ticket/2657#comment:18>
Haiku <http://dev.haiku-os.org>
Haiku - the operating system.
Other related posts: