Remove some gratuitous differences in the SHM implementations.

develop
Tom Prince 2011-02-23 02:26:55 -05:00
parent 9b854be327
commit 9ba80d517f
2 changed files with 66 additions and 105 deletions

@ -39,9 +39,6 @@ distribution.
using namespace DFHack; using namespace DFHack;
// a full memory barrier! better be safe than sorry.
#define gcc_barrier asm volatile("" ::: "memory"); __sync_synchronize();
class SHMProcess::Private class SHMProcess::Private
{ {
public: public:
@ -81,14 +78,14 @@ class SHMProcess::Private
bool validate(std::vector< VersionInfo* >& known_versions); bool validate(std::vector< VersionInfo* >& known_versions);
bool Aux_Core_Attach(bool & versionOK, pid_t & PID); bool Aux_Core_Attach(bool & versionOK, pid_t& PID);
//bool waitWhile (uint32_t state);
bool SetAndWait (uint32_t state); bool SetAndWait (uint32_t state);
bool GetLocks(); bool GetLocks();
bool AreLocksOk(); bool AreLocksOk();
void FreeLocks(); void FreeLocks();
}; };
// some helpful macros to keep the code bloat in check
#define SHMCMD ( (uint32_t *) shm_addr)[attachmentIdx] #define SHMCMD ( (uint32_t *) shm_addr)[attachmentIdx]
#define D_SHMCMD ( (uint32_t *) (d->shm_addr))[d->attachmentIdx] #define D_SHMCMD ( (uint32_t *) (d->shm_addr))[d->attachmentIdx]
@ -103,12 +100,17 @@ bool SHMProcess::Private::SetAndWait (uint32_t state)
uint32_t cnt = 0; uint32_t cnt = 0;
if(!attached) return false; if(!attached) return false;
SHMCMD = state; SHMCMD = state;
while (SHMCMD == state) while (SHMCMD == state)
{ {
// check if the other process is still there // yield the CPU, only on single-core CPUs
if(useYield)
{
SCHED_YIELD
}
if(cnt == 10000) if(cnt == 10000)
{ {
if(!AreLocksOk()) if(!AreLocksOk())// DF not there anymore?
{ {
//detach the shared memory //detach the shared memory
shmdt(shm_addr); shmdt(shm_addr);
@ -122,10 +124,6 @@ bool SHMProcess::Private::SetAndWait (uint32_t state)
cnt = 0; cnt = 0;
} }
} }
if(useYield)
{
SCHED_YIELD
}
cnt++; cnt++;
} }
// server returned a generic error // server returned a generic error
@ -155,21 +153,6 @@ uint32_t OS_getAffinity()
return affinity; return affinity;
} }
// test if we have client and server locks and the server is present
bool SHMProcess::Private::AreLocksOk()
{
// both locks are inited (we hold our lock)
if(client_lock != -1 && server_lock != -1)
{
if(lockf(server_lock,F_TEST,0) == -1) // and server holds its lock
{
return true; // OK, locks are good
}
}
// locks are bad
return false;
}
void SHMProcess::Private::FreeLocks() void SHMProcess::Private::FreeLocks()
{ {
attachmentIdx = -1; attachmentIdx = -1;
@ -258,6 +241,21 @@ bool SHMProcess::Private::GetLocks()
return false; return false;
} }
// test if we have client and server locks and the server is present
bool SHMProcess::Private::AreLocksOk()
{
// both locks are inited (we hold our lock)
if(client_lock != -1 && server_lock != -1)
{
if(lockf(server_lock,F_TEST,0) == -1) // and server holds its lock
{
return true; // OK, locks are good
}
}
// locks are bad
return false;
}
SHMProcess::SHMProcess(uint32_t PID, vector< VersionInfo* >& known_versions) SHMProcess::SHMProcess(uint32_t PID, vector< VersionInfo* >& known_versions)
: d(new Private(this)) : d(new Private(this))
{ {
@ -425,8 +423,8 @@ bool SHMProcess::suspend()
if(D_SHMCMD == CORE_RUN) if(D_SHMCMD == CORE_RUN)
{ {
//fprintf(stderr,"%d invokes step\n",d->attachmentIdx); //fprintf(stderr,"%d invokes step\n",d->attachmentIdx);
/*
// wait for the next window // wait for the next window
/*
if(!d->SetAndWait(CORE_STEP)) if(!d->SetAndWait(CORE_STEP))
{ {
throw Error::SHMLockingError("if(!d->SetAndWait(CORE_STEP))"); throw Error::SHMLockingError("if(!d->SetAndWait(CORE_STEP))");
@ -599,7 +597,7 @@ void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buff
{ {
D_SHMHDR->address = src_address; D_SHMHDR->address = src_address;
D_SHMHDR->length = size; D_SHMHDR->length = size;
gcc_barrier full_barrier
d->SetAndWait(CORE_READ); d->SetAndWait(CORE_READ);
memcpy (target_buffer, D_SHMDATA(void),size); memcpy (target_buffer, D_SHMDATA(void),size);
} }
@ -613,7 +611,7 @@ void SHMProcess::read (uint32_t src_address, uint32_t size, uint8_t *target_buff
// read to_read bytes from src_cursor // read to_read bytes from src_cursor
D_SHMHDR->address = src_address; D_SHMHDR->address = src_address;
D_SHMHDR->length = to_read; D_SHMHDR->length = to_read;
gcc_barrier full_barrier
d->SetAndWait(CORE_READ); d->SetAndWait(CORE_READ);
memcpy (target_buffer, D_SHMDATA(void) ,to_read); memcpy (target_buffer, D_SHMDATA(void) ,to_read);
// decrease size by bytes read // decrease size by bytes read
@ -632,7 +630,7 @@ void SHMProcess::readByte (const uint32_t offset, uint8_t &val )
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
gcc_barrier full_barrier
d->SetAndWait(CORE_READ_BYTE); d->SetAndWait(CORE_READ_BYTE);
val = D_SHMHDR->value; val = D_SHMHDR->value;
} }
@ -642,7 +640,7 @@ void SHMProcess::readWord (const uint32_t offset, uint16_t &val)
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
gcc_barrier full_barrier
d->SetAndWait(CORE_READ_WORD); d->SetAndWait(CORE_READ_WORD);
val = D_SHMHDR->value; val = D_SHMHDR->value;
} }
@ -652,7 +650,7 @@ void SHMProcess::readDWord (const uint32_t offset, uint32_t &val)
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
gcc_barrier full_barrier
d->SetAndWait(CORE_READ_DWORD); d->SetAndWait(CORE_READ_DWORD);
val = D_SHMHDR->value; val = D_SHMHDR->value;
} }
@ -662,7 +660,7 @@ void SHMProcess::readQuad (const uint32_t offset, uint64_t &val)
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
gcc_barrier full_barrier
d->SetAndWait(CORE_READ_QUAD); d->SetAndWait(CORE_READ_QUAD);
val = D_SHMHDR->Qvalue; val = D_SHMHDR->Qvalue;
} }
@ -672,7 +670,7 @@ void SHMProcess::readFloat (const uint32_t offset, float &val)
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
gcc_barrier full_barrier
d->SetAndWait(CORE_READ_DWORD); d->SetAndWait(CORE_READ_DWORD);
val = reinterpret_cast<float&> (D_SHMHDR->value); val = reinterpret_cast<float&> (D_SHMHDR->value);
} }
@ -681,13 +679,13 @@ void SHMProcess::readFloat (const uint32_t offset, float &val)
* WRITING * WRITING
*/ */
void SHMProcess::writeQuad (const uint32_t offset, const uint64_t data) void SHMProcess::writeQuad (uint32_t offset, uint64_t data)
{ {
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
D_SHMHDR->Qvalue = data; D_SHMHDR->Qvalue = data;
gcc_barrier full_barrier
d->SetAndWait(CORE_WRITE_QUAD); d->SetAndWait(CORE_WRITE_QUAD);
} }
@ -697,7 +695,7 @@ void SHMProcess::writeDWord (uint32_t offset, uint32_t data)
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
D_SHMHDR->value = data; D_SHMHDR->value = data;
gcc_barrier full_barrier
d->SetAndWait(CORE_WRITE_DWORD); d->SetAndWait(CORE_WRITE_DWORD);
} }
@ -708,7 +706,7 @@ void SHMProcess::writeWord (uint32_t offset, uint16_t data)
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
D_SHMHDR->value = data; D_SHMHDR->value = data;
gcc_barrier full_barrier
d->SetAndWait(CORE_WRITE_WORD); d->SetAndWait(CORE_WRITE_WORD);
} }
@ -718,7 +716,7 @@ void SHMProcess::writeByte (uint32_t offset, uint8_t data)
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
D_SHMHDR->value = data; D_SHMHDR->value = data;
gcc_barrier full_barrier
d->SetAndWait(CORE_WRITE_BYTE); d->SetAndWait(CORE_WRITE_BYTE);
} }
@ -732,7 +730,7 @@ void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buf
D_SHMHDR->address = dst_address; D_SHMHDR->address = dst_address;
D_SHMHDR->length = size; D_SHMHDR->length = size;
memcpy(D_SHMDATA(void),source_buffer, size); memcpy(D_SHMDATA(void),source_buffer, size);
gcc_barrier full_barrier
d->SetAndWait(CORE_WRITE); d->SetAndWait(CORE_WRITE);
} }
// a big write, we push this over the shm in iterations // a big write, we push this over the shm in iterations
@ -746,7 +744,7 @@ void SHMProcess::write (uint32_t dst_address, uint32_t size, uint8_t *source_buf
D_SHMHDR->address = dst_address; D_SHMHDR->address = dst_address;
D_SHMHDR->length = to_write; D_SHMHDR->length = to_write;
memcpy(D_SHMDATA(void),source_buffer, to_write); memcpy(D_SHMDATA(void),source_buffer, to_write);
gcc_barrier full_barrier
d->SetAndWait(CORE_WRITE); d->SetAndWait(CORE_WRITE);
// decrease size by bytes written // decrease size by bytes written
size -= to_write; size -= to_write;
@ -825,6 +823,19 @@ string SHMProcess::readClassName (uint32_t vptr)
return raw.substr(start,end-start); return raw.substr(start,end-start);
} }
string SHMProcess::getPath()
{
char cwd_name[256];
char target_name[1024];
int target_result;
sprintf(cwd_name,"/proc/%d/cwd", getPID());
// resolve /proc/PID/exe link
target_result = readlink(cwd_name, target_name, sizeof(target_name));
target_name[target_result] = '\0';
return(string(target_name));
}
// get module index by name and version. bool 0 = error // get module index by name and version. bool 0 = error
bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT)
{ {
@ -874,15 +885,3 @@ bool SHMProcess::Private::Aux_Core_Attach(bool & versionOK, pid_t & PID)
#endif #endif
return true; return true;
} }
string SHMProcess::getPath()
{
char cwd_name[256];
char target_name[1024];
int target_result;
sprintf(cwd_name,"/proc/%d/cwd", getPID());
// resolve /proc/PID/exe link
target_result = readlink(cwd_name, target_name, sizeof(target_name));
target_name[target_result] = '\0';
return(string(target_name));
}

@ -29,7 +29,6 @@ distribution.
#include "mod-core.h" #include "mod-core.h"
using namespace DFHack; using namespace DFHack;
// a full memory barrier! better be safe than sorry.
class SHMProcess::Private class SHMProcess::Private
{ {
public: public:
@ -81,11 +80,6 @@ class SHMProcess::Private
#define SHMDATA(type) ((type *)(shm_addr + SHM_HEADER)) #define SHMDATA(type) ((type *)(shm_addr + SHM_HEADER))
#define D_SHMDATA(type) ((type *)(d->shm_addr + SHM_HEADER)) #define D_SHMDATA(type) ((type *)(d->shm_addr + SHM_HEADER))
bool SHMProcess::SetAndWait (uint32_t state)
{
return d->SetAndWait(state);
}
bool SHMProcess::Private::SetAndWait (uint32_t state) bool SHMProcess::Private::SetAndWait (uint32_t state)
{ {
uint32_t cnt = 0; uint32_t cnt = 0;
@ -116,6 +110,7 @@ bool SHMProcess::Private::SetAndWait (uint32_t state)
} }
cnt++; cnt++;
} }
// server returned a generic error
if(SHMCMD == CORE_ERROR) if(SHMCMD == CORE_ERROR)
{ {
return false; return false;
@ -123,6 +118,11 @@ bool SHMProcess::Private::SetAndWait (uint32_t state)
return true; return true;
} }
bool SHMProcess::SetAndWait (uint32_t state)
{
return d->SetAndWait(state);
}
uint32_t OS_getAffinity() uint32_t OS_getAffinity()
{ {
HANDLE hProcess = GetCurrentProcess(); HANDLE hProcess = GetCurrentProcess();
@ -253,27 +253,6 @@ bool SHMProcess::Private::AreLocksOk()
return false; return false;
} }
/*
char svmutexname [256];
char clmutexname [256];
sprintf(clmutexname,"DFCLMutex-%d",PID);
// get server and client mutex
d->DFSVMutex = OpenMutex(SYNCHRONIZE,false, svmutexname);
if(d->DFSVMutex == 0)
{
return;
}
d->DFCLMutex = OpenMutex(SYNCHRONIZE,false, clmutexname);
if(d->DFCLMutex == 0)
{
return;
}
*/
SHMProcess::SHMProcess(uint32_t PID, vector <VersionInfo *> & known_versions) SHMProcess::SHMProcess(uint32_t PID, vector <VersionInfo *> & known_versions)
: d(new Private()) : d(new Private())
{ {
@ -463,7 +442,7 @@ bool SHMProcess::suspend()
{ {
//fprintf(stderr,"%d invokes step\n",d->attachmentIdx); //fprintf(stderr,"%d invokes step\n",d->attachmentIdx);
// wait for the next window // wait for the next window
/* /*
if(!d->SetAndWait(CORE_STEP)) if(!d->SetAndWait(CORE_STEP))
{ {
throw Error::SHMLockingError("if(!d->SetAndWait(CORE_STEP))"); throw Error::SHMLockingError("if(!d->SetAndWait(CORE_STEP))");
@ -577,21 +556,6 @@ bool SHMProcess::attach()
//cerr << "server is full or not really there!" << endl; //cerr << "server is full or not really there!" << endl;
return false; return false;
} }
/*
// check if DF is there
if(!d->isValidSV())
{
return false; // NOT
}
*/
/*
// try locking client mutex
uint32_t result = WaitForSingleObject(d->DFCLMutex,0);
if( result != WAIT_OBJECT_0 && result != WAIT_ABANDONED)
{
return false; // we couldn't lock it
}
*/
/* /*
* Locate the segment. * Locate the segment.
@ -634,12 +598,10 @@ bool SHMProcess::attach()
bool SHMProcess::detach() bool SHMProcess::detach()
{ {
if(!d->attached) return true; if(!d->attached) return true;
//cerr << "detach" << endl;// FIXME: throw
if(d->locked) if(d->locked)
{ {
resume(); resume();
} }
//cerr << "detach after resume" << endl;// FIXME: throw
// detach segment // detach segment
UnmapViewOfFile(d->shm_addr); UnmapViewOfFile(d->shm_addr);
// release it for some other client // release it for some other client
@ -718,24 +680,24 @@ void SHMProcess::readDWord (const uint32_t offset, uint32_t &val)
val = D_SHMHDR->value; val = D_SHMHDR->value;
} }
void SHMProcess::readFloat (const uint32_t offset, float &val) void SHMProcess::readQuad (const uint32_t offset, uint64_t &val)
{ {
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
full_barrier full_barrier
d->SetAndWait(CORE_READ_DWORD); d->SetAndWait(CORE_READ_QUAD);
val = reinterpret_cast<float&> (D_SHMHDR->value); val = D_SHMHDR->Qvalue;
} }
void SHMProcess::readQuad (const uint32_t offset, uint64_t &val) void SHMProcess::readFloat (const uint32_t offset, float &val)
{ {
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
D_SHMHDR->address = offset; D_SHMHDR->address = offset;
full_barrier full_barrier
d->SetAndWait(CORE_READ_QUAD); d->SetAndWait(CORE_READ_DWORD);
val = D_SHMHDR->Qvalue; val = reinterpret_cast<float&> (D_SHMHDR->value);
} }
/* /*
@ -752,7 +714,6 @@ void SHMProcess::writeQuad (uint32_t offset, uint64_t data)
d->SetAndWait(CORE_WRITE_QUAD); d->SetAndWait(CORE_WRITE_QUAD);
} }
void SHMProcess::writeDWord (uint32_t offset, uint32_t data) void SHMProcess::writeDWord (uint32_t offset, uint32_t data)
{ {
if(!d->locked) throw Error::MemoryAccessDenied(); if(!d->locked) throw Error::MemoryAccessDenied();
@ -895,6 +856,7 @@ string SHMProcess::getPath()
string out(String); string out(String);
return(out.substr(0,out.find_last_of("\\"))); return(out.substr(0,out.find_last_of("\\")));
} }
// get module index by name and version. bool 0 = error // get module index by name and version. bool 0 = error
bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT) bool SHMProcess::getModuleIndex (const char * name, const uint32_t version, uint32_t & OUTPUT)
{ {