This commit is contained in:
Erwin Coumans
2017-01-06 09:56:04 -08:00
4 changed files with 215 additions and 177 deletions

View File

@@ -1444,22 +1444,6 @@ 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,36 +26,39 @@ 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_areConnected[MAX_SHARED_MEMORY_BLOCKS];
bool m_verboseOutput; bool m_verboseOutput;
PhysicsServerCommandProcessor* m_commandProcessor; PhysicsServerCommandProcessor* m_commandProcessor;
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_verboseOutput(false),
m_isConnected(false),
m_verboseOutput(false),
m_commandProcessor(0) m_commandProcessor(0)
{ {
for (int i=0;i<MAX_SHARED_MEMORY_BLOCKS;i++)
{
m_testBlocks[i]=0;
m_areConnected[i]=false;
}
} }
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++;
} }
}; };
@@ -84,9 +88,25 @@ PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* shar
PhysicsServerSharedMemory::~PhysicsServerSharedMemory() PhysicsServerSharedMemory::~PhysicsServerSharedMemory()
{ {
m_data->m_commandProcessor->deleteDynamicsWorld(); m_data->m_commandProcessor->deleteDynamicsWorld();
delete m_data->m_commandProcessor; 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() void PhysicsServerSharedMemory::resetDynamicsWorld()
@@ -107,55 +127,61 @@ bool PhysicsServerSharedMemory::connectSharedMemory( struct GUIHelperInterface*
bool allowCreation = true; bool allowCreation = true;
bool allConnected = false;
if (m_data->m_isConnected)
{
b3Warning("connectSharedMemory, while already connected");
return m_data->m_isConnected;
}
int counter = 0; int counter = 0;
do for (int block=0;block<MAX_SHARED_MEMORY_BLOCKS;block++)
{ {
if (m_data->m_areConnected[block])
{
allConnected = true;
b3Warning("connectSharedMemory, while already connected");
continue;
}
do
{
m_data->m_testBlock1 = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE,allowCreation); m_data->m_testBlocks[block] = (SharedMemoryBlock*)m_data->m_sharedMemory->allocateSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE,allowCreation);
if (m_data->m_testBlock1) if (m_data->m_testBlocks[block])
{ {
int magicId =m_data->m_testBlock1->m_magicId; int magicId =m_data->m_testBlocks[block]->m_magicId;
if (m_data->m_verboseOutput) if (m_data->m_verboseOutput)
{ {
b3Printf("magicId = %d\n", magicId); b3Printf("magicId = %d\n", magicId);
} }
if (m_data->m_testBlock1->m_magicId !=SHARED_MEMORY_MAGIC_NUMBER) if (m_data->m_testBlocks[block]->m_magicId !=SHARED_MEMORY_MAGIC_NUMBER)
{ {
InitSharedMemoryBlock(m_data->m_testBlock1); InitSharedMemoryBlock(m_data->m_testBlocks[block]);
if (m_data->m_verboseOutput) if (m_data->m_verboseOutput)
{ {
b3Printf("Created and initialized shared memory block\n"); b3Printf("Created and initialized shared memory block\n");
} }
m_data->m_isConnected = true; m_data->m_areConnected[block] = true;
} else } else
{ {
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE); m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey+block, SHARED_MEMORY_SIZE);
m_data->m_testBlock1 = 0; m_data->m_testBlocks[block] = 0;
m_data->m_isConnected = false; m_data->m_areConnected[block] = false;
} }
} else } else
{ {
b3Error("Cannot connect to shared memory"); 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) return allConnected;
{
b3Error("Server cannot connect to shared memory.\n");
}
return m_data->m_isConnected;
} }
@@ -167,72 +193,34 @@ 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) m_data->m_testBlocks[block] = 0;
{ m_data->m_areConnected[block] = false;
b3Printf("m_sharedMemory\n");
} }
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_sharedMemory = 0;
m_data->m_testBlock1 = 0;
}
} }
void PhysicsServerSharedMemory::releaseSharedMemory() void PhysicsServerSharedMemory::releaseSharedMemory()
{ {
if (m_data->m_verboseOutput) disconnectSharedMemory(true);
{
b3Printf("releaseSharedMemory1\n");
}
if (m_data->m_testBlock1)
{
if (m_data->m_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;
}
} }
@@ -250,30 +238,34 @@ 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);
///we ignore overflow of integer for now if (m_data->m_areConnected[block] && m_data->m_testBlocks[block])
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);
///we ignore overflow of integer for now
if (m_data->m_testBlocks[block]->m_numClientCommands> m_data->m_testBlocks[block]->m_numProcessedClientCommands)
{
//until we implement a proper ring buffer, we assume always maximum of 1 outstanding commands //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); btAssert(m_data->m_testBlocks[block]->m_numClientCommands==m_data->m_testBlocks[block]->m_numProcessedClientCommands+1);
const SharedMemoryCommand& clientCmd =m_data->m_testBlock1->m_clientCommands[0]; const SharedMemoryCommand& clientCmd =m_data->m_testBlocks[block]->m_clientCommands[0];
m_data->m_testBlock1->m_numProcessedClientCommands++; m_data->m_testBlocks[block]->m_numProcessedClientCommands++;
//todo, timeStamp //todo, timeStamp
int timeStamp = 0; int timeStamp = 0;
SharedMemoryStatus& serverStatusOut = m_data->createServerStatus(CMD_BULLET_DATA_STREAM_RECEIVED_COMPLETED,clientCmd.m_sequenceNumber,timeStamp); 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_testBlock1->m_bulletStreamDataServerToClientRefactor[0],SHARED_MEMORY_MAX_STREAM_CHUNK_SIZE); 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) if (hasStatus)
{ {
m_data->submitServerStatus(serverStatusOut); m_data->submitServerStatus(serverStatusOut,block);
} }
}
} }
} }
} }

View File

@@ -1,6 +1,7 @@
#include "PosixSharedMemory.h" #include "PosixSharedMemory.h"
#include "Bullet3Common/b3Logging.h" #include "Bullet3Common/b3Logging.h"
#include "LinearMath/btScalar.h" //for btAssert #include "LinearMath/btScalar.h" //for btAssert
#include "LinearMath/btAlignedObjectArray.h"
//Windows implementation is in Win32SharedMemory.cpp //Windows implementation is in Win32SharedMemory.cpp
#ifndef _WIN32 #ifndef _WIN32
@@ -16,16 +17,28 @@
#endif #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 struct PosixSharedMemoryInteralData
{ {
bool m_createdSharedMemory; btAlignedObjectArray<btSharedMemorySegment> m_segments;
int m_sharedMemoryId;
void* m_sharedMemoryPtr;
PosixSharedMemoryInteralData() PosixSharedMemoryInteralData()
:m_createdSharedMemory(false),
m_sharedMemoryId(-1),
m_sharedMemoryPtr(0)
{ {
} }
}; };
@@ -53,6 +66,27 @@ struct btPointerCaster
void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCreation) void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCreation)
{ {
#ifdef TEST_SHARED_MEMORY #ifdef TEST_SHARED_MEMORY
{
btSharedMemorySegment* seg = 0;
int i=0;
for (i=0;i<m_internalData->m_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 flags = (allowCreation ? IPC_CREAT : 0) | 0666;
int id = shmget((key_t) key, (size_t) size,flags); int id = shmget((key_t) key, (size_t) size,flags);
if (id < 0) if (id < 0)
@@ -67,9 +101,12 @@ void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCr
b3Error("shmat returned -1"); b3Error("shmat returned -1");
} else } else
{ {
m_internalData->m_createdSharedMemory = allowCreation; btSharedMemorySegment seg;
m_internalData->m_sharedMemoryId = id; seg.m_key = key;
m_internalData->m_sharedMemoryPtr = result.ptr; seg.m_createdSharedMemory = allowCreation;
seg.m_sharedMemoryId = id;
seg.m_sharedMemoryPtr = result.ptr;
m_internalData->m_segments.push_back(seg);
return result.ptr; return result.ptr;
} }
} }
@@ -82,14 +119,33 @@ void* PosixSharedMemory::allocateSharedMemory(int key, int size, bool allowCr
void PosixSharedMemory::releaseSharedMemory(int key, int size) void PosixSharedMemory::releaseSharedMemory(int key, int size)
{ {
#ifdef TEST_SHARED_MEMORY #ifdef TEST_SHARED_MEMORY
if (m_internalData->m_sharedMemoryId < 0)
btSharedMemorySegment* seg = 0;
int i=0;
for (i=0;i<m_internalData->m_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"); b3Error("PosixSharedMemory::releaseSharedMemory: shared memory id is not set");
} else } 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) if (result == -1)
{ {
b3Error("PosixSharedMemory::releaseSharedMemory: shmat returned -1"); b3Error("PosixSharedMemory::releaseSharedMemory: shmat returned -1");
@@ -97,15 +153,18 @@ void PosixSharedMemory::releaseSharedMemory(int key, int size)
{ {
b3Printf("PosixSharedMemory::releaseSharedMemory removed shared memory"); b3Printf("PosixSharedMemory::releaseSharedMemory removed shared memory");
} }
m_internalData->m_createdSharedMemory = false; seg->m_createdSharedMemory = false;
m_internalData->m_sharedMemoryId = -1; seg->m_sharedMemoryId = -1;
} }
if (m_internalData->m_sharedMemoryPtr) if (seg->m_sharedMemoryPtr)
{ {
shmdt(m_internalData->m_sharedMemoryPtr); shmdt(seg->m_sharedMemoryPtr);
m_internalData->m_sharedMemoryPtr = 0; seg->m_sharedMemoryPtr = 0;
b3Printf("PosixSharedMemory::releaseSharedMemory detached shared memory\n"); b3Printf("PosixSharedMemory::releaseSharedMemory detached shared memory\n");
} }
} }
m_internalData->m_segments.removeAtIndex(i);
#endif #endif
} }

View File

@@ -476,15 +476,18 @@ protected:
return index; return index;
} }
void removeAtIndex(int index)
{
if (index<size())
{
swap( index,size()-1);
pop_back();
}
}
void remove(const T& key) void remove(const T& key)
{ {
int findIndex = findLinearSearch(key); int findIndex = findLinearSearch(key);
if (findIndex<size()) removeAtIndex(findIndex);
{
swap( findIndex,size()-1);
pop_back();
}
} }
//PCK: whole function //PCK: whole function