Allow InProcessExampleBrowser to use a malloc allocated memory block, instead of system shared memory.

Make shared memory client/server a bit more robust, in case the server is terminated early.
This commit is contained in:
erwincoumans 2016-03-10 14:36:46 -08:00
parent 40a9b8cea0
commit efbb1edecc
19 changed files with 186 additions and 23 deletions

View File

@ -10,12 +10,14 @@ struct CommonExampleOptions
//Those are optional, some examples will use them others don't. Each example should work with them being 0.
int m_option;
const char* m_fileName;
class SharedMemoryInterface* m_sharedMem;
CommonExampleOptions(struct GUIHelperInterface* helper, int option=0)
:m_guiHelper(helper),
m_option(option),
m_fileName(0)
m_fileName(0),
m_sharedMem(0)
{
}

View File

@ -24,6 +24,7 @@ SET(App_ExampleBrowser_SRCS
../SharedMemory/PhysicsClientExample.cpp
../SharedMemory/PosixSharedMemory.cpp
../SharedMemory/Win32SharedMemory.cpp
../SharedMemory/InProcessMemory.cpp
../SharedMemory/PhysicsServerSharedMemory.cpp
../SharedMemory/PhysicsDirect.cpp
../SharedMemory/PhysicsDirect.h

View File

@ -14,6 +14,7 @@
#include "ExampleEntries.h"
#include "Bullet3Common/b3Logging.h"
#include "../SharedMemory/InProcessMemory.h"
void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory);
void* ExampleBrowserMemoryFunc();
@ -65,6 +66,7 @@ struct ExampleBrowserArgs
struct ExampleBrowserThreadLocalStorage
{
SharedMemoryInterface* m_sharedMem;
int threadId;
};
@ -92,7 +94,9 @@ void ExampleBrowserThreadFunc(void* userPtr,void* lsMemory)
ExampleEntries examples;
examples.initExampleEntries();
ExampleBrowserInterface* exampleBrowser = new DefaultBrowser(&examples);
DefaultBrowser* exampleBrowser = new DefaultBrowser(&examples);
exampleBrowser->setSharedMemoryInterface(localStorage->m_sharedMem);
bool init = exampleBrowser->init(args->m_argc,args->m_argv);
clock.reset();
if (init)
@ -139,6 +143,7 @@ struct btInProcessExampleBrowserInternalData
{
ExampleBrowserArgs m_args;
b3ThreadSupportInterface* m_threadSupport;
SharedMemoryInterface* m_sharedMem;
};
@ -146,6 +151,7 @@ btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc,
{
btInProcessExampleBrowserInternalData* data = new btInProcessExampleBrowserInternalData;
data->m_sharedMem = new InProcessMemory;
int numThreads = 1;
int i;
@ -163,6 +169,7 @@ btInProcessExampleBrowserInternalData* btCreateInProcessExampleBrowser(int argc,
ExampleBrowserThreadLocalStorage* storage = (ExampleBrowserThreadLocalStorage*) data->m_threadSupport->getThreadLocalMemory(i);
b3Assert(storage);
storage->threadId = i;
storage->m_sharedMem = data->m_sharedMem;
}
@ -189,6 +196,11 @@ bool btIsExampleBrowserTerminated(btInProcessExampleBrowserInternalData* data)
return (data->m_args.m_cs->getSharedParam(0)==eExampleBrowserHasTerminated);
}
SharedMemoryInterface* btGetSharedMemoryInterface(btInProcessExampleBrowserInternalData* data)
{
return data->m_sharedMem;
}
void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data)
{
int numActiveThreads = 1;
@ -213,6 +225,7 @@ void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data)
printf("stopping threads\n");
delete data->m_threadSupport;
delete data->m_sharedMem;
delete data;
}

View File

@ -9,5 +9,7 @@ bool btIsExampleBrowserTerminated(btInProcessExampleBrowserInternalData* data);
void btShutDownExampleBrowser(btInProcessExampleBrowserInternalData* data);
class SharedMemoryInterface* btGetSharedMemoryInterface(btInProcessExampleBrowserInternalData* data);
#endif //IN_PROCESS_EXAMPLE_BROWSER_H

View File

@ -49,6 +49,7 @@ static CommonParameterInterface* s_parameterInterface=0;
static CommonRenderInterface* s_instancingRenderer=0;
static OpenGLGuiHelper* s_guiHelper=0;
static MyProfileWindow* s_profWindow =0;
static SharedMemoryInterface* sSharedMem = 0;
#define DEMO_SELECTION_COMBOBOX 13
const char* startFileName = "0_Bullet3Demo.txt";
@ -326,6 +327,7 @@ void selectDemo(int demoIndex)
int option = gAllExamples->getExampleOption(demoIndex);
s_guiHelper= new OpenGLGuiHelper(s_app, sUseOpenGL2);
CommonExampleOptions options(s_guiHelper, option);
options.m_sharedMem = sSharedMem;
sCurrentDemo = (*func)(options);
if (sCurrentDemo)
{
@ -1078,3 +1080,8 @@ void OpenGLExampleBrowser::update(float deltaTime)
gui->forceUpdateScrollBars();
}
void OpenGLExampleBrowser::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
{
sSharedMem = sharedMem;
}

View File

@ -17,6 +17,8 @@ public:
virtual void update(float deltaTime);
virtual bool requestedExit();
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
};

View File

@ -58,6 +58,7 @@
"../SharedMemory/PhysicsClient.cpp",
"../SharedMemory/PosixSharedMemory.cpp",
"../SharedMemory/Win32SharedMemory.cpp",
"../SharedMemory/InProcessMemory.cpp",
"../SharedMemory/PhysicsDirect.cpp",
"../SharedMemory/PhysicsDirect.h",
"../SharedMemory/PhysicsDirectC_API.cpp",

View File

@ -0,0 +1,49 @@
#include "InProcessMemory.h"
#include "LinearMath/btHashMap.h"
struct InProcessMemoryInternalData
{
btHashMap<btHashInt, void*> m_memoryPointers;
};
InProcessMemory::InProcessMemory()
{
m_data = new InProcessMemoryInternalData;
}
InProcessMemory::~InProcessMemory()
{
for (int i=0;i<m_data->m_memoryPointers.size();i++)
{
void** ptrptr = m_data->m_memoryPointers.getAtIndex(i);
if (ptrptr)
{
void* ptr = *ptrptr;
free(ptr);
}
}
delete m_data;
}
void* InProcessMemory::allocateSharedMemory(int key, int size, bool allowCreation)
{
void** ptrptr = m_data->m_memoryPointers[key];
if (ptrptr)
{
return *ptrptr;
}
void* ptr = malloc(size);
m_data->m_memoryPointers.insert(key,ptr);
return ptr;
}
void InProcessMemory::releaseSharedMemory(int /*key*/, int /*size*/)
{
//we don't release the memory here, but in the destructor instead,
//so multiple users could 'share' the memory given some key
}

View File

@ -0,0 +1,19 @@
#ifndef IN_PROCESS_MEMORY_H
#define IN_PROCESS_MEMORY_H
#include "SharedMemoryInterface.h"
class InProcessMemory : public SharedMemoryInterface
{
struct InProcessMemoryInternalData* m_data;
public:
InProcessMemory();
virtual ~InProcessMemory();
virtual void* allocateSharedMemory(int key, int size, bool allowCreation);
virtual void releaseSharedMemory(int key, int size);
};
#endif

View File

@ -72,7 +72,7 @@ b3SharedMemoryCommandHandle b3InitPhysicsParamCommand(b3PhysicsClientHandle
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
b3Assert(cl);
b3Assert(cl->canSubmitCommand());
b3Assert(cl->canSubmitCommand());
struct SharedMemoryCommand* command = cl->getAvailableSharedMemoryCommand();
b3Assert(command);
command->m_type = CMD_SEND_PHYSICS_SIMULATION_PARAMETERS;
@ -445,9 +445,12 @@ void b3DisconnectSharedMemory(b3PhysicsClientHandle physClient)
b3SharedMemoryStatusHandle b3ProcessServerStatus(b3PhysicsClientHandle physClient)
{
PhysicsClient* cl = (PhysicsClient* ) physClient;
const SharedMemoryStatus* stat = cl->processServerStatus();
return (b3SharedMemoryStatusHandle) stat;
if (cl && cl->isConnected())
{
const SharedMemoryStatus* stat = cl->processServerStatus();
return (b3SharedMemoryStatusHandle) stat;
}
return 0;
}
@ -461,7 +464,7 @@ int b3GetStatusType(b3SharedMemoryStatusHandle statusHandle)
{
return status->m_type;
}
return 0;
return CMD_INVALID_STATUS;
}
int b3GetStatusBodyIndex(b3SharedMemoryStatusHandle statusHandle)

View File

@ -23,6 +23,7 @@ struct BodyJointInfoCache
struct PhysicsClientSharedMemoryInternalData {
SharedMemoryInterface* m_sharedMemory;
bool m_ownsSharedMemory;
SharedMemoryBlock* m_testBlock1;
btHashMap<btHashInt,BodyJointInfoCache*> m_bodyJointMap;
@ -43,6 +44,7 @@ struct PhysicsClientSharedMemoryInternalData {
PhysicsClientSharedMemoryInternalData()
: m_sharedMemory(0),
m_ownsSharedMemory(false),
m_testBlock1(0),
m_counter(0),
m_serverLoadUrdfOK(false),
@ -95,23 +97,40 @@ PhysicsClientSharedMemory::PhysicsClientSharedMemory()
#else
m_data->m_sharedMemory = new PosixSharedMemory();
#endif
m_data->m_ownsSharedMemory = true;
}
PhysicsClientSharedMemory::~PhysicsClientSharedMemory() {
if (m_data->m_isConnected) {
disconnectSharedMemory();
}
delete m_data->m_sharedMemory;
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
delete m_data;
}
void PhysicsClientSharedMemory::setSharedMemoryKey(int key) { m_data->m_sharedMemoryKey = key; }
void PhysicsClientSharedMemory::setSharedMemoryInterface(class SharedMemoryInterface* sharedMem)
{
if (m_data->m_sharedMemory && m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_ownsSharedMemory = false;
m_data->m_sharedMemory = sharedMem;
}
void PhysicsClientSharedMemory::disconnectSharedMemory() {
if (m_data->m_isConnected) {
if (m_data->m_isConnected && m_data->m_sharedMemory) {
m_data->m_sharedMemory->releaseSharedMemory(m_data->m_sharedMemoryKey, SHARED_MEMORY_SIZE);
m_data->m_isConnected = false;
}
m_data->m_isConnected = false;
}
bool PhysicsClientSharedMemory::isConnected() const { return m_data->m_isConnected; }
@ -146,13 +165,20 @@ const SharedMemoryStatus* PhysicsClientSharedMemory::processServerStatus() {
SharedMemoryStatus* stat = 0;
if (!m_data->m_testBlock1) {
return 0;
m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED;
return &m_data->m_lastServerStatus;
}
if (!m_data->m_waitingForServer) {
return 0;
}
if (m_data->m_testBlock1->m_magicId != SHARED_MEMORY_MAGIC_NUMBER)
{
m_data->m_lastServerStatus.m_type = CMD_SHARED_MEMORY_NOT_INITIALIZED;
return &m_data->m_lastServerStatus;
}
if (m_data->m_testBlock1->m_numServerCommands >
m_data->m_testBlock1->m_numProcessedServerCommands) {
btAssert(m_data->m_testBlock1->m_numServerCommands ==
@ -446,7 +472,6 @@ bool PhysicsClientSharedMemory::submitClientCommand(const SharedMemoryCommand& c
/// at the moment we allow a maximum of 1 outstanding command, so we check for this
// once the server processed the command and returns a status, we clear the flag
// "m_data->m_waitingForServer" and allow submitting the next command
btAssert(!m_data->m_waitingForServer);
if (!m_data->m_waitingForServer) {
if (&m_data->m_testBlock1->m_clientCommands[0] != &command) {

View File

@ -10,6 +10,8 @@ class PhysicsClientSharedMemory : public PhysicsClient {
struct PhysicsClientSharedMemoryInternalData* m_data;
protected:
virtual void setSharedMemoryInterface(class SharedMemoryInterface* sharedMem);
public:
PhysicsClientSharedMemory();
virtual ~PhysicsClientSharedMemory();

View File

@ -22,7 +22,7 @@ class PhysicsServerExample : public SharedMemoryCommon
public:
PhysicsServerExample(GUIHelperInterface* helper);
PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem=0);
virtual ~PhysicsServerExample();
@ -133,8 +133,9 @@ public:
};
PhysicsServerExample::PhysicsServerExample(GUIHelperInterface* helper)
PhysicsServerExample::PhysicsServerExample(GUIHelperInterface* helper, SharedMemoryInterface* sharedMem)
:SharedMemoryCommon(helper),
m_physicsServer(sharedMem),
m_wantsShutdown(false),
m_isConnected(false),
m_replay(false)
@ -287,7 +288,7 @@ extern int gSharedMemoryKey;
class CommonExampleInterface* PhysicsServerCreateFunc(struct CommonExampleOptions& options)
{
PhysicsServerExample* example = new PhysicsServerExample(options.m_guiHelper);
PhysicsServerExample* example = new PhysicsServerExample(options.m_guiHelper, options.m_sharedMem);
if (gSharedMemoryKey>=0)
{
example->setSharedMemoryKey(gSharedMemoryKey);

View File

@ -23,6 +23,8 @@ struct PhysicsServerSharedMemoryInternalData
SharedMemoryInterface* m_sharedMemory;
bool m_ownsSharedMemory;
SharedMemoryBlock* m_testBlock1;
int m_sharedMemoryKey;
bool m_isConnected;
@ -31,6 +33,7 @@ struct PhysicsServerSharedMemoryInternalData
PhysicsServerSharedMemoryInternalData()
:m_sharedMemory(0),
m_ownsSharedMemory(false),
m_testBlock1(0),
m_sharedMemoryKey(SHARED_MEMORY_KEY),
m_isConnected(false),
@ -57,16 +60,23 @@ struct PhysicsServerSharedMemoryInternalData
};
PhysicsServerSharedMemory::PhysicsServerSharedMemory()
PhysicsServerSharedMemory::PhysicsServerSharedMemory(SharedMemoryInterface* sharedMem)
{
m_data = new PhysicsServerSharedMemoryInternalData();
if (sharedMem)
{
m_data->m_sharedMemory = sharedMem;
m_data->m_ownsSharedMemory = false;
} else
{
#ifdef _WIN32
m_data->m_sharedMemory = new Win32SharedMemoryServer();
#else
m_data->m_sharedMemory = new PosixSharedMemory();
#endif
m_data->m_ownsSharedMemory = true;
}
m_data->m_commandProcessor = new PhysicsServerCommandProcessor;
m_data->m_commandProcessor ->createEmptyDynamicsWorld();
@ -176,7 +186,10 @@ void PhysicsServerSharedMemory::disconnectSharedMemory(bool deInitializeSharedMe
{
b3Printf("m_sharedMemory\n");
}
delete m_data->m_sharedMemory;
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_sharedMemory = 0;
m_data->m_testBlock1 = 0;
}
@ -209,7 +222,10 @@ void PhysicsServerSharedMemory::releaseSharedMemory()
{
b3Printf("m_sharedMemory\n");
}
delete m_data->m_sharedMemory;
if (m_data->m_ownsSharedMemory)
{
delete m_data->m_sharedMemory;
}
m_data->m_sharedMemory = 0;
m_data->m_testBlock1 = 0;
}

View File

@ -14,7 +14,7 @@ protected:
public:
PhysicsServerSharedMemory();
PhysicsServerSharedMemory(class SharedMemoryInterface* sharedMem=0);
virtual ~PhysicsServerSharedMemory();
virtual void setSharedMemoryKey(int key);

View File

@ -21,10 +21,14 @@ public:
newargv[argc] = t0;
newargv[argc+1] = t1;
m_data = btCreateInProcessExampleBrowser(newargc,newargv);
SharedMemoryInterface* shMem = btGetSharedMemoryInterface(m_data);
setSharedMemoryInterface(shMem);
}
virtual ~InProcessPhysicsClientSharedMemory()
{
setSharedMemoryInterface(0);
btShutDownExampleBrowser(m_data);
}

View File

@ -30,7 +30,6 @@ enum EnumSharedMemoryServerStatus
{
CMD_SHARED_MEMORY_NOT_INITIALIZED=0,
CMD_WAITING_FOR_CLIENT_COMMAND,
//CMD_CLIENT_COMMAND_COMPLETED is a generic 'completed' status that doesn't need special handling on the client
CMD_CLIENT_COMMAND_COMPLETED,
//the server will skip unknown command and report a status 'CMD_UNKNOWN_COMMAND_FLUSHED'
@ -50,6 +49,7 @@ enum EnumSharedMemoryServerStatus
CMD_DESIRED_STATE_RECEIVED_COMPLETED,
CMD_STEP_FORWARD_SIMULATION_COMPLETED,
CMD_RESET_SIMULATION_COMPLETED,
CMD_INVALID_STATUS,
CMD_MAX_SERVER_COMMANDS
};

View File

@ -29,6 +29,7 @@ files {
"PhysicsServer.cpp",
"PosixSharedMemory.cpp",
"Win32SharedMemory.cpp",
"InProcessMemory.cpp",
"PhysicsDirect.cpp",
"PhysicsDirect.h",
"PhysicsDirectC_API.cpp",

View File

@ -66,6 +66,7 @@ int main(int argc, char* argv[])
{
b3SharedMemoryStatusHandle statusHandle;
int statusType;
b3SharedMemoryCommandHandle command = b3LoadUrdfCommandInit(sm, urdfFileName);
//setting the initial position, orientation and other arguments are optional
@ -74,6 +75,11 @@ int main(int argc, char* argv[])
startPosZ = 1;
ret = b3LoadUrdfCommandSetStartPosition(command, startPosX,startPosY,startPosZ);
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, command);
statusType = b3GetStatusType(statusHandle);
if (statusType != CMD_URDF_LOADING_COMPLETED)
{
printf("Loading URDF failed, status type = %d\n",statusType);
}
bodyIndex = b3GetStatusBodyIndex(statusHandle);
}
@ -169,7 +175,16 @@ int main(int argc, char* argv[])
///perform some simulation steps for testing
for ( i=0;i<100;i++)
{
b3SubmitClientCommandAndWaitStatus(sm, b3InitStepSimulationCommand(sm));
b3SharedMemoryStatusHandle statusHandle;
int statusType;
statusHandle = b3SubmitClientCommandAndWaitStatus(sm, b3InitStepSimulationCommand(sm));
statusType = b3GetStatusType(statusHandle);
if (statusType != CMD_STEP_FORWARD_SIMULATION_COMPLETED)
{
printf("Step Simulation failed, Unexpected status type = %d\n",statusType);
break;
}
}
{