in progress with integratign new shm in multi

This commit is contained in:
maliakal_d 2018-06-12 12:14:55 +02:00
parent bab7d8e3fb
commit b294b3e8b1
7 changed files with 1471 additions and 945 deletions

View File

@ -9,15 +9,15 @@ CFLAGS= -g -DC_ONLY -fPIC
DFLAGS= -g -DDACS_INT DFLAGS= -g -DDACS_INT
INCLUDES?= -IcommonFiles -IslsDetector -I../slsReceiverSoftware/MySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis -IslsReceiverInterface -I../slsReceiverSoftware/include -IthreadFiles -I$(ASM) INCLUDES?= -IcommonFiles -IslsDetector -I../slsReceiverSoftware/MySocketTCP -IusersFunctions -ImultiSlsDetector -IslsDetectorUtils -IslsDetectorCommand -IslsDetectorAnalysis -IslsReceiverInterface -I../slsReceiverSoftware/include -IthreadFiles -IsharedMemory-I$(ASM)
#EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -Wl,-R/usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -lca -lCom #EPICSFLAGS=-D EPICS -I/usr/local/epics/base/include/ -I /usr/local/epics/base/include/os/Linux/ -L /usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -Wl,-R/usr/local/epics/base/lib/$(EPICS_HOST_ARCH) -lca -lCom
LIBZMQDIR = ../slsReceiverSoftware/include LIBZMQDIR = ../slsReceiverSoftware/include
LIBZMQ = -L$(LIBZMQDIR) -Wl,-rpath=$(LIBZMQDIR) -lzmq LIBZMQ = -L$(LIBZMQDIR) -Wl,-rpath=$(LIBZMQDIR) -lzmq
SRC_CLNT=slsDetectorAnalysis/fileIO.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp slsDetectorAnalysis/postProcessingFuncs.cpp slsReceiverInterface/receiverInterface.cpp slsDetector/slsDetectorUsers.cpp threadFiles/CondVar.cpp threadFiles/Mutex.cpp threadFiles/ThreadPool.cpp #../slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp SRC_CLNT=slsDetectorAnalysis/fileIO.cpp usersFunctions/usersFunctions.cpp slsDetector/slsDetectorUtils.cpp slsDetector/slsDetectorCommand.cpp slsDetectorAnalysis/angularConversion.cpp slsDetectorAnalysis/angularConversionStatic.cpp slsDetectorAnalysis/energyConversion.cpp slsDetector/slsDetectorActions.cpp slsDetectorAnalysis/postProcessing.cpp slsDetector/slsDetector.cpp multiSlsDetector/multiSlsDetector.cpp slsDetectorAnalysis/postProcessingFuncs.cpp slsReceiverInterface/receiverInterface.cpp slsDetector/slsDetectorUsers.cpp threadFiles/CondVar.cpp threadFiles/Mutex.cpp threadFiles/ThreadPool.cpp sharedMemory/SharedMemory.cpp #../slsReceiverSoftware/MySocketTCP/MySocketTCP.cpp
DEPSINCLUDES = $(LIBZMQDIR)/sls_receiver_defs.h $(LIBZMQDIR)/sls_receiver_funcs.h $(LIBZMQDIR)/ansi.h commonFiles/sls_detector_defs.h commonFiles/sls_detector_funcs.h commonFiles/error_defs.h slsDetector/slsDetectorBase.h slsDetectorAnalysis/angCalLogClass.h slsDetectorAnalysis/angleConversionConstant.h slsDetectorAnalysis/badChannelCorrections.h slsDetectorAnalysis/detectorData.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/fileIOStatic.h slsDetectorAnalysis/movingStat.h slsDetectorAnalysis/runningStat.h slsDetectorAnalysis/single_photon_hit.h threadFiles/Global.h threadFiles/Task.h usersFunctions/angleFunction.h DEPSINCLUDES = $(LIBZMQDIR)/sls_receiver_defs.h $(LIBZMQDIR)/sls_receiver_funcs.h $(LIBZMQDIR)/ansi.h commonFiles/sls_detector_defs.h commonFiles/sls_detector_funcs.h commonFiles/error_defs.h slsDetector/slsDetectorBase.h slsDetectorAnalysis/angCalLogClass.h slsDetectorAnalysis/angleConversionConstant.h slsDetectorAnalysis/badChannelCorrections.h slsDetectorAnalysis/detectorData.h slsDetectorAnalysis/enCalLogClass.h slsDetectorAnalysis/fileIOStatic.h slsDetectorAnalysis/movingStat.h slsDetectorAnalysis/runningStat.h slsDetectorAnalysis/single_photon_hit.h threadFiles/Global.h threadFiles/Task.h usersFunctions/angleFunction.h sharedMemory/sharedMemory.h commonFiles/sls_detector_exceptions.h

View File

@ -0,0 +1,19 @@
#pragma once
/************************************************
* @file sls_detector_exceptions.h
* @short exceptions defined
***********************************************/
/**
*@short exceptions defined
*/
#include <iostream>
#include <exception>
using namespace std;
struct SharedMemoryException : public exception {
public:
SharedMemoryException() {}
string GetMessage() const { return "Shared Memory Failed";};
};//shmException;

View File

@ -9,84 +9,331 @@ ID: $Id$
********************************************************************/ ********************************************************************/
#include "multiSlsDetector.h" #include "multiSlsDetector.h"
#include "SharedMemory.h"
#include "slsDetector.h"
#include "sls_detector_exceptions.h"
#include "ThreadPool.h" #include "ThreadPool.h"
#include "ZmqSocket.h" #include "ZmqSocket.h"
#include "multiSlsDetectorClient.h" #include "multiSlsDetectorClient.h"
#include "multiSlsDetectorCommand.h" #include "multiSlsDetectorCommand.h"
#include "postProcessingFuncs.h" #include "postProcessingFuncs.h"
#include "slsDetector.h"
#include "usersFunctions.h" #include "usersFunctions.h"
#include <sys/types.h>
#include <iostream> #include <iostream>
#include <string.h>
#include <sstream>
#include <rapidjson/document.h> //json header in zmq stream #include <rapidjson/document.h> //json header in zmq stream
#include <string>
#include <sys/ipc.h> #include <sys/ipc.h>
#include <sys/shm.h> #include <sys/shm.h>
#include <sys/types.h>
#include <vector>
// char ans[MAX_STR_LENGTH];
int multiSlsDetector::freeSharedMemory()
multiSlsDetector::multiSlsDetector(int id, bool verify, bool update)
: slsDetectorUtils(),
detId(id),
sharedMemory(0),
thisMultiDetector(0),
client_downstream(false),
threadpool(0)
{ {
// Detach Memory address bool created = initSharedMemory(verify, update);
for (int id = 0; id < thisMultiDetector->numberOfDetectors; ++id) { initializeDetectorStructure(created, verify, update);
if (detectors[id])
detectors[id]->freeSharedMemory(); getNMods();
getMaxMods();
if (createThreadPool() == FAIL)
exit(-1);
} }
if (shmdt(thisMultiDetector) == -1) {
perror("shmdt failed\n");
return FAIL; multiSlsDetector::~multiSlsDetector(){
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
delete(*it);
} }
#ifdef VERBOSE detectors.clear();
printf("Shared memory %d detached\n", shmId);
#endif if (sharedMemory) {
// remove shared memory sharedMemory->UnmapSharedMemory(thisMultiDetector);
if (shmctl(shmId, IPC_RMID, 0) == -1) { delete sharedMemory;
perror("shmctl(IPC_RMID) failed\n");
return FAIL;
}
printf("Shared memory %d deleted\n", shmId);
return OK;
} }
int multiSlsDetector::initSharedMemory(int id = 0) for (int i = 0; i < MAXDET; ++i) {
{ if (zmqSocket[i]) {
delete zmqSocket[i];
key_t mem_key = DEFAULT_SHM_KEY + MAXDET + id; }
int shm_id; }
int sz; destroyThreadPool();
sz = sizeof(sharedMultiSlsDetector);
#ifdef VERBOSE
std::cout << "multiSlsDetector: Size of shared memory is " << sz << " - id " << mem_key << std::endl;
#endif
shm_id = shmget(mem_key, sz, IPC_CREAT | 0666); // allocate shared memory
if (shm_id < 0) {
std::cout << "*** shmget error (server) ***" << shm_id << std::endl;
return shm_id;
} }
/** slsDetector* multiSlsDetector::getSlsDetector(unsigned int pos) {
thisMultiDetector pointer is set to the memory address of the shared memory if (pos >= 0 && pos < detectors.size()) {
*/ return detectors[pos];
thisMultiDetector = (sharedMultiSlsDetector*)shmat(shm_id, NULL, 0); /* attach */
if (thisMultiDetector == (void*)-1) {
std::cout << "*** shmat error (server) ***" << std::endl;
return shm_id;
} }
/** return 0;
shm_id returns -1 is shared memory initialization fails
*/
return shm_id;
} }
void multiSlsDetector::freeSharedMemory(int multiId) {
// get number of detectors
int numDetectors = 0;
SharedMemory* shm = new SharedMemory(multiId, -1);
std::string shmname = shm->GetName();
// shm not created before
if (SharedMemory::IsExisting(shmname)) {
sharedMultiDet* mdet = (sharedMultiSlsDetector*)shm->OpenSharedMemory(
sizeof(sharedMultiSlsDetector), false);
numDetectors = mdet->numberOfDetectors;
shm->UnmapSharedMemory(mdet);
shm->RemoveSharedMemory();
}
delete shm;
for (int i = 0; i < numDetectors; ++i) {
SharedMemory* shm = new SharedMemory(multiId, i);
shm->RemoveSharedMemory();
delete shm;
}
}
void multiSlsDetector::freeSharedMemory() {
// single detector vector
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
(*it)->freeSharedMemory();
delete (*it);
}
detectors.clear();
// multi detector
if (sharedMemory) {
sharedMemory->RemoveSharedMemory();
delete sharedMemory;
}
thisMultiDetector = 0;
}
std::string multiSlsDetector::getUserDetails() {
std::ostringstream sstream;
if (!detectors.size()) {
return std::string("none");
}
//hostname
sstream << "\nHostname: " << getHostname();
//type
sstream<< "\nType: ";
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it)
sstream<< (*it)->sgetDetectorsType() << "+"; /*change funtion signature without argument*/
//PID
sstream << "\nPID: " << thisMultiDetector->lastPID
//user
<< "\nUser: " << thisMultiDetector->lastUser
<< "\nDate: " << thisMultiDetector->lastDate << endl;
string s = sstream.str();
return s;
}
bool multiSlsDetector::initSharedMemory(bool verify, bool update) {
// clear
if (sharedMemory)
delete sharedMemory;
thisMultiDetector = 0;
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
delete(*it);
}
detectors.clear();
// create/open shm and map to structure
size_t sz = sizeof(sharedMultiSlsDetector);
bool created = false;
sharedMemory = new SharedMemory(detId, -1);
if (SharedMemory::IsExisting(sharedMemory->GetName())) {
thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->OpenSharedMemory(sz, verify);
if (verify && thisMultiDetector->shmversion != MULTI_SHMVERSION) {
cprintf(RED, "Multi shared memory version mismatch "
"(expected 0x%x but got 0x%x)\n",
MULTI_SHMVERSION, thisMultiDetector->shmversion);
throw SharedMemoryException();
}
} else {
try {
thisMultiDetector = (sharedMultiSlsDetector*)sharedMemory->CreateSharedMemory(sz);
created = true;
} catch(...) {
sharedMemory->RemoveSharedMemory();
thisMultiDetector = 0;
throw;
}
}
return created;
}
void multiSlsDetector::initializeDetectorStructure(bool created, bool verify, bool update) {
// set up new structure
if (created) {
thisMultiDetector->shmversion = MULTI_SHMVERSION;
thisMultiDetector->numberOfDetectors = 0;
thisMultiDetector->numberOfDetector[X] = 0;
thisMultiDetector->numberOfDetector[Y] = 0;
thisMultiDetector->onlineFlag = 1;
stoppedFlag = 0;
masterPosition = -1;
syncMode;
dataBytes = 0;
dataBytesInclGapPixels = 0;
numberOfChannels = 0;
numberOfChannel[X] = 0;
numberOfChannel[Y] = 0;
numberOfChannelInclGapPixels[X] = 0;
numberOfChannelInclGapPixels[Y] = 0;
maxNumberOfChannels = 0;
maxNumberOfChannel[X] = 0;
maxNumberOfChannel[Y] = 0;
maxNumberOfChannelInclGapPixels[X] = 0;
maxNumberOfChannelInclGapPixels[Y] = 0;
maxNumberOfChannelsPerDetector[X] = 0;
maxNumberOfChannelsPerDetector[Y] = 0;
int64_t timerValue[MAX_TIMERS];
detectorSettings currentSettings;
currentThresholdEV;
progressIndex = 0;
totalProgress = 1;
fileIndex = 0;
strncpy(thisMultiDetector->fileName, "run", MAX_STR_LENGTH);
strncpy(thisMultiDetector->filePath, "/", MAX_STR_LENGTH);
framesPerFile = 1;
fileFormat fileFormatType = ASCII;
correctionMask = (1 << WRITE_FILE) | (1 << OVERWRITE_FILE);
threadedProcessing;
tDead = 0;
strncpy(flatFieldDir, getenv("HOME"), MAX_STR_LENGTH);
strncpy(flatFieldFile, "none", MAX_STR_LENGTH);
strncpy(thisMultiDetector->badChanFile, "none", MAX_STR_LENGTH);
angConvFile[MAX_STR_LENGTH];
angDirection;
fineOffset;
globalOffset;
binSize;
sampleDisplacement[2];
numberOfPositions;
detPositions[MAXPOS];
actionMask;
mystring actionScript[MAX_ACTIONS];
mystring actionParameter[MAX_ACTIONS];
scanMode[MAX_SCAN_LEVELS];
mystring scanScript[MAX_SCAN_LEVELS];
mystring scanParameter[MAX_SCAN_LEVELS];
nScanSteps[MAX_SCAN_LEVELS];
mysteps scanSteps[MAX_SCAN_LEVELS];
scanPrecision[MAX_SCAN_LEVELS];
acquiringFlag;
externalgui;
receiverOnlineFlag;
receiver_upstream;
}
// get objects from single det shared memory (open)
for (int i = 0; i < thisMultiDetector->numberOfDetectors; i++) {
slsDetector* sdet = new slsDetector(detId, i, verify, this);
detectors.push_back(sdet);
}
//update user details
if (update) {
thisMultiDetector->lastPID = getpid();
memset(thisMultiDetector->lastUser, 0, SHORT_STRING_LENGTH);
memset(thisMultiDetector->lastDate, 0, SHORT_STRING_LENGTH);
try {
strncpy(thisMultiDetector->lastUser, exec("whoami").c_str(), SHORT_STRING_LENGTH);
strncpy(thisMultiDetector->lastDate, exec("date").c_str(), DATE_LENGTH);
} catch(...) {
strncpy(thisMultiDetector->lastUser, exec("errorreading").c_str(), SHORT_STRING_LENGTH);
strncpy(thisMultiDetector->lastDate, exec("errorreading").c_str(), SHORT_STRING_LENGTH);
}
}
}
void multiSlsDetector::AddSingleDetector (std::string s) {
cout << "Adding detector " << s << endl;
for (vector<slsDetector*>::const_iterator it = detectors.begin(); it != detectors.end(); ++it) {
if ((*it)->GetHostname() == s) {
cout << "Detector " << s << "already part of the multiDetector!" << endl
<< "Remove it before adding it back in a new position!" << endl;
return;
}
}
//check entire shared memory if it doesnt exist?? needed?
//could be that detectors not loaded completely cuz of crash in new slsdetector in initsharedmemory
// get type by connecting
detectorType type = slsDetector::GetDetectorTypeFromDetector(s, DEFAULT_PORTNO);
if (type == GENERIC) {
cout << "Detector " << s << "does not exist in shared memory "
"and could not connect to it to determine the type!" << endl;
setErrorMask(getErrorMask() | MULTI_DETECTORS_NOT_ADDED);
appendNotAddedList(name);
return;
}
int pos = detectors.size();
slsDetector* sdet = new slsDetector(type, detId, pos, false, this);
detectors.push_back(sdet);
detectors[pos]->SetHostname(s);
detectors[pos]->SetOnline(1);
++thisMultiDetector->numberOfDetectors;
}
std::string multiSlsDetector::exec(const char* cmd) {
int bufsize = 1char buffer[bufsize];
std::string result = "";
FILE* pipe = popen(cmd, "r");
if (!pipe) throw std::exception();
try {
while (!feof(pipe)) {
if (fgets(buffer, bufsize, pipe) != NULL)
result += buffer;
}
} catch (...) {
pclose(pipe);
throw;
}
pclose(pipe);
result.erase(result.find_last_not_of(" \t\n\r")+1);
return result;
}
multiSlsDetector::multiSlsDetector(int id) multiSlsDetector::multiSlsDetector(int id)
: slsDetectorUtils() : slsDetectorUtils()
, shmId(-1) , shmId(-1)
@ -103,57 +350,14 @@ multiSlsDetector::multiSlsDetector(int id)
} }
if (thisMultiDetector->alreadyExisting == 0) { if (thisMultiDetector->alreadyExisting == 0) {
thisMultiDetector->onlineFlag = ONLINE_FLAG;
thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG; thisMultiDetector->receiverOnlineFlag = OFFLINE_FLAG;
thisMultiDetector->numberOfDetectors = 0;
thisMultiDetector->numberOfDetector[X] = 0;
thisMultiDetector->numberOfDetector[Y] = 0;
for (int id = 0; id < MAXDET; ++id) {
thisMultiDetector->detectorIds[id] = -1;
thisMultiDetector->offsetX[id] = 0;
thisMultiDetector->offsetY[id] = 0;
}
thisMultiDetector->masterPosition = -1;
thisMultiDetector->dataBytes = 0;
thisMultiDetector->dataBytesInclGapPixels = 0;
thisMultiDetector->numberOfChannels = 0;
thisMultiDetector->numberOfChannel[X] = 0;
thisMultiDetector->numberOfChannel[Y] = 0;
thisMultiDetector->numberOfChannelInclGapPixels[X] = 0;
thisMultiDetector->numberOfChannelInclGapPixels[Y] = 0;
thisMultiDetector->maxNumberOfChannels = 0;
thisMultiDetector->maxNumberOfChannel[X] = 0;
thisMultiDetector->maxNumberOfChannel[Y] = 0;
thisMultiDetector->maxNumberOfChannelInclGapPixels[X] = 0;
thisMultiDetector->maxNumberOfChannelInclGapPixels[Y] = 0;
thisMultiDetector->maxNumberOfChannelsPerDetector[X] = -1;
thisMultiDetector->maxNumberOfChannelsPerDetector[Y] = -1;
/** set trimDsdir, calDir and filePath to default to root directory*/
strcpy(thisMultiDetector->filePath, "/");
/** set fileName to default to run*/
strcpy(thisMultiDetector->fileName, "run");
/** set fileIndex to default to 0*/
thisMultiDetector->fileIndex = 0;
/** set frames per file to default to 1*/
thisMultiDetector->framesPerFile = 1;
/** set fileFormat to default to ascii*/
thisMultiDetector->fileFormatType = ASCII;
/** set progress Index to default to 0*/
thisMultiDetector->progressIndex = 0;
/** set total number of frames to be acquired to default to 1*/
thisMultiDetector->totalProgress = 1;
/** set correction mask to 0*/
thisMultiDetector->correctionMask = 1 << WRITE_FILE;
thisMultiDetector->correctionMask |= (1 << OVERWRITE_FILE);
/** set deat time*/
thisMultiDetector->tDead = 0;
/** sets bad channel list file to none */
strcpy(thisMultiDetector->badChanFile, "none");
/** sets flat field correction directory */ /** sets flat field correction directory */
strcpy(thisMultiDetector->flatFieldDir, getenv("HOME")); strcpy(thisMultiDetector->flatFieldDir, getenv("HOME"));
/** sets flat field correction file */ /** sets flat field correction file */
@ -175,7 +379,7 @@ multiSlsDetector::multiSlsDetector(int id)
strcpy(thisMultiDetector->angConvFile, "none"); strcpy(thisMultiDetector->angConvFile, "none");
/** set binsize*/ /** set binsize*/
thisMultiDetector->binSize = 0.001; thisMultiDetector->binSize = 0.001;
thisMultiDetector->stoppedFlag = 0;
thisMultiDetector->threadedProcessing = 1; thisMultiDetector->threadedProcessing = 1;

View File

@ -14,70 +14,62 @@ ID: $Id$
#define MULTI_SLS_DETECTOR_H #define MULTI_SLS_DETECTOR_H
#include "slsDetectorUtils.h" #include "slsDetectorUtils.h"
class slsDetector; class slsDetector;
class SharedMemory;
class ThreadPool; class ThreadPool;
class ZmqSocket; class ZmqSocket;
//#include "sls_detector_defs.h"
#include <vector>
#include <string>
#define MULTI_SHMVERSION 0x180608
#define SHORT_STRING_LENGTH 50
#define DATE_LENGTH 29
/** /**
*
*
@libdoc The multiSlsDetector class is used to operate several slsDetectors in parallel. @libdoc The multiSlsDetector class is used to operate several slsDetectors in parallel.
*
* @short This is the base class for multi detector system functionalities * @short This is the base class for multi detector system functionalities
* @author Anna Bergamaschi * @author Anna Bergamaschi
* @version 0.1alpha
*/ */
class multiSlsDetector : public slsDetectorUtils { class multiSlsDetector : public slsDetectorUtils {
//public virtual slsDetectorUtils {
typedef struct sharedMultiSlsDetector { typedef struct sharedMultiSlsDetector {
/* FIXED PATTERN FOR STATIC FUNCTIONS. DO NOT CHANGE, ONLY APPEND ------*/
/** shared memory version */
/** already existing flag. If the detector does not yet exist (alreadyExisting=0) the sharedMemory will be created, otherwise it will simly be linked */ int shmversion;
int alreadyExisting;
/** last process id accessing the shared memory */ /** last process id accessing the shared memory */
pid_t lastPID; pid_t lastPID;
/** last user name accessing the shared memory */
char lastUser[SHORT_STRING_LENGTH];
/** online flag - is set if the detector is connected, unset if socket connection is not possible */ /** last time stamp when accessing the shared memory */
int onlineFlag; char lastDate[SHORT_STRING_LENGTH];
/** number of sls detectors in shared memory */
/** stopped flag - is set if an acquisition error occurs or the detector is stopped manually. Is reset to 0 at the start of the acquisition */
int stoppedFlag;
/** Number of detectors operated at once */
int numberOfDetectors; int numberOfDetectors;
/** END OF FIXED PATTERN -----------------------------------------------*/
/** Number of detectors operated at once */ /** Number of detectors operated at once */
int numberOfDetector[2]; int numberOfDetector[2];
/** Ids of the detectors to be operated at once */ /** online flag - is set if the detector is connected, unset if socket connection is not possible */
int detectorIds[MAXDET]; int onlineFlag;
/** stopped flag - is set if an acquisition error occurs or the detector is stopped manually. Is reset to 0 at the start of the acquisition */
/** Detectors offset in the X direction (in number of channels)*/ int stoppedFlag;
int offsetX[MAXDET];
/** Detectors offsets in the Y direction (in number of channels) */
int offsetY[MAXDET];
/** position of the master detector */ /** position of the master detector */
int masterPosition; int masterPosition;
@ -87,10 +79,10 @@ class multiSlsDetector : public slsDetectorUtils {
/** size of the data that are transfered from all detectors */ /** size of the data that are transfered from all detectors */
int dataBytes; int dataBytes;
/** data bytes including gap pixels transferred from all detectors */ /** data bytes including gap pixels transferred from all detectors */
int dataBytesInclGapPixels; int dataBytesInclGapPixels;
/** total number of channels for all detectors */ /** total number of channels for all detectors */
int numberOfChannels; int numberOfChannels;
@ -113,93 +105,82 @@ class multiSlsDetector : public slsDetectorUtils {
int maxNumberOfChannelsPerDetector[2]; int maxNumberOfChannelsPerDetector[2];
/** timer values */ /** timer values */
int64_t timerValue[MAX_TIMERS]; // needed?!?!?!? int64_t timerValue[MAX_TIMERS];
/** detector settings (standard, fast, etc.) */ /** detector settings (standard, fast, etc.) */
detectorSettings currentSettings; // needed?!?!?!? detectorSettings currentSettings;
/** detector threshold (eV) */
int currentThresholdEV; // needed?!?!?!?
/** detector threshold (eV) */
int currentThresholdEV;
/** indicator for the acquisition progress - set to 0 at the beginning of the acquisition and incremented every time that the data are written to file */ /** indicator for the acquisition progress - set to 0 at the beginning of the acquisition and incremented every time that the data are written to file */
int progressIndex; int progressIndex;
/** total number of frames to be acquired */ /** total number of frames to be acquired */
int totalProgress; int totalProgress;
/** current index of the output file */ /** current index of the output file */
int fileIndex; int fileIndex;
/** name root of the output files */ /** name root of the output files */
char fileName[MAX_STR_LENGTH]; char fileName[MAX_STR_LENGTH];
/** path of the output files */ /** path of the output files */
char filePath[MAX_STR_LENGTH]; char filePath[MAX_STR_LENGTH];
/** max frames per file */ /** max frames per file */
int framesPerFile; int framesPerFile;
/** file format*/ /** file format*/
fileFormat fileFormatType; fileFormat fileFormatType;
/** corrections to be applied to the data \see ::correctionFlags */ /** corrections to be applied to the data \see ::correctionFlags */
int correctionMask; int correctionMask;
/** threaded processing flag (i.e. if data are processed and written to file in a separate thread) */ /** threaded processing flag (i.e. if data are processed and written to file in a separate thread) */
int threadedProcessing; int threadedProcessing;
/** dead time (in ns) for rate corrections */ /** dead time (in ns) for rate corrections */
double tDead; double tDead;
/** directory where the flat field files are stored */ /** directory where the flat field files are stored */
char flatFieldDir[MAX_STR_LENGTH]; char flatFieldDir[MAX_STR_LENGTH];
/** file used for flat field corrections */ /** file used for flat field corrections */
char flatFieldFile[MAX_STR_LENGTH]; char flatFieldFile[MAX_STR_LENGTH];
/** file with the bad channels */ /** file with the bad channels */
char badChanFile[MAX_STR_LENGTH]; char badChanFile[MAX_STR_LENGTH];
/** angular conversion file */ /** angular conversion file */
char angConvFile[MAX_STR_LENGTH]; char angConvFile[MAX_STR_LENGTH];
/** array of angular conversion constants for each module \see ::angleConversionConstant */
//angleConversionConstant angOff[MAXMODS];
/** angular direction (1 if it corresponds to the encoder direction i.e. channel 0 is 0, maxchan is positive high angle, 0 otherwise */ /** angular direction (1 if it corresponds to the encoder direction i.e. channel 0 is 0, maxchan is positive high angle, 0 otherwise */
int angDirection; int angDirection;
/** beamline fine offset (of the order of mdeg, might be adjusted for each measurements) */ /** beamline fine offset (of the order of mdeg, might be adjusted for each measurements) */
double fineOffset; double fineOffset;
/** beamline offset (might be a few degrees beacuse of encoder offset - normally it is kept fixed for a long period of time) */ /** beamline offset (might be a few degrees beacuse of encoder offset - normally it is kept fixed for a long period of time) */
double globalOffset; double globalOffset;
/** bin size for data merging */ /** bin size for data merging */
double binSize; double binSize;
//X and Y displacement //X and Y displacement
double sampleDisplacement[2]; double sampleDisplacement[2];
/** number of positions at which the detector should acquire */ /** number of positions at which the detector should acquire */
int numberOfPositions; int numberOfPositions;
/** list of encoder positions at which the detector should acquire */ /** list of encoder positions at which the detector should acquire */
double detPositions[MAXPOS]; double detPositions[MAXPOS];
/** Scans and scripts */ /** Scans and scripts */
int actionMask; int actionMask;
//int actionMode[MAX_ACTIONS];
mystring actionScript[MAX_ACTIONS]; mystring actionScript[MAX_ACTIONS];
mystring actionParameter[MAX_ACTIONS]; mystring actionParameter[MAX_ACTIONS];
int scanMode[MAX_SCAN_LEVELS]; int scanMode[MAX_SCAN_LEVELS];
mystring scanScript[MAX_SCAN_LEVELS]; mystring scanScript[MAX_SCAN_LEVELS];
mystring scanParameter[MAX_SCAN_LEVELS]; mystring scanParameter[MAX_SCAN_LEVELS];
@ -224,18 +205,6 @@ class multiSlsDetector : public slsDetectorUtils {
public: public:
@ -252,16 +221,50 @@ class multiSlsDetector : public slsDetectorUtils {
*/ */
/** (default) constructor /**
\param id is the detector index which is needed to define the shared memory id. Different physical detectors should have different IDs in order to work independently * Constructor
* @param id multi detector id
* @param verify true to verify if shared memory size matches existing one
* @param update true to update last user pid, date etc
*/
multiSlsDetector(int id = 0, bool verify = true, bool update = true);
/**
* Destructor
*/ */
multiSlsDetector(int id=0);
//slsDetector(std::string const fname);
/** destructor */
virtual ~multiSlsDetector(); virtual ~multiSlsDetector();
/**
* Get sls detector object from position in detectors array
* @param pos position in detectors array
* @returns pointer to sls detector object
*/
slsDetector* getSlsDetector(unsigned int pos);
/**
* Free shared memory from the command line
* avoiding creating the constructor classes and mapping
* @param multiId multi detector Id
*/
static void freeSharedMemory(int multiId);
/**
* Free shared memory and delete shared memory structure
* occupied by the sharedMultiSlsDetector structure
*/
void freeSharedMemory();
/**
* Get user details of shared memory
* @returns string with user details
*/
std::string getUserDetails();
/** /**
* returns true. Used when reference is slsDetectorUtils and to determine if command can be implemented as slsDetector/multiSlsDetector object/ * returns true. Used when reference is slsDetectorUtils and to determine if command can be implemented as slsDetector/multiSlsDetector object/
*/ */
@ -276,11 +279,6 @@ class multiSlsDetector : public slsDetectorUtils {
/** destroys all the threads in the threadpool */ /** destroys all the threads in the threadpool */
void destroyThreadPool(); void destroyThreadPool();
/** frees the shared memory occpied by the sharedMultiSlsDetector structure */
int freeSharedMemory() ;
/** allocates the shared memory occpied for the sharedMultiSlsDetector structure */
int initSharedMemory(int) ;
/** adds the detector with ID id in postion pos /** adds the detector with ID id in postion pos
\param id of the detector to be added (should already exist!) \param id of the detector to be added (should already exist!)
@ -1280,7 +1278,6 @@ template<typename T>
int getMoveFlag(int imod); int getMoveFlag(int imod);
slsDetector *getSlsDetector(int pos) {if (pos>=0 && pos< MAXDET) return detectors[pos]; return NULL;};
//additional way of accessing //additional way of accessing
slsDetector *operator()(int pos) {if (pos>=0 && pos< MAXDET) return detectors[pos]; return NULL;}; slsDetector *operator()(int pos) {if (pos>=0 && pos< MAXDET) return detectors[pos]; return NULL;};
@ -1612,7 +1609,34 @@ template<typename T>
private: private:
/**
* Initialize (open/create) shared memory for the sharedMultiDetector structure
* @param verify true to verify if shm size matches existing one
* @param update true to update last user pid, date etc
* @returns true if the shared memory was created now
*/
bool initSharedMemory(bool verify = true, bool update = true);
/**
* Initialize detector structure
* @param created true if shared memory was just created now
* @param verify true to verify if shm size matches existing one
* @param update true to update last user pid, date etc
*/
void initializeDetectorStructure(bool created, bool verify = true, bool update = true);
/**
* Add single detector
* @param s hostname of the single detector
*/
void addSlsDetector (std::string s);
/**
* Execute in command line and return result
* @param cmd command
* @returns result
*/
std::string exec(const char* cmd);
/** /**
* add gap pixels to the image (only for Eiger in 4 bit mode) * add gap pixels to the image (only for Eiger in 4 bit mode)
@ -1623,29 +1647,26 @@ private:
int processImageWithGapPixels(char* image, char*& gpImage); int processImageWithGapPixels(char* image, char*& gpImage);
/** Multi detector Id */
int detId;
/** Shared Memory object */
SharedMemory* sharedMemory;
/** Shared memory structure */
sharedMultiSlsDetector *thisMultiDetector;
/** pointers to the slsDetector structures */
std::vector <slsDetector*> detectors;
/** data streaming (down stream) enabled in client (zmq sckets created) */ /** data streaming (down stream) enabled in client (zmq sckets created) */
bool client_downstream; bool client_downstream;
/** ZMQ Socket - Receiver to Client */ /** ZMQ Socket - Receiver to Client */
ZmqSocket* zmqSocket[MAXDET]; std::vector <ZmqSocket*> zmqSocket;
protected: /** Threadpool */
/** Shared memory ID */
int shmId;
/** pointers to the slsDetector structures */
slsDetector *detectors[MAXDET];
/** Shared memory structure */
sharedMultiSlsDetector *thisMultiDetector;
private:
ThreadPool* threadpool; ThreadPool* threadpool;
}; };

View File

@ -0,0 +1,165 @@
#include "SharedMemory.h"
#include "sls_detector_exceptions.h"
#include "ansi.h"
#include <iostream>
#include <stdio.h> // printf
#include <cerrno> // errno
#include <cstring> // strerror
#include <unistd.h>
#include <fcntl.h> // O_CREAT, O_TRUNC..
#include <sys/stat.h> // fstat
#include <sys/mman.h> // shared memory
#include <sstream>
SharedMemory::SharedMemory(int multiId, int singleId):
fd(-1),
shmSize(0)
{
name = ConstructSharedMemoryName(multiId, singleId);
}
SharedMemory::~SharedMemory(){
if (fd >= 0)
close(fd);
}
bool SharedMemory::IsExisting(std::string name) {
bool ret = true;
int fd = shm_open(name.c_str(), O_RDWR, 0);
if ((fd < 0) && (errno == ENOENT)) {
ret = false;
}
close(fd);
return ret;
}
std::string SharedMemory::GetName() {
return name;
}
void* SharedMemory::CreateSharedMemory(size_t sz){
// create
fd = shm_open(name.c_str(), O_CREAT | O_TRUNC | O_EXCL | O_RDWR, S_IRUSR | S_IWUSR);
if (fd < 0) {
cprintf(RED, "Error: Create shared memory %s failed: %s\n",
name.c_str(), strerror(errno));
throw SharedMemoryException();
}
// resize
if (ftruncate(fd, sz) < 0) {
cprintf(RED, "Error: Create shared memory %s failed at ftruncate: %s\n",
name.c_str(), strerror(errno));
close(fd);
throw SharedMemoryException();
}
// map
return MapSharedMemory(sz);
}
void* SharedMemory::OpenSharedMemory(size_t sz, bool verify){
// open
fd = shm_open(name.c_str(), O_RDWR, 0);
if (fd < 0) {
cprintf(RED, "Error: Open existing shared memory %s failed: %s\n",
name.c_str(), strerror(errno));
throw SharedMemoryException();
}
// verification required and size does not match
if (verify)
VerifySizeMatch(sz);
// map
return MapSharedMemory(sz);
}
void SharedMemory::UnmapSharedMemory(void* addr) {
if (munmap(addr, shmSize) < 0) {
cprintf(RED, "Error: Unmapping shared memory %s failed: %s\n",
name.c_str(), strerror(errno));
close(fd);
throw SharedMemoryException();
}
}
void SharedMemory::RemoveSharedMemory() {
RemoveSharedMemory(name.c_str());
}
void* SharedMemory::MapSharedMemory(size_t sz) {
void* addr = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (addr == MAP_FAILED) {
cprintf(RED, "Error: Mapping shared memory %s failed: %s\n",
name.c_str(), strerror(errno));
close(fd);
throw SharedMemoryException();
}
shmSize = sz;
close(fd);
return addr;
}
std::string SharedMemory::ConstructSharedMemoryName(int multiId, int singleId) {
stringstream ss;
if (singleId < 0)
ss << "/slsDetectorPackage_multi_" << multiId;
else
ss << "/slsDetectorPackage_multi_" << multiId << "_single_" << singleId;
std::string temp = ss.str();
if (temp.length() > NAME_MAX) {
cprintf(RED, "Error: Shared memory initialization %s failed: %s\n",
name.c_str(), strerror(errno));
throw SharedMemoryException();
}
return temp;
}
int SharedMemory::VerifySizeMatch(size_t expectedSize) {
struct stat sb;
// could not fstat
if (fstat(fd, &sb) < 0) {
cprintf(RED, "Error: Could not verify existing shared memory %s size match "
"(could not fstat): %s\n", name.c_str(), strerror(errno));
close(fd);
throw SharedMemoryException();
}
//size does not match
long unsigned int sz = (long unsigned int)sb.st_size;
if (sz != expectedSize) {
cprintf(RED, "Warning: Existing shared memory %s size does not match.\n",
name.c_str());
#ifdef VERBOSE
cprintf(RED, " Expected %ld, found %ld\n", expectedSize, sz);
#endif
throw SharedMemoryException();
return 1;
}
return 0;
}
void SharedMemory::RemoveSharedMemory(std::string name) {
if (shm_unlink(name.c_str()) < 0) {
// silent exit if shm did not exist anyway
if (errno == ENOENT)
return;
cprintf(RED, "Error: Free Shared Memory %s Failed: %s\n",
name.c_str(), strerror(errno));
throw SharedMemoryException();
}
printf("Shared memory deleted %s \n", name.c_str());
}

View File

@ -0,0 +1,117 @@
#pragma once
/************************************************
* @file SharedMemory.h
* @short functions basic implemenation of
* shared memory
***********************************************/
/**
*@short functions basic implemenation of shared memory
*/
#include <iostream>
#include <string>
class SharedMemory{
public:
/**
* Constructor
* creates the single/multi detector shared memory name
* @param multiId multi detector id
* @param singleId sls detector id, -1 if a multi detector shared memory
*/
SharedMemory(int multiId, int singleId);
/**
* Destructor
*/
~SharedMemory();
/**
* Verify if it exists
* @param name of shared memory
* @return true if exists, else false
*/
static bool IsExisting(std::string name);
/**
* Get shared memory name
*/
std::string GetName();
/**
* Create Shared memory and call MapSharedMemory to map it to an address
* throws a SharedMemoryException exception on failure to create, ftruncate or map
* @param sz of shared memory
* @param addr double pointer to address to be mapped
*/
void* CreateSharedMemory(size_t sz);
/**
* Open existing Shared memory and call MapSharedMemory to map it to an address
* throws a SharedMemoryException exception on failure to open, incorrect size if verify true, or map
* @param sz of shared memory
* @param addr double pointer to address to be mapped
* @param verify true to verify if the size matches existing one and return fail if does not match
*/
void* OpenSharedMemory(size_t sz, bool verify = true);
/**
* Unmap shared memory from an address
* throws a SharedMemoryException exception on failure
* @param addr double pointer to address to be mapped
*/
void UnmapSharedMemory(void* addr);
/**
* Remove existing Shared memory
*/
void RemoveSharedMemory();
/**
* Maximum length of name as from man pages
*/
static const int NAME_MAX = 255;
private:
/**
* Create Shared memory name
* throws exception if name created is longer than required 255(manpages)
* @param multiId multi detector id
* @param singleId sls detector id, -1 if a multi detector shared memory
* @returns shared memory name
*/
std::string ConstructSharedMemoryName(int multiId, int singleId);
/**
* Map shared memory to an address
* throws a SharedMemoryException exception on failure
* @param addr double pointer to address to be mapped
* @param sz of shared memory
*/
//template <typename myType>
// void MapSharedMemory(myType*& addr, size_t sz);
void* MapSharedMemory(size_t sz);
/**
* Verify if existing shared memory size matches expected size
* @param sz expected size of shared memory, replaced with smaller size if size does not match
* @return 0 for success, 1 for fail
*/
int VerifySizeMatch(size_t expectedSize);
/**
* Remove existing Shared memory
* @param name name of shared memory (should be less than NAME_MAX)
*/
void RemoveSharedMemory(std::string name);
/** Shared memory name */
std::string name;
/** File descriptor */
int fd;
/** shm size */
size_t shmSize;
};

View File

@ -262,7 +262,7 @@ slsDetector::slsDetector(int pos, detectorType type, int id, multiSlsDetector *p
} }
slsDetector::~slsDetector(){ slsDetector:slsDetector(){
// Detach Memory address // Detach Memory address
if (shmdt(thisDetector) == -1) { if (shmdt(thisDetector) == -1) {