Opened 12 years ago
Last modified 19 months ago
#2657 new enhancement
Implement XSI shared memory <sys/shm.h>
| Reported by: | kaliber | Owned by: | emitrax |
|---|---|---|---|
| Priority: | normal | Milestone: | Unscheduled |
| Component: | System/POSIX | Version: | R1/Development |
| Keywords: | Cc: | haiku@…, umccullough@…, richienyhus@…, adek336@…, michaelvoliveira@…, 0xffea@…, mark@… | |
| Blocked By: | Blocking: | ||
| Platform: | All |
Description
sys/shm.h is missing and not implemented in Haiku. It would be nice to have it.
http://www.opengroup.org/onlinepubs/009695399/basedefs/sys/shm.h.html
Attachments (5)
Change History (31)
comment:1 by , 12 years ago
| Owner: | changed from to |
|---|
comment:2 by , 12 years ago
| Cc: | added |
|---|
comment:3 by , 11 years ago
| Cc: | added |
|---|
comment:4 by , 11 years ago
| Cc: | added |
|---|
comment:5 by , 11 years ago
| Cc: | added |
|---|
comment:6 by , 11 years ago
| Component: | - General → System/POSIX |
|---|
follow-up: 9 comment:8 by , 10 years ago
This one will be necessary for a decent port of boost-1.42
We could use this one from FreeBSD.. of course, since that we axe some functions from there...
comment:9 by , 10 years ago
Replying to michaelvoliveira:
This one will be necessary for a decent port of boost-1.42
We could use this one from FreeBSD.. of course, since that we axe some functions from there...
The header is the trivial part (copy and paste from the specs). The implementation is the actual work.
comment:10 by , 10 years ago
| Cc: | added |
|---|
Ok them...
This code (BSD 3-clause) has taken from postgresql-8.1.20..
But I don't know how make a good patch because I don't know where shm.c would fit in the tree.
comment:12 by , 10 years ago
| Version: | R1/pre-alpha1 → R1/Development |
|---|
comment:13 by , 10 years ago
Besides only approximating the feature (one can't emulate it correctly with areas), the code has other problems, like missing error checks, incorrect return values and incorrect function signatures.
comment:14 by , 9 years ago
| Cc: | added |
|---|
by , 9 years ago
| Attachment: | draft-shm-001.patch added |
|---|
comment:15 by , 9 years ago
| patch: | 0 → 1 |
|---|
comment:16 by , 9 years ago
Thanks for the patch. I haven't looked too closely yet, but it seems a good start. There's a whole bunch of coding style issues, though. Just pointing out a few:
- Two blank lines between groups of unrelated stuff -- e.g. before and after
#include,#define, variable declaration, etc. blocks and between functions. Never within functions or class definitions, though (max. one blank line there). No blank line between copyright header and header guard. - No blank line at the beginning or end of blocks (
SharedMemoryEntry::HasPermission()). - Don't indent/align with anything but tabs. Only exception is in class definitions when e.g. the type needs more space than there is in its column. Then a single space can be used to separate it from the next column.
- Don't indent names in local variable definitions.
- No spaces after C cast operator (wrong:
(int) fArea). - No space between function name and opening parenthesis (also
new(std::nothrow)), but single space betweenif/switch/... and opening parenthesis. - Always name parameters in function/method prototypes.
- Don't use uncommon abbreviations in identifiers. E.g.
addrshould beaddress,fDsshould befDataorfDefinitionor whatever that might stand for. - Use a consistent pointer style, preferably
Foo* foo. - No unnecessary parentheses (wrong:
fDs.shm_perm.mode = (flags & 0x01ff);). - In function definitions define variables where they are first used, not at the beginning of the function. Whenever possible combine definition and initialization (
status_t status = ...). if (fArea < B_OK): Compare with< 0instead, when values>= 0are valid. Use the stricter comparison!= B_OK, when the value is supposed to be an error code (i.e.B_OKor another error code, normally of typestatus_t).- Explicitly force bit check expressions to boolean (
(flags & IPC_CREAT) != 0). - When wrapping an expression, the operator always goes to beginning of the next line.
- Broken indentation in
SharedMemoryEntry::HasReadPermission()and_user_xsi_shmget().
I haven't really looked at the implementation, but I noticed:
_user_xsi_shmat():raddrneeds to be copied out viauser_memcpy(). Besides, it needs a better name. Also, it is recommended to prefix output parameters with_, e.g._mappedAddressin this case.- Using fully locked kernel areas is not a good idea. The locking isn't necessary at all. But the bigger issue is that kernel address space is a rather limited resource. I'd only create a
VMCacheand map it into the user address spaces as needed, but not into the kernel address space at all.
by , 9 years ago
| Attachment: | draft-shm-002.patch added |
|---|
follow-up: 18 comment:17 by , 9 years ago
bonefish: thanks for the very helpful comments!
i tried to correct the style issues and not to use areas in kernel space.
- 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.
comment:18 by , 9 years ago
Replying to 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,bufferis 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 isFoo* foo. - In
syscalls.h:struct shmid_dsis in wrong line. - In
xsi_shared_memory.cpp: The<kernel/...>includes block is not sorted and thekernel/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_SIZEdefinition: 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
*HashTableDefinitionclasses:- Incorrect space after
HashKey. - Superfluous
constof parameter type inHashKey()andCompare(). - Superfluous parenthesis in
HashKey()implementation.
- Incorrect space after
- There are still a few instances of implicit
(foo & bar)toboolconversions. 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 tosize_tbeing 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
VMAddressSpaceobject 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 theVMAreaobjects contained in the address space. Holding the read lock guarantees that the respective address space and area members don't change. - A
VMCacheobject 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
MultiAddressSpaceLockermust be used. There are more locking helper classes insrc/system/kernel/vm/VMAddressSpaceLocking.h. - To map a
VMCacheinto an address space, creating an area, the function of choice ismap_backing_store()invm/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_AREAor it will have copy-on-write behavior onfork().
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 VMCaches 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.
by , 6 years ago
| Attachment: | 0001-work-in-progress-patch-for-XSI-shm.h-implementation.patch added |
|---|
updated patch with style and build fixes
comment:19 by , 6 years ago
| Cc: | added |
|---|
comment:20 by , 5 years ago
| Milestone: | R1 → Unscheduled |
|---|
Move POSIX compatibility related tickets out of R1 milestone (FutureHaiku/Features).
follow-up: 22 comment:21 by , 5 years ago
Ping.
Has an updated patch here waiting so long for a commit
comment:22 by , 5 years ago
Replying to michaelvoliveira:
Has an updated patch here waiting so long for a commit
I haven't looked at the latest patch, but if korli has only addressed the style issues and applied build fixes as its description says, the second part of comment:18 still remains to be addressed.
comment:23 by , 5 years ago
Thanks for the reply! I'll try build libboost again using #ifdef and vm_create_anonymous_area() like you suggested.
comment:24 by , 2 years ago
| patch: | 1 → 0 |
|---|
comment:26 by , 19 months ago
| patch: | → 0 |
|---|
Besides only approximating the feature (one can't emulate it correctly with areas),
@bonefish, how so? It looks like we would need a set of housekeeping structs or the like to keep track of the "modification time", etc. and other such values, so we would still need new syscalls, but AFAICT there is nothing that shm areas can do that Be areas cannot -- so can you perhaps elaborate on what those are, if you can recall?



If no one else wants it, I should be able to do it.