SHM rework, stage 1

develop
Petr Mrázek 2010-03-03 05:43:38 +01:00
parent b3424418e6
commit 0192520d43
11 changed files with 1328 additions and 1571 deletions

@ -1,138 +0,0 @@
Here's how you build dfhack!
----------------------------
First, there is one dependency, regardless of the OS you use:
cmake - it's the build system
Building on Linux:
--------------------
* To run in the output folder (without installing):
building the library is simple. Enter the build folder, run the tools. Like this:
cd build
cmake .. -DCMAKE_BUILD_TYPE:string=Release
make
This will build the library and its tools and place them in /output.
You can also use a cmake-friendly IDE like KDevelop 4 or the cmake GUI program.
* To be installed into the system or packaged
cd build
cmake -DCMAKE_BUILD_TYPE:string=Release -DCMAKE_INSTALL_PREFIX=/usr -DMEMXML_DATA_PATH:path=/usr/share/dfhack ..
make
make install
With this dfhack installs:
library to $CMAKE_INSTALL_PREFIX/lib
executables to $CMAKE_INSTALL_PREFIX/bin
The Memory.xml file to /usr/share/dfhack
See the section on the shared memory hook library (SHM).
Building on Windows:
--------------------
You need cmake. Get the win32 installer version from the official site: http://www.cmake.org/cmake/resources/software.html
It has the usual installer wizard thing.
* Using mingw:
You also need a compiler. I build dfhack using mingw. You can get it from the mingw site:
Get the automated installer, it will download newest version of mingw and set things up nicely.
You'll have to add C:\MinGW\ to your PATH variable.
- Building:
open up cmd and navigate to the dfhack\build folder, run cmake and the mingw version of make:
cd build
cmake .. -G"MinGW Makefiles" -DCMAKE_BUILD_TYPE:string=Release
mingw32-make
* Using MSVC
open up cmd and navigate to the dfhack\build folder, run cmake:
cd build
cmake ..
This will generate MSVC solution and project files. Note that: you are working in the /build folder.
Files added to projects will end up there! (and that's wrong). Any changes to the build system should
be done by changing cmake configs and running cmake on them!
* Using some other compiler:
I'm afraid you are on your own. dfhack wasn't tested with any other compiler.
Try using a different cmake generator that's intended for your tools.
Building the shared memory hook library (SHM)
---------------------------------------------
Unlike the rest of DFHack, The SHM needs special treatment when it comes to compilation.
Because it shares the memory space with DF itself, it has to be built with the same tools as DF
and use the same C and C++/STL libraries.
For DF 40d15 - 40d17 on Windows, use MSVC 2008. You can get the Express edition for free from Microsoft.
Windows dependencies can be determined by a tool like depends.exe (google it). Both the fake SDL.dll
and DF have to use the same version of the C runtime (MSVCRT).
The SHM can't be debugged, because debug builds in MSVC use a different CRT!
Linux dependencies can be determined by setting the LD_DEBUG variable and running ./df:
export LD_DEBUG=versions
./df
Example of (a part of a) relevant output from a working SHM installation:
24472: checking for version `GLIBC_2.0' in file /opt/lib32/lib/libpthread.so.0 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GCC_3.0' in file ./libs/libgcc_s.so.1 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.0' in file ./libs/libgcc_s.so.1 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.1' in file /opt/lib32/lib/libm.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.0' in file /opt/lib32/lib/libm.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.1.3' in file /opt/lib32/lib/libc.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.3.4' in file /opt/lib32/lib/libc.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.4' in file /opt/lib32/lib/libc.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBC_2.0' in file /opt/lib32/lib/libc.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBCXX_3.4.9' in file ./libs/libstdc++.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `CXXABI_1.3' in file ./libs/libstdc++.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `GLIBCXX_3.4' in file ./libs/libstdc++.so.6 [0] required by file ./dwarfort.exe [0]
24472: checking for version `CXXABI_1.3' in file ./libs/libstdc++.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBCXX_3.4' in file ./libs/libstdc++.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBC_2.1.3' in file /opt/lib32/lib/libc.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBC_2.2' in file /opt/lib32/lib/libc.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBC_2.3.4' in file /opt/lib32/lib/libc.so.6 [0] required by file ./libs/libdfconnect.so [0]
24472: checking for version `GLIBC_2.0' in file /opt/lib32/lib/libc.so.6 [0] required by file ./libs/libdfconnect.so [0]
libdfconnect is the SHM. Both are compiled against the same C++ library and share the same CXXABI version.
Precompiled SHM libraries are provided in binary releases.
* Checking strings support
Strings are one of the important C++ types and a great indicator that the SHM works. Tools like Dwarf Therapist depend
on string support. Reading of strings can be checked by running any of the tools that deal with materials.
String writing is best tested with a fresh throw-away fort and dfrenamer. Embark, give one dwarf a very long name using dfrenamer
and save/exit. If DF crashes during the save sequence, your SHM is not compatible with DF and the throw-away fort is lost.
Build targets
-------------
dfhack has a few build targets. If you're only after the library run 'make dfhack'.
'make' will build everything.
'make expbench' will build the expbench throughput testing program and the library.
Build types
-----------
cmake allows you to pick a build type by changing this variable: CMAKE_BUILD_TYPE
cmake .. -DCMAKE_BUILD_TYPE:string=BUILD_TYPE
Without specifying a build type or 'None', cmake uses the CMAKE_CXX_FLAGS variable for building.
Valid build types include 'Release' and 'Debug'. There are others, but they aren't really that useful.
Have fun.

@ -1,174 +0,0 @@
Introduction
------------
DFHack is a Dwarf Fortress memory access library and a set of basic tools using
this library. The library is a work in progress, so things might change as more
tools are written for it.
It is an attempt to unite the various ways tools access DF memory and allow for
easier development of new tools.
Getting DFHack
----------------
The project is currently hosted on github:
http://github.com/peterix/dfhack
There's an SVN repository at sourceforge, but will only be updated for major releases:
https://sourceforge.net/projects/dfhack/
* subversion access:
svn co https://dfhack.svn.sourceforge.net/svnroot/dfhack/trunk dfhack
Compatibility
-------------
DFHack works on Windows XP, Vista, 7 or any modern Linux distribution.
Windows 2000 is currently *not supported* due to missing OS functionality.
If you know how to easily suspend processes, you can fix it :)
OSX is also not supported due to lack of developers with a Mac.
Currently supported Dwarf Fortress versions:
* Windows
40d
40d9 - 40d18
* Linux
40d9 - 40d18
Using the library
-----------------
The library is compilable under Linux with GCC and under Windows with MinGW32
and MSVC compilers. It is using the cmake build system. See COMPILE for details.
DFHack is using the zlib/libpng license. This makes it easy to link to it, use
it in-source or add your own extensions. Contributing back to the dfhack
repository is welcome and the right thing to do :)
At the time of writing there's no API reference or documentation. The code does
have a lot of comments though.
Using DFHack Tools
------------------
The project comes with a special extra library you should add to your DF
installation. It's used to boost the transfer speed between DF and DFHack, and
provide data consistency and synchronization. DFHack will work without the
library, but at suboptimal speeds and the consistency of data written back
to DF is questionable.
!!! on Windows this currently only works with DF 40d15 - 40d18 !!!
On Linux, it works with the whole range of supported DF versions.
!!! use the pre-compiled library intended for your OS and version of DF !!!
You can find them in the 'precompiled' folder.
** Installing on Windows
- Open your DF folder, locate SDL.dll and rename it to SDLreal.dll (making
a backup of it is a good idea)
- Copy the right DFHack SDL.dll into your DF folder.
- Restart DF if it is running
** Unistalling on Windows
- Open your DF folder, locate SDL.dll and delete it
- Rename SDLreal.dll to SDL.dll
- Restart DF if it is running
** Installing on Linux
- Open your DF folder and the libs folder within it
- copy DFHack libdfconnect.so to the libs folder
- copy the df startup script, name it dfhacked
- open the new dfhacked startup script and add this line:
export LD_PRELOAD="./libs/libdfconnect.so" # Hack DF!
just before the line that launches DF
Here's an example how the file can look after the change:
#!/bin/sh
DF_DIR=$(dirname "$0")
cd "${DF_DIR}"
export SDL_DISABLE_LOCK_KEYS=1 # Work around for bug in Debian/Ubuntu SDL patch.
#export SDL_VIDEO_CENTERED=1 # Centre the screen. Messes up resizing.
ldd dwarfort.exe | grep SDL_image | grep -qv "not found$"
if [ $? -eq 0 ]; then
mkdir unused_libs
mv libs/libSDL* unused_libs/
fi
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:"./libs" # Update library search path.
export LD_PRELOAD="./libs/libdfconnect.so" # Hack DF!
./dwarfort.exe $* # Go, go, go! :)
- Use this new startup script to start DF
** Uninstalling on Linux
- Open your DF and DF/libs folders
- Delete libdfconnect.so and the dfhacked startup script
- Go back to using the df startup script
Tools
-----
All the DFHack tools are terminal programs. This might seem strange to Windows
users, but these are meant mostly as examples for developers. Still, they can
be useful and are cross-platform just like the library itself.
If the tool writes back to DF's memory, make sure you are using the shared
memory interface mentioned in the previous section!
* reveal - plain old reveal tool. It reveals all the map blocks already
initialized by DF.
* prospector - scans the map for minerals. by default it only scans only visible
veins. You can make it show hidden things with '-a' and base rock
and soil layers with '-b'. These can be combined ('-ab')
* cleanmap - cleans mud, vomit, snow and all kinds of mess from the map.
It will clean your irrigated farms too, so consider yourself
warned.
* incremental - incremental search utility.
* bauxite - converts all mechanisms into bauxite mechanisms.
* itemdesignator - Allows mass-designating items by type and material - dump,
forbid, melt and set on fire ;)
* digger - allows designating tiles for digging/cutting/ramp removal
A list of accepted tile classes:
1 = WALL
2 = PILLAR
3 = FORTIFICATION
4 = STAIR_UP
5 = STAIR_DOWN
6 = STAIR_UPDOWN
7 = RAMP
8 = FLOOR
9 = TREE_DEAD
10 = TREE_OK
11 = SAPLING_DEAD
12 = SAPLING_OK
13 = SHRUB_DEAD
14 = SHRUB_OK
15 = BOULDER
16 = PEBBLES
Example : dfdigger -o 100,100,15 -t 9,10 -m 10
This will start looking for trees at coords 100,100,15 and designate ten of them for cutting.
Memory offset definitions
-------------------------
The file with memory offset definitions used by dfhack can be found in the
output folder.
~ EOF ~

@ -50,6 +50,7 @@ class Process::Private
attached = false; attached = false;
suspended = false; suspended = false;
identified = false; identified = false;
useYield = false;
}; };
~Private(){}; ~Private(){};
memory_info * my_descriptor; memory_info * my_descriptor;
@ -61,18 +62,26 @@ class Process::Private
bool attached; bool attached;
bool suspended; bool suspended;
bool identified; bool identified;
bool useYield;
bool validate(char* exe_file, uint32_t pid, std::vector< memory_info* >& known_versions); bool validate(char* exe_file, uint32_t pid, std::vector< memory_info* >& known_versions);
bool waitWhile (DF_PINGPONG state); bool waitWhile (CORE_COMMAND state);
bool DF_TestBridgeVersion(bool & ret); bool DF_TestBridgeVersion(bool & ret);
bool DF_GetPID(pid_t & ret); bool DF_GetPID(pid_t & ret);
}; };
bool Process::Private::waitWhile (DF_PINGPONG state) // some helpful macros to keep the code bloat in check
#define SHMCMD ((shm_cmd *)my_shm)->pingpong
#define D_SHMCMD ((shm_cmd *)d->my_shm)->pingpong
#define SHMHDR ((shm_header *)my_shm)
#define D_SHMHDR ((shm_header *)d->my_shm)
bool Process::Private::waitWhile (CORE_COMMAND state)
{ {
uint32_t cnt = 0; uint32_t cnt = 0;
struct shmid_ds descriptor; struct shmid_ds descriptor;
while (((shm_cmd *)my_shm)->pingpong == state) while (SHMCMD == state)
{ {
if(cnt == 10000) if(cnt == 10000)
{ {
@ -80,8 +89,7 @@ bool Process::Private::waitWhile (DF_PINGPONG state)
shmctl(my_shmid, IPC_STAT, &descriptor); shmctl(my_shmid, IPC_STAT, &descriptor);
if(descriptor.shm_nattch == 1)// DF crashed? if(descriptor.shm_nattch == 1)// DF crashed?
{ {
gcc_barrier SHMCMD = CORE_RUNNING;
((shm_cmd *)my_shm)->pingpong = DFPP_RUNNING;
attached = suspended = false; attached = suspended = false;
return false; return false;
} }
@ -93,9 +101,9 @@ bool Process::Private::waitWhile (DF_PINGPONG state)
SCHED_YIELD SCHED_YIELD
cnt++; cnt++;
} }
if(((shm_cmd *)my_shm)->pingpong == DFPP_SV_ERROR) if(SHMCMD == CORE_SV_ERROR)
{ {
((shm_cmd *)my_shm)->pingpong = DFPP_RUNNING; SHMCMD = CORE_RUNNING;
attached = suspended = false; attached = suspended = false;
cerr << "shm server error!" << endl; cerr << "shm server error!" << endl;
assert (false); assert (false);
@ -106,25 +114,25 @@ bool Process::Private::waitWhile (DF_PINGPONG state)
bool Process::Private::DF_TestBridgeVersion(bool & ret) bool Process::Private::DF_TestBridgeVersion(bool & ret)
{ {
((shm_cmd *)my_shm)->pingpong = DFPP_VERSION; SHMCMD = CORE_GET_VERSION;
gcc_barrier gcc_barrier
if(!waitWhile(DFPP_VERSION)) if(!waitWhile(CORE_GET_VERSION))
return false; return false;
gcc_barrier gcc_barrier
((shm_cmd *)my_shm)->pingpong = DFPP_SUSPENDED; SHMCMD = CORE_SUSPENDED;
ret =( ((shm_retval *)my_shm)->value == PINGPONG_VERSION ); ret =( SHMHDR->value == CORE_VERSION );
return true; return true;
} }
bool Process::Private::DF_GetPID(pid_t & ret) bool Process::Private::DF_GetPID(pid_t & ret)
{ {
((shm_cmd *)my_shm)->pingpong = DFPP_PID; SHMCMD = CORE_GET_PID;
gcc_barrier gcc_barrier
if(!waitWhile(DFPP_PID)) if(!waitWhile(CORE_GET_PID))
return false; return false;
gcc_barrier gcc_barrier
((shm_cmd *)my_shm)->pingpong = DFPP_SUSPENDED; SHMCMD = CORE_SUSPENDED;
ret = ((shm_retval *)my_shm)->value; ret = SHMHDR->value;
return true; return true;
} }
@ -200,7 +208,7 @@ Process::Process(vector <memory_info *> & known_versions)
} }
gcc_barrier gcc_barrier
// at this point, DF is stopped and waiting for commands. make it run again // at this point, DF is stopped and waiting for commands. make it run again
((shm_cmd *)d->my_shm)->pingpong = DFPP_RUNNING; D_SHMCMD = CORE_RUNNING;
shmdt(d->my_shm); // detach so we don't attach twice when attach() is called shmdt(d->my_shm); // detach so we don't attach twice when attach() is called
} }
@ -319,8 +327,8 @@ bool Process::suspend()
{ {
return true; return true;
} }
((shm_cmd *)d->my_shm)->pingpong = DFPP_SUSPEND; D_SHMCMD = CORE_SUSPEND;
if(!d->waitWhile(DFPP_SUSPEND)) if(!d->waitWhile(CORE_SUSPEND))
{ {
return false; return false;
} }
@ -338,14 +346,14 @@ bool Process::asyncSuspend()
{ {
return true; return true;
} }
if(((shm_cmd *)d->my_shm)->pingpong == DFPP_SUSPENDED) if(D_SHMCMD == CORE_SUSPENDED)
{ {
d->suspended = true; d->suspended = true;
return true; return true;
} }
else else
{ {
((shm_cmd *)d->my_shm)->pingpong = DFPP_SUSPEND; D_SHMCMD = CORE_SUSPEND;
return false; return false;
} }
} }
@ -361,7 +369,7 @@ bool Process::resume()
return false; return false;
if(!d->suspended) if(!d->suspended)
return true; return true;
((shm_cmd *)d->my_shm)->pingpong = DFPP_RUNNING; D_SHMCMD = CORE_RUNNING;
d->suspended = false; d->suspended = false;
return true; return true;
} }
@ -425,11 +433,11 @@ void Process::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer)
// normal read under 1MB // normal read under 1MB
if(size <= SHM_BODY) if(size <= SHM_BODY)
{ {
((shm_read *)d->my_shm)->address = src_address; D_SHMHDR->address = src_address;
((shm_read *)d->my_shm)->length = size; D_SHMHDR->length = size;
gcc_barrier gcc_barrier
((shm_read *)d->my_shm)->pingpong = DFPP_READ; D_SHMCMD = CORE_DFPP_READ;
d->waitWhile(DFPP_READ); d->waitWhile(CORE_DFPP_READ);
memcpy (target_buffer, d->my_shm + SHM_HEADER,size); memcpy (target_buffer, d->my_shm + SHM_HEADER,size);
} }
// a big read, we pull data over the shm in iterations // a big read, we pull data over the shm in iterations
@ -440,11 +448,11 @@ void Process::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer)
while (size) while (size)
{ {
// read to_read bytes from src_cursor // read to_read bytes from src_cursor
((shm_read *)d->my_shm)->address = src_address; D_SHMHDR->address = src_address;
((shm_read *)d->my_shm)->length = to_read; D_SHMHDR->length = to_read;
gcc_barrier gcc_barrier
((shm_read *)d->my_shm)->pingpong = DFPP_READ; D_SHMCMD = CORE_DFPP_READ;
d->waitWhile(DFPP_READ); d->waitWhile(CORE_DFPP_READ);
memcpy (target_buffer, d->my_shm + SHM_HEADER,size); memcpy (target_buffer, d->my_shm + SHM_HEADER,size);
// decrease size by bytes read // decrease size by bytes read
size -= to_read; size -= to_read;
@ -459,55 +467,55 @@ void Process::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer)
uint8_t Process::readByte (const uint32_t offset) uint8_t Process::readByte (const uint32_t offset)
{ {
((shm_read_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
gcc_barrier gcc_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_BYTE; D_SHMCMD = CORE_READ_BYTE;
d->waitWhile(DFPP_READ_BYTE); d->waitWhile(CORE_READ_BYTE);
return ((shm_retval *)d->my_shm)->value; return D_SHMHDR->value;
} }
void Process::readByte (const uint32_t offset, uint8_t &val ) void Process::readByte (const uint32_t offset, uint8_t &val )
{ {
((shm_read_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
gcc_barrier gcc_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_BYTE; D_SHMCMD = CORE_READ_BYTE;
d->waitWhile(DFPP_READ_BYTE); d->waitWhile(CORE_READ_BYTE);
val = ((shm_retval *)d->my_shm)->value; val = D_SHMHDR->value;
} }
uint16_t Process::readWord (const uint32_t offset) uint16_t Process::readWord (const uint32_t offset)
{ {
((shm_read_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
gcc_barrier gcc_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_WORD; D_SHMCMD = CORE_READ_WORD;
d->waitWhile(DFPP_READ_WORD); d->waitWhile(CORE_READ_WORD);
return ((shm_retval *)d->my_shm)->value; return D_SHMHDR->value;
} }
void Process::readWord (const uint32_t offset, uint16_t &val) void Process::readWord (const uint32_t offset, uint16_t &val)
{ {
((shm_read_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
gcc_barrier gcc_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_WORD; D_SHMCMD = CORE_READ_WORD;
d->waitWhile(DFPP_READ_WORD); d->waitWhile(CORE_READ_WORD);
val = ((shm_retval *)d->my_shm)->value; val = D_SHMHDR->value;
} }
uint32_t Process::readDWord (const uint32_t offset) uint32_t Process::readDWord (const uint32_t offset)
{ {
((shm_read_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
gcc_barrier gcc_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_DWORD; D_SHMCMD = CORE_READ_DWORD;
d->waitWhile(DFPP_READ_DWORD); d->waitWhile(CORE_READ_DWORD);
return ((shm_retval *)d->my_shm)->value; return D_SHMHDR->value;
} }
void Process::readDWord (const uint32_t offset, uint32_t &val) void Process::readDWord (const uint32_t offset, uint32_t &val)
{ {
((shm_read_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
gcc_barrier gcc_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_DWORD; D_SHMCMD = CORE_READ_DWORD;
d->waitWhile(DFPP_READ_DWORD); d->waitWhile(CORE_READ_DWORD);
val = ((shm_retval *)d->my_shm)->value; val = D_SHMHDR->value;
} }
/* /*
@ -516,30 +524,30 @@ void Process::readDWord (const uint32_t offset, uint32_t &val)
void Process::writeDWord (uint32_t offset, uint32_t data) void Process::writeDWord (uint32_t offset, uint32_t data)
{ {
((shm_write_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
((shm_write_small *)d->my_shm)->value = data; D_SHMHDR->value = data;
gcc_barrier gcc_barrier
((shm_write_small *)d->my_shm)->pingpong = DFPP_WRITE_DWORD; D_SHMCMD = CORE_WRITE_DWORD;
d->waitWhile(DFPP_WRITE_DWORD); d->waitWhile(CORE_WRITE_DWORD);
} }
// using these is expensive. // using these is expensive.
void Process::writeWord (uint32_t offset, uint16_t data) void Process::writeWord (uint32_t offset, uint16_t data)
{ {
((shm_write_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
((shm_write_small *)d->my_shm)->value = data; D_SHMHDR->value = data;
gcc_barrier gcc_barrier
((shm_write_small *)d->my_shm)->pingpong = DFPP_WRITE_WORD; D_SHMCMD = CORE_WRITE_WORD;
d->waitWhile(DFPP_WRITE_WORD); d->waitWhile(CORE_WRITE_WORD);
} }
void Process::writeByte (uint32_t offset, uint8_t data) void Process::writeByte (uint32_t offset, uint8_t data)
{ {
((shm_write_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
((shm_write_small *)d->my_shm)->value = data; D_SHMHDR->value = data;
gcc_barrier gcc_barrier
((shm_write_small *)d->my_shm)->pingpong = DFPP_WRITE_BYTE; D_SHMCMD = CORE_WRITE_BYTE;
d->waitWhile(DFPP_WRITE_BYTE); d->waitWhile(CORE_WRITE_BYTE);
} }
void Process::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) void Process::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer)
@ -547,12 +555,12 @@ void Process::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer
// normal write under 1MB // normal write under 1MB
if(size <= SHM_BODY) if(size <= SHM_BODY)
{ {
((shm_write *)d->my_shm)->address = dst_address; D_SHMHDR->address = dst_address;
((shm_write *)d->my_shm)->length = size; D_SHMHDR->length = size;
memcpy(d->my_shm+SHM_HEADER,source_buffer, size); memcpy(d->my_shm+SHM_HEADER,source_buffer, size);
gcc_barrier gcc_barrier
((shm_write *)d->my_shm)->pingpong = DFPP_WRITE; D_SHMCMD = CORE_WRITE;
d->waitWhile(DFPP_WRITE); d->waitWhile(CORE_WRITE);
} }
// a big write, we push this over the shm in iterations // a big write, we push this over the shm in iterations
else else
@ -562,12 +570,12 @@ void Process::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer
while (size) while (size)
{ {
// write to_write bytes to dst_cursor // write to_write bytes to dst_cursor
((shm_write *)d->my_shm)->address = dst_address; D_SHMHDR->address = dst_address;
((shm_write *)d->my_shm)->length = to_write; D_SHMHDR->length = to_write;
memcpy(d->my_shm+SHM_HEADER,source_buffer, to_write); memcpy(d->my_shm+SHM_HEADER,source_buffer, to_write);
gcc_barrier gcc_barrier
((shm_write *)d->my_shm)->pingpong = DFPP_WRITE; D_SHMCMD = CORE_WRITE;
d->waitWhile(DFPP_WRITE); d->waitWhile(CORE_WRITE);
// decrease size by bytes written // decrease size by bytes written
size -= to_write; size -= to_write;
// move the cursors // move the cursors
@ -615,21 +623,21 @@ DfVector Process::readVector (uint32_t offset, uint32_t item_size)
const std::string Process::readSTLString(uint32_t offset) const std::string Process::readSTLString(uint32_t offset)
{ {
((shm_read_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_STL_STRING; D_SHMCMD = CORE_READ_STL_STRING;
d->waitWhile(DFPP_READ_STL_STRING); d->waitWhile(CORE_READ_STL_STRING);
//int length = ((shm_retval *)d->my_shm)->value; //int length = ((shm_retval *)d->my_shm)->value;
return(string( (char *)d->my_shm+SHM_HEADER)); return(string( (char *)d->my_shm+SHM_HEADER));
} }
size_t Process::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) size_t Process::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{ {
((shm_read_small *)d->my_shm)->address = offset; D_SHMHDR->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_STL_STRING; D_SHMCMD = CORE_READ_STL_STRING;
d->waitWhile(DFPP_READ_STL_STRING); d->waitWhile(CORE_READ_STL_STRING);
size_t length = ((shm_retval *)d->my_shm)->value; size_t length = D_SHMHDR->value;
size_t fit = min(bufcapacity - 1, length); size_t fit = min(bufcapacity - 1, length);
strncpy(buffer,(char *)d->my_shm+SHM_HEADER,fit); strncpy(buffer,(char *)d->my_shm+SHM_HEADER,fit);
buffer[fit] = 0; buffer[fit] = 0;
@ -638,11 +646,11 @@ size_t Process::readSTLString (uint32_t offset, char * buffer, size_t bufcapacit
void Process::writeSTLString(const uint32_t address, const std::string writeString) void Process::writeSTLString(const uint32_t address, const std::string writeString)
{ {
((shm_write_small *)d->my_shm)->address = address; D_SHMHDR->address = address;
strncpy(d->my_shm+SHM_HEADER,writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator strncpy(d->my_shm+SHM_HEADER,writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator
full_barrier full_barrier
((shm_write_small *)d->my_shm)->pingpong = DFPP_WRITE_STL_STRING; D_SHMCMD = CORE_WRITE_STL_STRING;
d->waitWhile(DFPP_WRITE_STL_STRING); d->waitWhile(CORE_WRITE_STL_STRING);
} }
string Process::readClassName (uint32_t vptr) string Process::readClassName (uint32_t vptr)

@ -53,7 +53,7 @@ class Process::Private
bool suspended; bool suspended;
bool identified; bool identified;
bool waitWhile (DF_PINGPONG state); bool waitWhile (CORE_COMMAND state);
bool isValidSV(); bool isValidSV();
bool DF_TestBridgeVersion(bool & ret); bool DF_TestBridgeVersion(bool & ret);
bool DF_GetPID(uint32_t & ret); bool DF_GetPID(uint32_t & ret);
@ -87,7 +87,7 @@ bool Process::Private::isValidSV()
} }
} }
bool Process::Private::waitWhile (DF_PINGPONG state) bool Process::Private::waitWhile (CORE_COMMAND state)
{ {
uint32_t cnt = 0; uint32_t cnt = 0;
SCHED_YIELD // yield the CPU, valid only on single-core CPUs SCHED_YIELD // yield the CPU, valid only on single-core CPUs
@ -98,7 +98,7 @@ bool Process::Private::waitWhile (DF_PINGPONG state)
if(!isValidSV())// DF not there anymore? if(!isValidSV())// DF not there anymore?
{ {
full_barrier full_barrier
((shm_cmd *)my_shm)->pingpong = DFPP_RUNNING; ((shm_cmd *)my_shm)->pingpong = CORE_RUNNING;
attached = suspended = false; attached = suspended = false;
ReleaseMutex(DFCLMutex); ReleaseMutex(DFCLMutex);
return false; return false;
@ -110,9 +110,9 @@ bool Process::Private::waitWhile (DF_PINGPONG state)
} }
cnt++; cnt++;
} }
if(((shm_cmd *)my_shm)->pingpong == DFPP_SV_ERROR) if(((shm_cmd *)my_shm)->pingpong == CORE_SV_ERROR)
{ {
((shm_cmd *)my_shm)->pingpong = DFPP_RUNNING; ((shm_cmd *)my_shm)->pingpong = CORE_RUNNING;
attached = suspended = false; attached = suspended = false;
cerr << "shm server error!" << endl; cerr << "shm server error!" << endl;
assert (false); assert (false);
@ -123,25 +123,25 @@ bool Process::Private::waitWhile (DF_PINGPONG state)
bool Process::Private::DF_TestBridgeVersion(bool & ret) bool Process::Private::DF_TestBridgeVersion(bool & ret)
{ {
((shm_cmd *)my_shm)->pingpong = DFPP_VERSION; ((shm_cmd *)my_shm)->pingpong = CORE_GET_VERSION;
full_barrier full_barrier
if(!waitWhile(DFPP_VERSION)) if(!waitWhile(CORE_GET_VERSION))
return false; return false;
full_barrier full_barrier
((shm_cmd *)my_shm)->pingpong = DFPP_SUSPENDED; ((shm_cmd *)my_shm)->pingpong = CORE_SUSPENDED;
ret =( ((shm_retval *)my_shm)->value == PINGPONG_VERSION ); ret =( ((shm_val *)my_shm)->value == CORE_VERSION );
return true; return true;
} }
bool Process::Private::DF_GetPID(uint32_t & ret) bool Process::Private::DF_GetPID(uint32_t & ret)
{ {
((shm_cmd *)my_shm)->pingpong = DFPP_PID; ((shm_cmd *)my_shm)->pingpong = CORE_GET_PID;
full_barrier full_barrier
if(!waitWhile(DFPP_PID)) if(!waitWhile(CORE_GET_PID))
return false; return false;
full_barrier full_barrier
((shm_cmd *)my_shm)->pingpong = DFPP_SUSPENDED; ((shm_cmd *)my_shm)->pingpong = CORE_SUSPENDED;
ret = ((shm_retval *)my_shm)->value; ret = ((shm_val *)my_shm)->value;
return true; return true;
} }
@ -182,7 +182,7 @@ Process::Process(vector <memory_info *> & known_versions)
if(!bridgeOK) if(!bridgeOK)
{ {
fprintf(stderr,"SHM bridge version mismatch\n"); fprintf(stderr,"SHM bridge version mismatch\n");
((shm_cmd *)d->my_shm)->pingpong = DFPP_RUNNING; ((shm_cmd *)d->my_shm)->pingpong = CORE_RUNNING;
UnmapViewOfFile(d->my_shm); UnmapViewOfFile(d->my_shm);
ReleaseMutex(d->DFCLMutex); ReleaseMutex(d->DFCLMutex);
CloseHandle(d->DFSVMutex); CloseHandle(d->DFSVMutex);
@ -258,7 +258,7 @@ Process::Process(vector <memory_info *> & known_versions)
} }
else else
{ {
((shm_cmd *)d->my_shm)->pingpong = DFPP_RUNNING; ((shm_cmd *)d->my_shm)->pingpong = CORE_RUNNING;
UnmapViewOfFile(d->my_shm); UnmapViewOfFile(d->my_shm);
d->my_shm = 0; d->my_shm = 0;
ReleaseMutex(d->DFCLMutex); ReleaseMutex(d->DFCLMutex);
@ -375,8 +375,8 @@ bool Process::suspend()
cerr << "couldn't suspend, already suspended" << endl; cerr << "couldn't suspend, already suspended" << endl;
return true; return true;
} }
((shm_cmd *)d->my_shm)->pingpong = DFPP_SUSPEND; ((shm_cmd *)d->my_shm)->pingpong = CORE_SUSPEND;
if(!d->waitWhile(DFPP_SUSPEND)) if(!d->waitWhile(CORE_SUSPEND))
{ {
cerr << "couldn't suspend, DF not responding to commands" << endl; cerr << "couldn't suspend, DF not responding to commands" << endl;
return false; return false;
@ -395,14 +395,14 @@ bool Process::asyncSuspend()
{ {
return true; return true;
} }
if(((shm_cmd *)d->my_shm)->pingpong == DFPP_SUSPENDED) if(((shm_cmd *)d->my_shm)->pingpong == CORE_SUSPENDED)
{ {
d->suspended = true; d->suspended = true;
return true; return true;
} }
else else
{ {
((shm_cmd *)d->my_shm)->pingpong = DFPP_SUSPEND; ((shm_cmd *)d->my_shm)->pingpong = CORE_SUSPEND;
return false; return false;
} }
} }
@ -424,7 +424,7 @@ bool Process::resume()
cerr << "couldn't resume because of not being suspended" << endl; cerr << "couldn't resume because of not being suspended" << endl;
return true; return true;
} }
((shm_cmd *)d->my_shm)->pingpong = DFPP_RUNNING; ((shm_cmd *)d->my_shm)->pingpong = CORE_RUNNING;
d->suspended = false; d->suspended = false;
return true; return true;
} }
@ -499,11 +499,11 @@ void Process::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer)
// normal read under 1MB // normal read under 1MB
if(size <= SHM_BODY) if(size <= SHM_BODY)
{ {
((shm_read *)d->my_shm)->address = src_address; ((shm_addrlen *)d->my_shm)->address = src_address;
((shm_read *)d->my_shm)->length = size; ((shm_addrlen *)d->my_shm)->length = size;
full_barrier full_barrier
((shm_read *)d->my_shm)->pingpong = DFPP_READ; ((shm_cmd *)d->my_shm)->pingpong = CORE_DFPP_READ;
d->waitWhile(DFPP_READ); d->waitWhile(CORE_DFPP_READ);
memcpy (target_buffer, d->my_shm + SHM_HEADER,size); memcpy (target_buffer, d->my_shm + SHM_HEADER,size);
} }
// a big read, we pull data over the shm in iterations // a big read, we pull data over the shm in iterations
@ -514,11 +514,11 @@ void Process::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer)
while (size) while (size)
{ {
// read to_read bytes from src_cursor // read to_read bytes from src_cursor
((shm_read *)d->my_shm)->address = src_address; ((shm_addrlen *)d->my_shm)->address = src_address;
((shm_read *)d->my_shm)->length = to_read; ((shm_addrlen *)d->my_shm)->length = to_read;
full_barrier full_barrier
((shm_read *)d->my_shm)->pingpong = DFPP_READ; ((shm_cmd *)d->my_shm)->pingpong = CORE_DFPP_READ;
d->waitWhile(DFPP_READ); d->waitWhile(CORE_DFPP_READ);
memcpy (target_buffer, d->my_shm + SHM_HEADER,size); memcpy (target_buffer, d->my_shm + SHM_HEADER,size);
// decrease size by bytes read // decrease size by bytes read
size -= to_read; size -= to_read;
@ -533,55 +533,55 @@ void Process::read (uint32_t src_address, uint32_t size, uint8_t *target_buffer)
uint8_t Process::readByte (const uint32_t offset) uint8_t Process::readByte (const uint32_t offset)
{ {
((shm_read_small *)d->my_shm)->address = offset; ((shm_addr *)d->my_shm)->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_BYTE; ((shm_cmd *)d->my_shm)->pingpong = CORE_READ_BYTE;
d->waitWhile(DFPP_READ_BYTE); d->waitWhile(CORE_READ_BYTE);
return ((shm_retval *)d->my_shm)->value; return ((shm_val *)d->my_shm)->value;
} }
void Process::readByte (const uint32_t offset, uint8_t &val ) void Process::readByte (const uint32_t offset, uint8_t &val )
{ {
((shm_read_small *)d->my_shm)->address = offset; ((shm_addr *)d->my_shm)->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_BYTE; ((shm_cmd *)d->my_shm)->pingpong = CORE_READ_BYTE;
d->waitWhile(DFPP_READ_BYTE); d->waitWhile(CORE_READ_BYTE);
val = ((shm_retval *)d->my_shm)->value; val = ((shm_val *)d->my_shm)->value;
} }
uint16_t Process::readWord (const uint32_t offset) uint16_t Process::readWord (const uint32_t offset)
{ {
((shm_read_small *)d->my_shm)->address = offset; ((shm_addr *)d->my_shm)->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_WORD; ((shm_cmd *)d->my_shm)->pingpong = CORE_READ_WORD;
d->waitWhile(DFPP_READ_WORD); d->waitWhile(CORE_READ_WORD);
return ((shm_retval *)d->my_shm)->value; return ((shm_val *)d->my_shm)->value;
} }
void Process::readWord (const uint32_t offset, uint16_t &val) void Process::readWord (const uint32_t offset, uint16_t &val)
{ {
((shm_read_small *)d->my_shm)->address = offset; ((shm_addr *)d->my_shm)->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_WORD; ((shm_cmd *)d->my_shm)->pingpong = CORE_READ_WORD;
d->waitWhile(DFPP_READ_WORD); d->waitWhile(CORE_READ_WORD);
val = ((shm_retval *)d->my_shm)->value; val = ((shm_val *)d->my_shm)->value;
} }
uint32_t Process::readDWord (const uint32_t offset) uint32_t Process::readDWord (const uint32_t offset)
{ {
((shm_read_small *)d->my_shm)->address = offset; ((shm_addr *)d->my_shm)->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_DWORD; ((shm_cmd *)d->my_shm)->pingpong = CORE_READ_DWORD;
d->waitWhile(DFPP_READ_DWORD); d->waitWhile(CORE_READ_DWORD);
return ((shm_retval *)d->my_shm)->value; return ((shm_val *)d->my_shm)->value;
} }
void Process::readDWord (const uint32_t offset, uint32_t &val) void Process::readDWord (const uint32_t offset, uint32_t &val)
{ {
((shm_read_small *)d->my_shm)->address = offset; ((shm_addr *)d->my_shm)->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_DWORD; ((shm_cmd *)d->my_shm)->pingpong = CORE_READ_DWORD;
d->waitWhile(DFPP_READ_DWORD); d->waitWhile(CORE_READ_DWORD);
val = ((shm_retval *)d->my_shm)->value; val = ((shm_val *)d->my_shm)->value;
} }
/* /*
@ -590,30 +590,30 @@ void Process::readDWord (const uint32_t offset, uint32_t &val)
void Process::writeDWord (uint32_t offset, uint32_t data) void Process::writeDWord (uint32_t offset, uint32_t data)
{ {
((shm_write_small *)d->my_shm)->address = offset; ((shm_addrval *)d->my_shm)->address = offset;
((shm_write_small *)d->my_shm)->value = data; ((shm_addrval *)d->my_shm)->value = data;
full_barrier full_barrier
((shm_write_small *)d->my_shm)->pingpong = DFPP_WRITE_DWORD; ((shm_cmd *)d->my_shm)->pingpong = CORE_WRITE_DWORD;
d->waitWhile(DFPP_WRITE_DWORD); d->waitWhile(CORE_WRITE_DWORD);
} }
// using these is expensive. // using these is expensive.
void Process::writeWord (uint32_t offset, uint16_t data) void Process::writeWord (uint32_t offset, uint16_t data)
{ {
((shm_write_small *)d->my_shm)->address = offset; ((shm_addrval *)d->my_shm)->address = offset;
((shm_write_small *)d->my_shm)->value = data; ((shm_addrval *)d->my_shm)->value = data;
full_barrier full_barrier
((shm_write_small *)d->my_shm)->pingpong = DFPP_WRITE_WORD; ((shm_cmd *)d->my_shm)->pingpong = CORE_WRITE_WORD;
d->waitWhile(DFPP_WRITE_WORD); d->waitWhile(CORE_WRITE_WORD);
} }
void Process::writeByte (uint32_t offset, uint8_t data) void Process::writeByte (uint32_t offset, uint8_t data)
{ {
((shm_write_small *)d->my_shm)->address = offset; ((shm_addrval *)d->my_shm)->address = offset;
((shm_write_small *)d->my_shm)->value = data; ((shm_addrval *)d->my_shm)->value = data;
full_barrier full_barrier
((shm_write_small *)d->my_shm)->pingpong = DFPP_WRITE_BYTE; ((shm_cmd *)d->my_shm)->pingpong = CORE_WRITE_BYTE;
d->waitWhile(DFPP_WRITE_BYTE); d->waitWhile(CORE_WRITE_BYTE);
} }
void Process::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer) void Process::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer)
@ -621,12 +621,12 @@ void Process::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer
// normal write under 1MB // normal write under 1MB
if(size <= SHM_BODY) if(size <= SHM_BODY)
{ {
((shm_write *)d->my_shm)->address = dst_address; ((shm_addrlen *)d->my_shm)->address = dst_address;
((shm_write *)d->my_shm)->length = size; ((shm_addrlen *)d->my_shm)->length = size;
memcpy(d->my_shm+SHM_HEADER,source_buffer, size); memcpy(d->my_shm+SHM_HEADER,source_buffer, size);
full_barrier full_barrier
((shm_write *)d->my_shm)->pingpong = DFPP_WRITE; ((shm_cmd *)d->my_shm)->pingpong = CORE_WRITE;
d->waitWhile(DFPP_WRITE); d->waitWhile(CORE_WRITE);
} }
// a big write, we push this over the shm in iterations // a big write, we push this over the shm in iterations
else else
@ -636,12 +636,12 @@ void Process::write (uint32_t dst_address, uint32_t size, uint8_t *source_buffer
while (size) while (size)
{ {
// write to_write bytes to dst_cursor // write to_write bytes to dst_cursor
((shm_write *)d->my_shm)->address = dst_address; ((shm_addrlen *)d->my_shm)->address = dst_address;
((shm_write *)d->my_shm)->length = to_write; ((shm_addrlen *)d->my_shm)->length = to_write;
memcpy(d->my_shm+SHM_HEADER,source_buffer, to_write); memcpy(d->my_shm+SHM_HEADER,source_buffer, to_write);
full_barrier full_barrier
((shm_write *)d->my_shm)->pingpong = DFPP_WRITE; ((shm_cmd *)d->my_shm)->pingpong = CORE_WRITE;
d->waitWhile(DFPP_WRITE); d->waitWhile(CORE_WRITE);
// decrease size by bytes written // decrease size by bytes written
size -= to_write; size -= to_write;
// move the cursors // move the cursors
@ -692,11 +692,11 @@ DfVector Process::readVector (uint32_t offset, uint32_t item_size)
const std::string Process::readSTLString(uint32_t offset) const std::string Process::readSTLString(uint32_t offset)
{ {
//offset -= 4; //msvc std::string pointers are 8 bytes ahead of their data, not 4 //offset -= 4; //msvc std::string pointers are 8 bytes ahead of their data, not 4
((shm_read_small *)d->my_shm)->address = offset; ((shm_addr *)d->my_shm)->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_STL_STRING; ((shm_cmd *)d->my_shm)->pingpong = CORE_READ_STL_STRING;
d->waitWhile(DFPP_READ_STL_STRING); d->waitWhile(CORE_READ_STL_STRING);
int length = ((shm_retval *)d->my_shm)->value; int length = ((shm_val *)d->my_shm)->value;
// char temp_c[256]; // char temp_c[256];
// strncpy(temp_c, d->my_shm+SHM_HEADER,length+1); // length + 1 for the null terminator // strncpy(temp_c, d->my_shm+SHM_HEADER,length+1); // length + 1 for the null terminator
return(string(d->my_shm+SHM_HEADER)); return(string(d->my_shm+SHM_HEADER));
@ -705,11 +705,11 @@ const std::string Process::readSTLString(uint32_t offset)
size_t Process::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity) size_t Process::readSTLString (uint32_t offset, char * buffer, size_t bufcapacity)
{ {
//offset -= 4; //msvc std::string pointers are 8 bytes ahead of their data, not 4 //offset -= 4; //msvc std::string pointers are 8 bytes ahead of their data, not 4
((shm_read_small *)d->my_shm)->address = offset; ((shm_addr *)d->my_shm)->address = offset;
full_barrier full_barrier
((shm_read_small *)d->my_shm)->pingpong = DFPP_READ_STL_STRING; ((shm_cmd *)d->my_shm)->pingpong = CORE_READ_STL_STRING;
d->waitWhile(DFPP_READ_STL_STRING); d->waitWhile(CORE_READ_STL_STRING);
size_t length = ((shm_retval *)d->my_shm)->value; size_t length = ((shm_val *)d->my_shm)->value;
size_t real = min(length, bufcapacity - 1); size_t real = min(length, bufcapacity - 1);
strncpy(buffer, d->my_shm+SHM_HEADER,real); // length + 1 for the null terminator strncpy(buffer, d->my_shm+SHM_HEADER,real); // length + 1 for the null terminator
buffer[real] = 0; buffer[real] = 0;
@ -718,11 +718,11 @@ size_t Process::readSTLString (uint32_t offset, char * buffer, size_t bufcapacit
void Process::writeSTLString(const uint32_t address, const std::string writeString) void Process::writeSTLString(const uint32_t address, const std::string writeString)
{ {
((shm_write_small *)d->my_shm)->address = address/*-4*/; ((shm_addr *)d->my_shm)->address = address/*-4*/;
strncpy(d->my_shm+SHM_HEADER,writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator strncpy(d->my_shm+SHM_HEADER,writeString.c_str(),writeString.length()+1); // length + 1 for the null terminator
full_barrier full_barrier
((shm_write_small *)d->my_shm)->pingpong = DFPP_WRITE_STL_STRING; ((shm_cmd *)d->my_shm)->pingpong = CORE_WRITE_STL_STRING;
d->waitWhile(DFPP_WRITE_STL_STRING); d->waitWhile(CORE_WRITE_STL_STRING);
} }
string Process::readClassName (uint32_t vptr) string Process::readClassName (uint32_t vptr)

@ -5,7 +5,7 @@ shms.h
) )
SET(PROJECT_SRCS SET(PROJECT_SRCS
shms-proto.cpp shms-core.cpp
) )
SET(PROJECT_HDRS_LINUX SET(PROJECT_HDRS_LINUX

@ -0,0 +1,274 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/**
* This is the source for the DF <-> dfhack shm bridge's core module.
*/
#include <stdio.h>
#include "../library/integers.h"
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include "shms.h"
enum DFPP_CmdType
{
CANCELLATION, // we should jump out of the Act()
CLIENT_WAIT, // we are waiting for the client
FUNCTION, // we call a function as a result of the command
};
struct DFPP_command
{
DFPP_CmdType type:32; // force the enum to 32 bits for compatibility reasons
std::string name;
void (*_function)(void);
};
struct DFPP_module
{
inline void push_command(DFPP_CmdType type, const char * name, void (*_function)(void))
{
DFPP_command cmd;
cmd.type = type;
cmd.name = name;
cmd._function = _function;
commands.push_back(cmd);
}
inline void set_command(unsigned int index, DFPP_CmdType type, const char * name, void (*_function)(void))
{
DFPP_command cmd;
cmd.type = type;
cmd.name = name;
cmd._function = _function;
commands[index] = cmd;
}
inline void reserve (unsigned int numcommands)
{
commands.clear();
DFPP_command cmd = {CANCELLATION,"",0};
commands.resize(numcommands,cmd);
}
std::string name;
uint32_t version; // version
std::vector <DFPP_command> commands;
void * modulestate;
};
std::vector <DFPP_module> module_registry;
// various crud
extern int errorstate;
extern char *shm;
extern int shmid;
#define SHMHDR ((shm_header *)shm)
#define SHMCMD ((shm_cmd *)shm)->pingpong
void GetCoreVersion (void)
{
SHMHDR->value = module_registry[0].version;
full_barrier
SHMCMD = CORE_RET_VERSION;
}
void GetPID (void)
{
SHMHDR->value = OS_getPID();
full_barrier
SHMCMD = CORE_RET_PID;
}
void ReadRaw (void)
{
memcpy(shm + SHM_HEADER, (void *) SHMHDR->address,SHMHDR->length);
full_barrier
SHMCMD = CORE_RET_DATA;
}
void ReadDWord (void)
{
SHMHDR->value = *((uint32_t*) SHMHDR->address);
full_barrier
SHMCMD = CORE_RET_DWORD;
}
void ReadWord (void)
{
SHMHDR->value = *((uint16_t*) SHMHDR->address);
full_barrier
SHMCMD = CORE_RET_WORD;
}
void ReadByte (void)
{
SHMHDR->value = *((uint8_t*) SHMHDR->address);
full_barrier
SHMCMD = CORE_RET_BYTE;
}
void WriteRaw (void)
{
memcpy((void *)SHMHDR->address, shm + SHM_HEADER,SHMHDR->length);
full_barrier
SHMCMD = CORE_SUSPENDED;
}
void WriteDWord (void)
{
(*(uint32_t*)SHMHDR->address) = SHMHDR->value;
full_barrier
SHMCMD = CORE_SUSPENDED;
}
void WriteWord (void)
{
(*(uint16_t*)SHMHDR->address) = SHMHDR->value;
full_barrier
SHMCMD = CORE_SUSPENDED;
}
void WriteByte (void)
{
(*(uint8_t*)SHMHDR->address) = SHMHDR->value;
full_barrier
SHMCMD = CORE_SUSPENDED;
}
void ReadSTLString (void)
{
std::string * myStringPtr = (std::string *) SHMHDR->address;
unsigned int l = myStringPtr->length();
SHMHDR->value = l;
// there doesn't have to be a null terminator!
strncpy(shm+SHM_HEADER,myStringPtr->c_str(),l+1);
full_barrier
SHMCMD = CORE_RET_STRING;
}
void WriteSTLString (void)
{
std::string * myStringPtr = (std::string *) SHMHDR->address;
// here we DO expect a 0 terminator
myStringPtr->assign((const char *) (shm + SHM_HEADER));
full_barrier
SHMCMD = CORE_SUSPENDED;
}
void Suspend (void)
{
SHMCMD = CORE_SUSPENDED;
}
void InitCore(void)
{
DFPP_module core;
core.name = "Core";
core.version = CORE_VERSION;
core.modulestate = 0; // this one is dumb and has no real state
core.reserve(NUM_CORE_CMDS);
core.set_command(CORE_RUNNING, CANCELLATION, "Running", NULL);
core.set_command(CORE_GET_VERSION, FUNCTION,"Get core version",GetCoreVersion);
core.set_command(CORE_RET_VERSION, CLIENT_WAIT,"Core version return",0);
core.set_command(CORE_GET_PID, FUNCTION, "Get PID", GetPID);
core.set_command(CORE_RET_PID, CLIENT_WAIT, "PID return", 0);
core.set_command(CORE_DFPP_READ, FUNCTION,"Raw read",ReadRaw);
core.set_command(CORE_RET_DATA, CLIENT_WAIT,"Raw read return",0);
core.set_command(CORE_READ_DWORD, FUNCTION,"Read DWORD",ReadDWord);
core.set_command(CORE_RET_DWORD, CLIENT_WAIT,"Read DWORD return",0);
core.set_command(CORE_READ_WORD, FUNCTION,"Read WORD",ReadWord);
core.set_command(CORE_RET_WORD, CLIENT_WAIT,"Read WORD return",0);
core.set_command(CORE_READ_BYTE, FUNCTION,"Read BYTE",ReadByte);
core.set_command(CORE_RET_BYTE, CLIENT_WAIT,"Read BYTE return",0);
core.set_command(CORE_SV_ERROR, CANCELLATION, "Server error", 0);
core.set_command(CORE_CL_ERROR, CANCELLATION, "Client error", 0);
core.set_command(CORE_WRITE, FUNCTION, "Raw write", WriteRaw);
core.set_command(CORE_WRITE_DWORD, FUNCTION, "Write DWORD", WriteDWord);
core.set_command(CORE_WRITE_WORD, FUNCTION, "Write WORD", WriteWord);
core.set_command(CORE_WRITE_BYTE, FUNCTION, "Write BYTE", WriteByte);
core.set_command(CORE_SUSPEND, FUNCTION, "Suspend", Suspend);
core.set_command(CORE_SUSPENDED, CLIENT_WAIT, "Suspended", 0);
core.set_command(CORE_READ_STL_STRING, FUNCTION, "Read STL string", ReadSTLString);
core.set_command(CORE_READ_C_STRING, CLIENT_WAIT, "RESERVED", 0);
core.set_command(CORE_RET_STRING, CLIENT_WAIT, "Return string", 0);
core.set_command(CORE_WRITE_STL_STRING, FUNCTION, "Write STL string", WriteSTLString);
module_registry.push_back(core);
}
void InitModules (void)
{
// create the core module
InitCore();
}
void SHM_Act (void)
{
if(errorstate)
{
return;
}
uint32_t numwaits = 0;
check_again: // goto target!!!
if(numwaits == 10000)
{
// this tests if there's a process on the other side
if(isValidSHM())
{
numwaits = 0;
}
else
{
full_barrier
SHMCMD = CORE_RUNNING;
fprintf(stderr,"dfhack: Broke out of loop, other process disappeared.\n");
}
}
DFPP_module & mod = module_registry[((shm_cmd *)shm)->parts.module];
DFPP_command & cmd = mod.commands[((shm_cmd *)shm)->parts.command];
//fprintf(stderr, "Client invoked %s\n", cmd.name.c_str() );
if(cmd._function)
{
cmd._function();
}
if(cmd.type != CANCELLATION)
{
SCHED_YIELD
numwaits ++; // watchdog timeout
goto check_again;
}
}

@ -34,6 +34,8 @@ distribution.
#include <sys/types.h> #include <sys/types.h>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <unistd.h> #include <unistd.h>
#include <vector>
#include <string>
#include "shms.h" #include "shms.h"
#include <sys/time.h> #include <sys/time.h>
#include <time.h> #include <time.h>
@ -62,7 +64,7 @@ bool isValidSHM()
//fprintf(stderr,"ID %d, attached: %d\n",shmid, descriptor.shm_nattch); //fprintf(stderr,"ID %d, attached: %d\n",shmid, descriptor.shm_nattch);
return (descriptor.shm_nattch == 2); return (descriptor.shm_nattch == 2);
} }
uint32_t getPID() uint32_t OS_getPID()
{ {
return getpid(); return getpid();
} }
@ -109,7 +111,8 @@ void SHM_Init ( void )
} }
full_barrier full_barrier
// make sure we don't stall or do crazy stuff // make sure we don't stall or do crazy stuff
((shm_cmd *)shm)->pingpong = DFPP_RUNNING; ((shm_cmd *)shm)->pingpong = CORE_RUNNING;
InitModules();
} }
void SHM_Destroy ( void ) void SHM_Destroy ( void )
@ -144,7 +147,7 @@ DFhackCExport void SDL_GL_SwapBuffers(void)
{ {
if(_SDL_GL_SwapBuffers) if(_SDL_GL_SwapBuffers)
{ {
if(!errorstate && ((shm_cmd *)shm)->pingpong != DFPP_RUNNING) if(!errorstate && ((shm_cmd *)shm)->pingpong != CORE_RUNNING)
{ {
SHM_Act(); SHM_Act();
} }
@ -158,7 +161,7 @@ DFhackCExport int SDL_Flip(void * some_ptr)
{ {
if(_SDL_Flip) if(_SDL_Flip)
{ {
if(!errorstate && ((shm_cmd *)shm)->pingpong != DFPP_RUNNING) if(!errorstate && ((shm_cmd *)shm)->pingpong != CORE_RUNNING)
{ {
SHM_Act(); SHM_Act();
} }
@ -216,7 +219,7 @@ DFhackCExport int refresh (void)
{ {
if(_refresh) if(_refresh)
{ {
if(!errorstate && ((shm_cmd *)shm)->pingpong != DFPP_RUNNING) if(!errorstate && ((shm_cmd *)shm)->pingpong != CORE_RUNNING)
{ {
SHM_Act(); SHM_Act();
} }

@ -1,187 +0,0 @@
/*
www.sourceforge.net/projects/dfhack
Copyright (c) 2009 Petr Mrázek (peterix)
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any
damages arising from the use of this software.
Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product documentation
would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source
distribution.
*/
/**
* This is the source for the DF <-> dfhack shm bridge, server protocol part
*/
#include <stdio.h>
#include "../library/integers.h"
#include <stdlib.h>
#include <string.h>
#include <string>
//#include <unistd.h>
#include "shms.h"
// various crud
extern int errorstate;
extern char *shm;
extern int shmid;
void SHM_Act (void)
{
if(errorstate)
{
return;
}
uint32_t numwaits = 0;
uint32_t length;
uint32_t address;
std::string * myStringPtr;
check_again: // goto target!!!
SCHED_YIELD // yield the CPU, valid only on single-core CPUs
if(numwaits == 10000)
{
// this tests if there's a process on the other side
if(isValidSHM())
{
numwaits = 0;
}
else
{
full_barrier
((shm_cmd *)shm)->pingpong = DFPP_RUNNING;
fprintf(stderr,"dfhack: Broke out of loop, other process disappeared.\n");
//MessageBox(0,"Broke out of loop, other process disappeared.","FUN", MB_OK);
}
}
switch (((shm_cmd *)shm)->pingpong)
{
case DFPP_RET_VERSION:
case DFPP_RET_DATA:
case DFPP_RET_DWORD:
case DFPP_RET_WORD:
case DFPP_RET_BYTE:
case DFPP_RET_STRING:
case DFPP_SUSPENDED:
case DFPP_RET_PID:
case DFPP_SV_ERROR:
numwaits++;
goto check_again;
case DFPP_SUSPEND:
full_barrier
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
goto check_again;
/*
case DFPP_BOUNCE:
length = ((shm_bounce *)shm)->length;
memcpy(BigFat,shm + SHM_HEADER,length);
memcpy(shm + SHM_HEADER,BigFat,length);
((shm_cmd *)shm)->pingpong = DFPP_RET_DATA;
goto check_again;
*/
case DFPP_PID:
((shm_retval *)shm)->value = getPID();
full_barrier
((shm_retval *)shm)->pingpong = DFPP_RET_PID;
goto check_again;
case DFPP_VERSION:
((shm_retval *)shm)->value = PINGPONG_VERSION;
full_barrier
((shm_retval *)shm)->pingpong = DFPP_RET_VERSION;
goto check_again;
case DFPP_READ:
length = ((shm_read *)shm)->length;
address = ((shm_read *)shm)->address;
memcpy(shm + SHM_HEADER, (void *) address,length);
full_barrier
((shm_cmd *)shm)->pingpong = DFPP_RET_DATA;
goto check_again;
case DFPP_READ_DWORD:
address = ((shm_read_small *)shm)->address;
((shm_retval *)shm)->value = *((uint32_t*) address);
full_barrier
((shm_retval *)shm)->pingpong = DFPP_RET_DWORD;
goto check_again;
case DFPP_READ_WORD:
address = ((shm_read_small *)shm)->address;
((shm_retval *)shm)->value = *((uint16_t*) address);
full_barrier
((shm_retval *)shm)->pingpong = DFPP_RET_WORD;
goto check_again;
case DFPP_READ_BYTE:
address = ((shm_read_small *)shm)->address;
((shm_retval *)shm)->value = *((uint8_t*) address);
full_barrier
((shm_retval *)shm)->pingpong = DFPP_RET_BYTE;
goto check_again;
case DFPP_WRITE:
address = ((shm_write *)shm)->address;
length = ((shm_write *)shm)->length;
memcpy((void *)address, shm + SHM_HEADER,length);
full_barrier
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
goto check_again;
case DFPP_WRITE_DWORD:
(*(uint32_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
full_barrier
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
goto check_again;
case DFPP_WRITE_WORD:
(*(uint16_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
full_barrier
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
goto check_again;
case DFPP_WRITE_BYTE:
(*(uint8_t*)((shm_write_small *)shm)->address) = ((shm_write_small *)shm)->value;
full_barrier
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
goto check_again;
case DFPP_CL_ERROR:
case DFPP_RUNNING:
//fprintf(stderr, "no. of waits: %d\n", numwaits);
//MessageBox(0,"Broke out of loop properly","FUN", MB_OK);
break;
case DFPP_READ_STL_STRING:
myStringPtr = (std::string *) ((shm_read_small *)shm)->address;
((shm_retval *)shm)->value = myStringPtr->length();
strncpy(shm+SHM_HEADER,myStringPtr->c_str(),myStringPtr->length()+1);// length + 1 for the null terminator
full_barrier
((shm_retval *)shm)->pingpong = DFPP_RET_STRING;
goto check_again;
case DFPP_WRITE_STL_STRING:
myStringPtr = (std::string *) ((shm_write *)shm)->address;
myStringPtr->assign((const char *) (shm + SHM_HEADER));
full_barrier
((shm_cmd *)shm)->pingpong = DFPP_SUSPENDED;
goto check_again;
default:
((shm_retval *)shm)->value = DFEE_INVALID_COMMAND;
full_barrier
((shm_retval *)shm)->pingpong = DFPP_SV_ERROR;
break;
}
}

@ -34,8 +34,10 @@ distribution.
#define DFhackCExport extern "C" __declspec(dllexport) #define DFhackCExport extern "C" __declspec(dllexport)
#include "../library/integers.h" #include "../library/integers.h"
#include <vector>
#include <string>
#include "shms.h" #include "shms.h"
#include <stdio.h> #include <cstdio>
int errorstate = 0; int errorstate = 0;
char *shm = 0; char *shm = 0;
int shmid = 0; int shmid = 0;
@ -131,8 +133,7 @@ void SHM_Init ( void )
shm = (char *) MapViewOfFile(shmHandle,FILE_MAP_ALL_ACCESS, 0,0, SHM_SIZE); shm = (char *) MapViewOfFile(shmHandle,FILE_MAP_ALL_ACCESS, 0,0, SHM_SIZE);
if(shm) if(shm)
{ {
((shm_cmd *)shm)->pingpong = DFPP_RUNNING; ((shm_cmd *)shm)->pingpong = CORE_RUNNING;
//MessageBox(0,"Sucessfully mapped SHM","FUN", MB_OK);
} }
else else
{ {
@ -142,6 +143,7 @@ void SHM_Init ( void )
CloseHandle(DFSVMutex); CloseHandle(DFSVMutex);
CloseHandle(DFCLMutex); CloseHandle(DFCLMutex);
} }
InitModules();
} }
void SHM_Destroy ( void ) void SHM_Destroy ( void )
@ -153,7 +155,7 @@ void SHM_Destroy ( void )
CloseHandle(DFCLMutex); CloseHandle(DFCLMutex);
} }
uint32_t getPID() uint32_t OS_getPID()
{ {
return GetCurrentProcessId(); return GetCurrentProcessId();
} }
@ -665,7 +667,7 @@ DFhackCExport void SDL_Quit(void)
static void (*_SDL_GL_SwapBuffers)(void) = 0; static void (*_SDL_GL_SwapBuffers)(void) = 0;
DFhackCExport void SDL_GL_SwapBuffers(void) DFhackCExport void SDL_GL_SwapBuffers(void)
{ {
if(!errorstate && ((shm_cmd *)shm)->pingpong != DFPP_RUNNING) if(!errorstate && ((shm_cmd *)shm)->pingpong != CORE_RUNNING)
{ {
SHM_Act(); SHM_Act();
} }
@ -678,7 +680,7 @@ DFhackCExport int SDL_Flip(void * some_ptr)
{ {
if(_SDL_Flip) if(_SDL_Flip)
{ {
if(!errorstate && ((shm_cmd *)shm)->pingpong != DFPP_RUNNING) if(!errorstate && ((shm_cmd *)shm)->pingpong != CORE_RUNNING)
{ {
SHM_Act(); SHM_Act();
} }

@ -1,10 +1,10 @@
#ifndef DFCONNECT_H #ifndef DFCONNECT_H
#define DFCONNECT_H #define DFCONNECT_H
#define PINGPONG_VERSION 2 #define CORE_VERSION 3
#define SHM_KEY 123466 #define SHM_KEY 123466
#define SHM_HEADER 1024 #define SHM_HEADER 1024 // 1kB reserved for a header
#define SHM_BODY 1024*1024 #define SHM_BODY 1024*1024 // 1MB reserved for bulk data transfer
#define SHM_SIZE SHM_HEADER+SHM_BODY #define SHM_SIZE SHM_HEADER+SHM_BODY
@ -32,14 +32,6 @@
#endif #endif
#endif #endif
/*
* read - parameters are address and length
* write - parameters are address, length and the actual data to write
* wait - sent to DF so that it waits for more commands
* end - sent to DF for breaking out of the wait
*/
enum DF_SHM_ERRORSTATE enum DF_SHM_ERRORSTATE
{ {
SHM_OK, // all OK SHM_OK, // all OK
@ -48,51 +40,51 @@ enum DF_SHM_ERRORSTATE
SHM_SECOND_DF // we are a second DF process, can't use SHM at all SHM_SECOND_DF // we are a second DF process, can't use SHM at all
}; };
enum DF_PINGPONG enum CORE_COMMAND
{ {
DFPP_RUNNING = 0, // no command, normal server execution CORE_RUNNING = 0, // no command, normal server execution
DFPP_VERSION, // protocol version query CORE_GET_VERSION, // protocol version query
DFPP_RET_VERSION, // return the protocol version CORE_RET_VERSION, // return the protocol version
DFPP_PID, // query for the process ID CORE_GET_PID, // query for the process ID
DFPP_RET_PID, // return process ID CORE_RET_PID, // return process ID
// version 1 stuff below // version 1 stuff below
DFPP_READ, // cl -> sv, read some data CORE_DFPP_READ, // cl -> sv, read some data
DFPP_RET_DATA, // sv -> cl, returned data CORE_RET_DATA, // sv -> cl, returned data
DFPP_READ_DWORD, // cl -> sv, read a dword CORE_READ_DWORD, // cl -> sv, read a dword
DFPP_RET_DWORD, // sv -> cl, returned dword CORE_RET_DWORD, // sv -> cl, returned dword
DFPP_READ_WORD, // cl -> sv, read a word CORE_READ_WORD, // cl -> sv, read a word
DFPP_RET_WORD, // sv -> cl, returned word CORE_RET_WORD, // sv -> cl, returned word
DFPP_READ_BYTE, // cl -> sv, read a byte CORE_READ_BYTE, // cl -> sv, read a byte
DFPP_RET_BYTE, // sv -> cl, returned byte CORE_RET_BYTE, // sv -> cl, returned byte
DFPP_SV_ERROR, // there was a server error CORE_SV_ERROR, // there was a server error
DFPP_CL_ERROR, // there was a client error CORE_CL_ERROR, // there was a client error
DFPP_WRITE,// client writes to server CORE_WRITE,// client writes to server
DFPP_WRITE_DWORD,// client writes a DWORD to server CORE_WRITE_DWORD,// client writes a DWORD to server
DFPP_WRITE_WORD,// client writes a WORD to server CORE_WRITE_WORD,// client writes a WORD to server
DFPP_WRITE_BYTE,// client writes a BYTE to server CORE_WRITE_BYTE,// client writes a BYTE to server
DFPP_SUSPEND, // client notifies server to wait for commands (server is stalled in busy wait) CORE_SUSPEND, // client notifies server to wait for commands (server is stalled in busy wait)
DFPP_SUSPENDED, // response to WAIT, server is stalled in busy wait CORE_SUSPENDED, // response to WAIT, server is stalled in busy wait
// all strings capped at 1MB // all strings capped at 1MB
DFPP_READ_STL_STRING,// client requests contents of STL string at address CORE_READ_STL_STRING,// client requests contents of STL string at address
DFPP_READ_C_STRING,// client requests contents of a C string at address, max length (0 means zero terminated) CORE_READ_C_STRING,// client requests contents of a C string at address, max length (0 means zero terminated)
DFPP_RET_STRING, // sv -> cl length + string contents CORE_RET_STRING, // sv -> cl length + string contents
DFPP_WRITE_STL_STRING,// client wants to set STL string at address to something CORE_WRITE_STL_STRING,// client wants to set STL string at address to something
// vector elements > 1MB are not supported because they don't fit into the shared memory // compare affinity and determine if using yield is required
DFPP_READ_ENTIRE_VECTOR, // read an entire vector (parameters are address of vector object and size of items) CORE_SYNC_YIELD,// cl sends affinity to sv, sv sets yield
DFPP_RET_VECTOR_BODY, // a part of a vector is returned - no. of elements returned, no. of elements total, elements CORE_SYNC_YIELD_RET,// sv returns yield bool
NUM_DFPP NUM_CORE_CMDS
}; };
@ -102,54 +94,31 @@ enum DF_ERROR
DFEE_BUFFER_OVERFLOW DFEE_BUFFER_OVERFLOW
}; };
typedef struct typedef union
{
volatile uint32_t pingpong; // = 0
} shm_cmd;
typedef struct
{
volatile uint32_t pingpong;
uint32_t address;
uint32_t length;
} shm_read;
typedef shm_read shm_write;
typedef shm_read shm_bounce;
typedef struct
{ {
struct
{
volatile uint16_t command;
volatile uint16_t module;
} parts;
volatile uint32_t pingpong; volatile uint32_t pingpong;
} shm_ret_data; inline void set(uint16_t module, uint16_t command)
{
typedef struct pingpong = module + command << 16;
{ }
volatile uint32_t pingpong; } shm_cmd;
uint32_t address;
} shm_read_small;
typedef struct typedef struct
{ {
volatile uint32_t pingpong; shm_cmd cmd;
uint32_t address; uint32_t address;
uint32_t value; uint32_t value;
} shm_write_small;
typedef struct
{
volatile uint32_t pingpong;
uint32_t value;
} shm_retval;
typedef struct
{
volatile uint32_t pingpong;
uint32_t length; uint32_t length;
} shm_retstr; } shm_header;
void SHM_Act (void); void SHM_Act (void);
void InitModules (void);
bool isValidSHM(); bool isValidSHM();
uint32_t getPID(); uint32_t OS_getPID();
#endif #endif