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.
This commit is contained in:
Erwin Coumans
2017-01-05 18:30:01 -08:00
parent c940f0ec47
commit 0cf869e56a
2 changed files with 138 additions and 138 deletions

View File

@@ -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()<endTime)
{
m_physicsServer.processClientCommands();
}
} else
{
//for (int i=0;i<10;i++)
m_physicsServer.processClientCommands();
}
#endif
{ {
if (m_multiThreadedHelper->m_childGuiHelper->getRenderInterface()) if (m_multiThreadedHelper->m_childGuiHelper->getRenderInterface())
{ {

View File

@@ -14,7 +14,8 @@
#include "PhysicsServerCommandProcessor.h" #include "PhysicsServerCommandProcessor.h"
//number of shared memory blocks == number of simultaneous connections
#define MAX_SHARED_MEMORY_BLOCKS 2
struct PhysicsServerSharedMemoryInternalData struct PhysicsServerSharedMemoryInternalData
{ {
@@ -25,7 +26,7 @@ struct PhysicsServerSharedMemoryInternalData
SharedMemoryInterface* m_sharedMemory; SharedMemoryInterface* m_sharedMemory;
bool m_ownsSharedMemory; bool m_ownsSharedMemory;
SharedMemoryBlock* m_testBlock1; SharedMemoryBlock* m_testBlocks[MAX_SHARED_MEMORY_BLOCKS];
int m_sharedMemoryKey; int m_sharedMemoryKey;
bool m_isConnected; bool m_isConnected;
bool m_verboseOutput; bool m_verboseOutput;
@@ -34,27 +35,31 @@ struct PhysicsServerSharedMemoryInternalData
PhysicsServerSharedMemoryInternalData() PhysicsServerSharedMemoryInternalData()
:m_sharedMemory(0), :m_sharedMemory(0),
m_ownsSharedMemory(false), m_ownsSharedMemory(false),
m_testBlock1(0), m_sharedMemoryKey(SHARED_MEMORY_KEY),
m_sharedMemoryKey(SHARED_MEMORY_KEY),
m_isConnected(false), m_isConnected(false),
m_verboseOutput(false), m_verboseOutput(false),
m_commandProcessor(0) m_commandProcessor(0)
{ {
for (int i=0;i<MAX_SHARED_MEMORY_BLOCKS;i++)
{
m_testBlocks[i]=0;
}
} }
SharedMemoryStatus& createServerStatus(int statusType, int sequenceNumber, int timeStamp) SharedMemoryStatus& createServerStatus(int statusType, int sequenceNumber, int timeStamp, int blockIndex)
{ {
SharedMemoryStatus& serverCmd =m_testBlock1->m_serverCommands[0]; SharedMemoryStatus& serverCmd =m_testBlocks[blockIndex]->m_serverCommands[0];
serverCmd .m_type = statusType; serverCmd .m_type = statusType;
serverCmd.m_sequenceNumber = sequenceNumber; serverCmd.m_sequenceNumber = sequenceNumber;
serverCmd.m_timeStamp = timeStamp; serverCmd.m_timeStamp = timeStamp;
return serverCmd; 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; int counter = 0;
do for (int block=0;block<MAX_SHARED_MEMORY_BLOCKS;block++)
{ {
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);
m_data->m_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) if (!m_data->m_isConnected)
{ {
b3Error("Server cannot connect to shared memory.\n"); b3Error("Server cannot connect to shared memory.\n");
@@ -167,71 +174,77 @@ void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMe
{ {
b3Printf("releaseSharedMemory1\n"); b3Printf("releaseSharedMemory1\n");
} }
if (m_data->m_testBlock1) for (int block = 0;block<MAX_SHARED_MEMORY_BLOCKS;block++)
{ {
if (m_data->m_verboseOutput) if (m_data->m_testBlocks[block])
{ {
b3Printf("m_testBlock1\n"); if (m_data->m_verboseOutput)
} {
if (deInitializeSharedMemory) b3Printf("m_testBlock1\n");
{ }
m_data->m_testBlock1->m_magicId = 0; if (deInitializeSharedMemory)
if (m_data->m_verboseOutput) {
{ m_data->m_testBlocks[block]->m_magicId = 0;
b3Printf("De-initialized shared memory, magic id = %d\n",m_data->m_testBlock1->m_magicId); 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, SHARED_MEMORY_SIZE); }
} btAssert(m_data->m_sharedMemory);
if (m_data->m_sharedMemory) m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE);
{ }
if (m_data->m_verboseOutput) if (m_data->m_sharedMemory)
{ {
b3Printf("m_sharedMemory\n"); if (m_data->m_verboseOutput)
} {
if (m_data->m_ownsSharedMemory) b3Printf("m_sharedMemory\n");
{ }
delete m_data->m_sharedMemory; if (m_data->m_ownsSharedMemory)
} {
m_data->m_sharedMemory = 0; delete m_data->m_sharedMemory;
m_data->m_testBlock1 = 0; }
} m_data->m_sharedMemory = 0;
m_data->m_testBlocks[block] = 0;
}
}
} }
void PhysicsServerSharedMemory::releaseSharedMemory() void PhysicsServerSharedMemory::releaseSharedMemory()
{ {
if (m_data->m_verboseOutput) for (int block = 0;block<MAX_SHARED_MEMORY_BLOCKS;block++)
{
b3Printf("releaseSharedMemory1\n");
}
if (m_data->m_testBlock1)
{ {
if (m_data->m_verboseOutput) if (m_data->m_verboseOutput)
{ {
b3Printf("m_testBlock1\n"); b3Printf("releaseSharedMemory1\n");
} }
m_data->m_testBlock1->m_magicId = 0; if (m_data->m_testBlocks[block])
if (m_data->m_verboseOutput) {
{ if (m_data->m_verboseOutput)
b3Printf("magic id = %d\n",m_data->m_testBlock1->m_magicId); {
} b3Printf("m_testBlock1\n");
btAssert(m_data->m_sharedMemory); }
m_data->m_sharedMemory->releaseSharedMemory( m_data->m_sharedMemoryKey m_data->m_testBlocks[block]->m_magicId = 0;
, SHARED_MEMORY_SIZE); if (m_data->m_verboseOutput)
} {
if (m_data->m_sharedMemory) b3Printf("magic id = %d\n",m_data->m_testBlocks[block]->m_magicId);
{ }
if (m_data->m_verboseOutput) btAssert(m_data->m_sharedMemory);
{ m_data->m_sharedMemory->releaseSharedMemory( m_data->m_sharedMemoryKey+block
b3Printf("m_sharedMemory\n"); , SHARED_MEMORY_SIZE);
} }
if (m_data->m_ownsSharedMemory) if (m_data->m_sharedMemory)
{ {
delete m_data->m_sharedMemory; if (m_data->m_verboseOutput)
} {
m_data->m_sharedMemory = 0; b3Printf("m_sharedMemory\n");
m_data->m_testBlock1 = 0; }
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() void PhysicsServerSharedMemory::processClientCommands()
{ {
if (m_data->m_isConnected && m_data->m_testBlock1) for (int block = 0;block<MAX_SHARED_MEMORY_BLOCKS;block++)
{ {
m_data->m_commandProcessor->replayLogCommand(&m_data->m_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); if (m_data->m_isConnected && m_data->m_testBlocks[block])
///we ignore overflow of integer for now
if (m_data->m_testBlock1->m_numClientCommands> m_data->m_testBlock1->m_numProcessedClientCommands)
{ {
m_data->m_commandProcessor->replayLogCommand(&m_data->m_testBlocks[block]->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE);
//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);
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++; //until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands
//todo, timeStamp btAssert(m_data->m_testBlocks[block]->m_numClientCommands==m_data->m_testBlocks[block]->m_numProcessedClientCommands+1);
int timeStamp = 0;
SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp); const SharedMemoryCommand& clientCmd =m_data->m_testBlocks[block]->m_clientCommands[0];
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->m_testBlocks[block]->m_numProcessedClientCommands++;
{ //todo, timeStamp
m_data->submitServerStatus(serverStatusOut); 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);
}
}
} }
} }
} }