From 0cf869e56a8c3421f0710acf090158add82adf70 Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Thu, 5 Jan 2017 18:30:01 -0800 Subject: [PATCH 1/3] add multiple shared memory blocks, to allow multiple simultaneous connections. At the moment, MAX_SHARED_MEMORY_BLOCKS = 2 Note that the amount of shared memory is limited on many systems, 32MB, while one block is already over 1MB at the moment... You can connect to SHARED_MEMORY using the current key, and key+1. There are a few commands that cannot currently be executed in parallel among multiple connections, since the implementation of the server caches some data: rendering image (getCameraData), getting contact point data and getting debug lines. --- .../SharedMemory/PhysicsServerExample.cpp | 18 +- .../PhysicsServerSharedMemory.cpp | 258 ++++++++++-------- 2 files changed, 138 insertions(+), 138 deletions(-) diff --git a/examples/SharedMemory/PhysicsServerExample.cpp b/examples/SharedMemory/PhysicsServerExample.cpp index ca4d9e204..889c3a5b8 100644 --- a/examples/SharedMemory/PhysicsServerExample.cpp +++ b/examples/SharedMemory/PhysicsServerExample.cpp @@ -1439,23 +1439,7 @@ void PhysicsServerExample::stepSimulation(float deltaTime) - #if 0 - if (m_options == PHYSICS_SERVER_USE_RTC_CLOCK) - { - btClock rtc; - btScalar endTime = rtc.getTimeMilliseconds() + deltaTime*btScalar(800); - - while (rtc.getTimeMilliseconds()m_childGuiHelper->getRenderInterface()) { diff --git a/examples/SharedMemory/PhysicsServerSharedMemory.cpp b/examples/SharedMemory/PhysicsServerSharedMemory.cpp index 5c967c9c4..004bc048c 100644 --- a/examples/SharedMemory/PhysicsServerSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsServerSharedMemory.cpp @@ -14,7 +14,8 @@ #include "PhysicsServerCommandProcessor.h" - +//number of shared memory blocks == number of simultaneous connections +#define MAX_SHARED_MEMORY_BLOCKS 2 struct PhysicsServerSharedMemoryInternalData { @@ -25,7 +26,7 @@ struct PhysicsServerSharedMemoryInternalData SharedMemoryInterface* m_sharedMemory; bool m_ownsSharedMemory; - SharedMemoryBlock* m_testBlock1; + SharedMemoryBlock* m_testBlocks[MAX_SHARED_MEMORY_BLOCKS]; int m_sharedMemoryKey; bool m_isConnected; bool m_verboseOutput; @@ -34,27 +35,31 @@ struct PhysicsServerSharedMemoryInternalData PhysicsServerSharedMemoryInternalData() :m_sharedMemory(0), m_ownsSharedMemory(false), - m_testBlock1(0), - m_sharedMemoryKey(SHARED_MEMORY_KEY), + m_sharedMemoryKey(SHARED_MEMORY_KEY), m_isConnected(false), m_verboseOutput(false), m_commandProcessor(0) { - + + for (int i=0;im_serverCommands[0]; + SharedMemoryStatus& serverCmd =m_testBlocks[blockIndex]->m_serverCommands[0]; serverCmd .m_type = statusType; serverCmd.m_sequenceNumber = sequenceNumber; serverCmd.m_timeStamp = timeStamp; return serverCmd; } - void submitServerStatus(SharedMemoryStatus& status) + void submitServerStatus(SharedMemoryStatus& status,int blockIndex) { - m_testBlock1->m_numServerCommands++; + m_testBlocks[blockIndex]->m_numServerCommands++; } }; @@ -117,39 +122,41 @@ bool PhysicsServerSharedMemory::connectSharedMemory( struct GUIHelperInterface* int counter = 0; - do - { - - m_data->m_testBlock1 = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE,allowCreation); - if (m_data->m_testBlock1) - { - int magicId =m_data->m_testBlock1->m_magicId; - if (m_data->m_verboseOutput) - { - b3Printf("magicId = %d\n", magicId); - } - - if (m_data->m_testBlock1->m_magicId !=SHARED_MEMORY_MAGIC_NUMBER) - { - InitSharedMemoryBlock(m_data->m_testBlock1); - if (m_data->m_verboseOutput) - { - b3Printf("Created and initialized shared memory block\n"); - } - m_data->m_isConnected = true; - } else - { - m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE); - m_data->m_testBlock1 = 0; - m_data->m_isConnected = false; - } - } else - { - b3Error("Cannot connect to shared memory"); - m_data->m_isConnected = false; - } - } while (counter++ < 10 && !m_data->m_isConnected); + for (int block=0;blockm_testBlocks[block] = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE,allowCreation); + if (m_data->m_testBlocks[block]) + { + int magicId =m_data->m_testBlocks[block]->m_magicId; + if (m_data->m_verboseOutput) + { + b3Printf("magicId = %d\n", magicId); + } + + if (m_data->m_testBlocks[block]->m_magicId !=SHARED_MEMORY_MAGIC_NUMBER) + { + InitSharedMemoryBlock(m_data->m_testBlocks[block]); + if (m_data->m_verboseOutput) + { + b3Printf("Created and initialized shared memory block\n"); + } + m_data->m_isConnected = true; + } else + { + m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE); + m_data->m_testBlocks[block] = 0; + m_data->m_isConnected = false; + } + } else + { + b3Error("Cannot connect to shared memory"); + m_data->m_isConnected = false; + } + } while (counter++ < 10 && !m_data->m_isConnected); + } if (!m_data->m_isConnected) { b3Error("Server cannot connect to shared memory.\n"); @@ -167,71 +174,77 @@ void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMe { b3Printf("releaseSharedMemory1\n"); } - if (m_data->m_testBlock1) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_testBlock1\n"); - } - if (deInitializeSharedMemory) - { - m_data->m_testBlock1->m_magicId = 0; - if (m_data->m_verboseOutput) - { - b3Printf("De-initialized shared memory, magic id = %d\n",m_data->m_testBlock1->m_magicId); - } - } - btAssert(m_data->m_sharedMemory); - m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE); - } - if (m_data->m_sharedMemory) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_sharedMemory\n"); - } - if (m_data->m_ownsSharedMemory) - { - delete m_data->m_sharedMemory; - } - m_data->m_sharedMemory = 0; - m_data->m_testBlock1 = 0; - } + for (int block = 0;blockm_testBlocks[block]) + { + if (m_data->m_verboseOutput) + { + b3Printf("m_testBlock1\n"); + } + if (deInitializeSharedMemory) + { + m_data->m_testBlocks[block]->m_magicId = 0; + if (m_data->m_verboseOutput) + { + b3Printf("De-initialized shared memory, magic id = %d\n",m_data->m_testBlocks[block]->m_magicId); + } + } + btAssert(m_data->m_sharedMemory); + m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE); + } + if (m_data->m_sharedMemory) + { + if (m_data->m_verboseOutput) + { + b3Printf("m_sharedMemory\n"); + } + if (m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } + m_data->m_sharedMemory = 0; + m_data->m_testBlocks[block] = 0; + } + } } void PhysicsServerSharedMemory::releaseSharedMemory() { - if (m_data->m_verboseOutput) - { - b3Printf("releaseSharedMemory1\n"); - } - if (m_data->m_testBlock1) + for (int block = 0;blockm_verboseOutput) - { - b3Printf("m_testBlock1\n"); - } - m_data->m_testBlock1->m_magicId = 0; - if (m_data->m_verboseOutput) - { - b3Printf("magic id = %d\n",m_data->m_testBlock1->m_magicId); - } - btAssert(m_data->m_sharedMemory); - m_data->m_sharedMemory->releaseSharedMemory( m_data->m_sharedMemoryKey -, SHARED_MEMORY_SIZE); - } - if (m_data->m_sharedMemory) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_sharedMemory\n"); - } - if (m_data->m_ownsSharedMemory) - { - delete m_data->m_sharedMemory; - } - m_data->m_sharedMemory = 0; - m_data->m_testBlock1 = 0; + if (m_data->m_verboseOutput) + { + b3Printf("releaseSharedMemory1\n"); + } + if (m_data->m_testBlocks[block]) + { + if (m_data->m_verboseOutput) + { + b3Printf("m_testBlock1\n"); + } + m_data->m_testBlocks[block]->m_magicId = 0; + if (m_data->m_verboseOutput) + { + b3Printf("magic id = %d\n",m_data->m_testBlocks[block]->m_magicId); + } + btAssert(m_data->m_sharedMemory); + m_data->m_sharedMemory->releaseSharedMemory( m_data->m_sharedMemoryKey+block + , SHARED_MEMORY_SIZE); + } + if (m_data->m_sharedMemory) + { + if (m_data->m_verboseOutput) + { + b3Printf("m_sharedMemory\n"); + } + if (m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } + m_data->m_sharedMemory = 0; + m_data->m_testBlocks[block] = 0; + } } } @@ -250,30 +263,33 @@ void PhysicsServerSharedMemory::enableRealTimeSimulation(bool enableRealTimeSim) void PhysicsServerSharedMemory::processClientCommands() { - if (m_data->m_isConnected && m_data->m_testBlock1) + for (int block = 0;blockm_commandProcessor->replayLogCommand(&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); - - ///we ignore overflow of integer for now - if (m_data->m_testBlock1->m_numClientCommands> m_data->m_testBlock1->m_numProcessedClientCommands) + if (m_data->m_isConnected && m_data->m_testBlocks[block]) { - - - //until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands - btAssert(m_data->m_testBlock1->m_numClientCommands==m_data->m_testBlock1->m_numProcessedClientCommands+1); + m_data->m_commandProcessor->replayLogCommand(&m_data->m_testBlocks[block]->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); - const SharedMemoryCommand& clientCmd =m_data->m_testBlock1->m_clientCommands[0]; + ///we ignore overflow of integer for now + if (m_data->m_testBlocks[block]->m_numClientCommands> m_data->m_testBlocks[block]->m_numProcessedClientCommands) + { + - m_data->m_testBlock1->m_numProcessedClientCommands++; - //todo, timeStamp - int timeStamp = 0; - SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp); - bool hasStatus = m_data->m_commandProcessor->processCommand(clientCmd, serverStatusOut,&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); - if (hasStatus) - { - m_data->submitServerStatus(serverStatusOut); - } - + //until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands + btAssert(m_data->m_testBlocks[block]->m_numClientCommands==m_data->m_testBlocks[block]->m_numProcessedClientCommands+1); + + const SharedMemoryCommand& clientCmd =m_data->m_testBlocks[block]->m_clientCommands[0]; + + m_data->m_testBlocks[block]->m_numProcessedClientCommands++; + //todo, timeStamp + int timeStamp = 0; + SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp,block); + bool hasStatus = m_data->m_commandProcessor->processCommand(clientCmd, serverStatusOut,&m_data->m_testBlocks[block]->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); + if (hasStatus) + { + m_data->submitServerStatus(serverStatusOut,block); + } + + } } } } From 8e554a0c1b3a7f1907015140f306fe0b68de8c8f Mon Sep 17 00:00:00 2001 From: Erwin Coumans Date: Fri, 6 Jan 2017 09:49:03 -0800 Subject: [PATCH 2/3] allow creation of multiple shared memory segments --- .../PhysicsServerSharedMemory.cpp | 112 +++++++----------- examples/SharedMemory/PosixSharedMemory.cpp | 74 +++++++++--- src/LinearMath/btAlignedObjectArray.h | 15 ++- 3 files changed, 109 insertions(+), 92 deletions(-) diff --git a/examples/SharedMemory/PhysicsServerSharedMemory.cpp b/examples/SharedMemory/PhysicsServerSharedMemory.cpp index 004bc048c..f19620cbd 100644 --- a/examples/SharedMemory/PhysicsServerSharedMemory.cpp +++ b/examples/SharedMemory/PhysicsServerSharedMemory.cpp @@ -28,7 +28,7 @@ struct PhysicsServerSharedMemoryInternalData SharedMemoryBlock* m_testBlocks[MAX_SHARED_MEMORY_BLOCKS]; int m_sharedMemoryKey; - bool m_isConnected; + bool m_areConnected[MAX_SHARED_MEMORY_BLOCKS]; bool m_verboseOutput; PhysicsServerCommandProcessor* m_commandProcessor; @@ -36,8 +36,7 @@ struct PhysicsServerSharedMemoryInternalData :m_sharedMemory(0), m_ownsSharedMemory(false), m_sharedMemoryKey(SHARED_MEMORY_KEY), - m_isConnected(false), - m_verboseOutput(false), + m_verboseOutput(false), m_commandProcessor(0) { @@ -45,7 +44,7 @@ struct PhysicsServerSharedMemoryInternalData for (int i=0;im_commandProcessor->deleteDynamicsWorld(); delete m_data->m_commandProcessor; - delete m_data; + + if (m_data->m_sharedMemory) + { + if (m_data->m_verboseOutput) + { + b3Printf("m_sharedMemory\n"); + } + if (m_data->m_ownsSharedMemory) + { + delete m_data->m_sharedMemory; + } + m_data->m_sharedMemory = 0; + } + + + delete m_data; } void PhysicsServerSharedMemory::resetDynamicsWorld() @@ -112,18 +127,22 @@ bool PhysicsServerSharedMemory::connectSharedMemory( struct GUIHelperInterface* bool allowCreation = true; + bool allConnected = false; + - if (m_data->m_isConnected) - { - b3Warning("connectSharedMemory, while already connected"); - return m_data->m_isConnected; - } + int counter = 0; for (int block=0;blockm_areConnected[block]) + { + allConnected = true; + b3Warning("connectSharedMemory, while already connected"); + continue; + } do { @@ -143,26 +162,26 @@ bool PhysicsServerSharedMemory::connectSharedMemory( struct GUIHelperInterface* { b3Printf("Created and initialized shared memory block\n"); } - m_data->m_isConnected = true; + m_data->m_areConnected[block] = true; } else { m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE); m_data->m_testBlocks[block] = 0; - m_data->m_isConnected = false; + m_data->m_areConnected[block] = false; } } else { b3Error("Cannot connect to shared memory"); - m_data->m_isConnected = false; + m_data->m_areConnected[block] = false; } - } while (counter++ < 10 && !m_data->m_isConnected); + } while (counter++ < 10 && !m_data->m_areConnected[block]); + if (!m_data->m_areConnected[block]) + { + b3Error("Server cannot connect to shared memory.\n"); + } } - if (!m_data->m_isConnected) - { - b3Error("Server cannot connect to shared memory.\n"); - } - return m_data->m_isConnected; + return allConnected; } @@ -193,59 +212,15 @@ void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMe btAssert(m_data->m_sharedMemory); m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE); } - if (m_data->m_sharedMemory) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_sharedMemory\n"); - } - if (m_data->m_ownsSharedMemory) - { - delete m_data->m_sharedMemory; - } - m_data->m_sharedMemory = 0; - m_data->m_testBlocks[block] = 0; - } + m_data->m_testBlocks[block] = 0; + m_data->m_areConnected[block] = false; + } } void PhysicsServerSharedMemory::releaseSharedMemory() { - for (int block = 0;blockm_verboseOutput) - { - b3Printf("releaseSharedMemory1\n"); - } - if (m_data->m_testBlocks[block]) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_testBlock1\n"); - } - m_data->m_testBlocks[block]->m_magicId = 0; - if (m_data->m_verboseOutput) - { - b3Printf("magic id = %d\n",m_data->m_testBlocks[block]->m_magicId); - } - btAssert(m_data->m_sharedMemory); - m_data->m_sharedMemory->releaseSharedMemory( m_data->m_sharedMemoryKey+block - , SHARED_MEMORY_SIZE); - } - if (m_data->m_sharedMemory) - { - if (m_data->m_verboseOutput) - { - b3Printf("m_sharedMemory\n"); - } - if (m_data->m_ownsSharedMemory) - { - delete m_data->m_sharedMemory; - } - m_data->m_sharedMemory = 0; - m_data->m_testBlocks[block] = 0; - } - } + disconnectSharedMemory(true); } @@ -265,7 +240,8 @@ void PhysicsServerSharedMemory::processClientCommands() { for (int block = 0;blockm_isConnected && m_data->m_testBlocks[block]) + + if (m_data->m_areConnected[block] && m_data->m_testBlocks[block]) { m_data->m_commandProcessor->replayLogCommand(&m_data->m_testBlocks[block]->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); diff --git a/examples/SharedMemory/PosixSharedMemory.cpp b/examples/SharedMemory/PosixSharedMemory.cpp index 0297d43e2..16c439d48 100644 --- a/examples/SharedMemory/PosixSharedMemory.cpp +++ b/examples/SharedMemory/PosixSharedMemory.cpp @@ -1,6 +1,7 @@ #include "PosixSharedMemory.h" #include "Bullet3Common/b3Logging.h" #include "LinearMath/btScalar.h" //for btAssert +#include "LinearMath/btAlignedObjectArray.h" //Windows implementation is in Win32SharedMemory.cpp #ifndef _WIN32 @@ -16,16 +17,28 @@ #endif +struct btSharedMemorySegment +{ + int m_key; + int m_sharedMemoryId; + void* m_sharedMemoryPtr; + bool m_createdSharedMemory; + + btSharedMemorySegment() + : m_sharedMemoryId(-1), + m_sharedMemoryPtr(0), + m_createdSharedMemory(true) + { + } + +}; + struct PosixSharedMemoryInteralData { - bool m_createdSharedMemory; - int m_sharedMemoryId; - void* m_sharedMemoryPtr; - + btAlignedObjectArray m_segments; + + PosixSharedMemoryInteralData() - :m_createdSharedMemory(false), - m_sharedMemoryId(-1), - m_sharedMemoryPtr(0) { } }; @@ -67,9 +80,12 @@ void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCr b3Error("shmat returned -1"); } else { - m_internalData->m_createdSharedMemory = allowCreation; - m_internalData->m_sharedMemoryId = id; - m_internalData->m_sharedMemoryPtr = result.ptr; + btSharedMemorySegment seg; + seg.m_key = key; + seg.m_createdSharedMemory = allowCreation; + seg.m_sharedMemoryId = id; + seg.m_sharedMemoryPtr = result.ptr; + m_internalData->m_segments.push_back(seg); return result.ptr; } } @@ -82,14 +98,33 @@ void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCr void PosixSharedMemory::releaseSharedMemory(int key, int size) { #ifdef TEST_SHARED_MEMORY - if (m_internalData->m_sharedMemoryId < 0) + + btSharedMemorySegment* seg = 0; + int i=0; + + for (i=0;im_segments.size();i++) + { + if (m_internalData->m_segments[i].m_key == key) + { + seg = &m_internalData->m_segments[i]; + break; + } + } + + if (0==seg) + { + b3Error("PosixSharedMemory::releaseSharedMemory: shared memory key not found"); + return; + } + + if (seg->m_sharedMemoryId < 0) { b3Error("PosixSharedMemory::releaseSharedMemory: shared memory id is not set"); } else { - if (m_internalData->m_createdSharedMemory) + if (seg->m_createdSharedMemory) { - int result = shmctl(m_internalData->m_sharedMemoryId,IPC_RMID,0); + int result = shmctl(seg->m_sharedMemoryId,IPC_RMID,0); if (result == -1) { b3Error("PosixSharedMemory::releaseSharedMemory: shmat returned -1"); @@ -97,15 +132,18 @@ void PosixSharedMemory::releaseSharedMemory(int key, int size) { b3Printf("PosixSharedMemory::releaseSharedMemory removed shared memory"); } - m_internalData->m_createdSharedMemory = false; - m_internalData->m_sharedMemoryId = -1; + seg->m_createdSharedMemory = false; + seg->m_sharedMemoryId = -1; } - if (m_internalData->m_sharedMemoryPtr) + if (seg->m_sharedMemoryPtr) { - shmdt(m_internalData->m_sharedMemoryPtr); - m_internalData->m_sharedMemoryPtr = 0; + shmdt(seg->m_sharedMemoryPtr); + seg->m_sharedMemoryPtr = 0; b3Printf("PosixSharedMemory::releaseSharedMemory detached shared memory\n"); } } + + m_internalData->m_segments.removeAtIndex(i); + #endif } diff --git a/src/LinearMath/btAlignedObjectArray.h b/src/LinearMath/btAlignedObjectArray.h index 146ae72e8..56f8189c1 100644 --- a/src/LinearMath/btAlignedObjectArray.h +++ b/src/LinearMath/btAlignedObjectArray.h @@ -476,15 +476,18 @@ protected: return index; } + void removeAtIndex(int index) + { + if (index Date: Fri, 6 Jan 2017 09:55:22 -0800 Subject: [PATCH 3/3] avoid creating shared memory segments with same key multiple times --- examples/SharedMemory/PosixSharedMemory.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/examples/SharedMemory/PosixSharedMemory.cpp b/examples/SharedMemory/PosixSharedMemory.cpp index 16c439d48..9c16b3fe7 100644 --- a/examples/SharedMemory/PosixSharedMemory.cpp +++ b/examples/SharedMemory/PosixSharedMemory.cpp @@ -66,6 +66,27 @@ struct btPointerCaster void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCreation) { #ifdef TEST_SHARED_MEMORY + + { + btSharedMemorySegment* seg = 0; + int i=0; + + for (i=0;im_segments.size();i++) + { + if (m_internalData->m_segments[i].m_key == key) + { + seg = &m_internalData->m_segments[i]; + break; + } + } + if (seg) + { + b3Error("already created shared memory segment using same key"); + return seg->m_sharedMemoryPtr; + } + + } + int flags = (allowCreation ? IPC_CREAT : 0) | 0666; int id = shmget((key_t) key, (size_t) size,flags); if (id < 0)