#ifndef DFCONNECT_H #define DFCONNECT_H #define SHM_KEY 123466 #define SHM_MAX_CLIENTS 4 #define SHM_HEADER 1024 // 1kB reserved for a header #define SHM_BODY 1024*1024 // 4MB reserved for bulk data transfer #define SHM_SIZE SHM_HEADER+SHM_BODY //#define SHM_ALL_CLIENTS SHM_MAX_CLIENTS*(SHM_SIZE) //#define SHM_CL(client_idx) client_idx*(SHM_SIZE) // FIXME: add YIELD for linux, add single-core and multi-core compile targets for optimal speed #ifdef LINUX_BUILD // a full memory barrier! better be safe than sorry. #define full_barrier asm volatile("" ::: "memory"); __sync_synchronize(); #define SCHED_YIELD sched_yield(); // a requirement for single-core #else // we need windows.h for Sleep() #define _WIN32_WINNT 0x0501 // needed for INPUT struct #define WINVER 0x0501 // OpenThread(), PSAPI, Toolhelp32 #define WIN32_LEAN_AND_MEAN #include #define SCHED_YIELD Sleep(0); // avoids infinite lockup on single core // FIXME: detect MSVC here and use the right barrier magic #ifdef __MINGW32__ #define full_barrier asm volatile("" ::: "memory"); #else #include #pragma intrinsic(_ReadWriteBarrier) #define full_barrier _ReadWriteBarrier(); #endif #endif enum DFPP_Locking { LOCKING_BUSY = 0, LOCKING_LOCKS = 1 }; 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 { void (*_function)(void *); DFPP_CmdType type:32; // force the enum to 32 bits for compatibility reasons std::string name; uint32_t nextState; DFPP_Locking locking; }; struct DFPP_module { DFPP_module() { name = "Uninitialized module"; version = 0; modulestate = 0; } // ALERT: the structures share state DFPP_module(const DFPP_module & orig) { commands = orig.commands; name = orig.name; modulestate = orig.modulestate; version = orig.version; } inline void set_command(const unsigned int index, const DFPP_CmdType type, const char * name, void (*_function)(void *) = 0,uint32_t nextState = -1, DFPP_Locking locking = LOCKING_BUSY) { commands[index].type = type; commands[index].name = name; commands[index]._function = _function; commands[index].nextState = nextState; commands[index].locking = locking; } inline void reserve (unsigned int numcommands) { commands.clear(); DFPP_command cmd = {0,CANCELLATION,"",0}; commands.resize(numcommands,cmd); } std::string name; uint32_t version; // version std::vector commands; void * modulestate; }; union shm_cmd { struct { volatile uint16_t command; volatile uint16_t module; } parts; volatile uint32_t pingpong; shm_cmd(volatile uint32_t z) { pingpong = z; } }; void SHM_Act (void); void InitModules (void); void KillModules (void); bool isValidSHM(int current); uint32_t OS_getPID(); uint32_t OS_getAffinity(); // limited to 32 processors. Silly, eh? void OS_releaseSuspendLock(int currentClient); void OS_lockSuspendLock(int currentClient); #endif