Changeset 226 for drsdaq


Ignore:
Timestamp:
06/18/10 12:25:29 (14 years ago)
Author:
ogrimm
Message:
Small changes to mutex handling in hvcontrol and drsdaq
Location:
drsdaq
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • drsdaq/DAQReadout.cc

    r211 r226  
    6464//
    6565 
    66 DAQReadout::DAQReadout():
    67                         DimCommand((char *) SERVER_NAME"/Command", (char *) "C"),
    68                         EvidenceServer(SERVER_NAME) {
    69 
    70   // Global class pointer
     66DAQReadout::DAQReadout(): EvidenceServer(SERVER_NAME) {
     67
     68  // Initialization
    7169  This = this;
    7270  MainThread = getpid();
    73 
    74   // Start time of DAQ
     71  ConsoleText = NULL;
    7572  time(&StartTime);
     73
     74  // DIM console service used in PrintMessage()
     75  ConsoleOut = new DimService(SERVER_NAME"/ConsoleOut", (char *) "");
    7676
    7777  // Initialize mutex for thread synchronisation
    7878  if (pthread_mutex_init(&Mutex, NULL) != 0) {
    79     State(FATAL, "pthread_mutex_init() failed");
     79    Message(FATAL, "pthread_mutex_init() failed");
    8080  }
    8181
     
    8989  LastBoard                     = -1;
    9090  MinDelay                      = 1;
    91  
     91
    9292  // Get configuration data
    9393  fRawDataPath = GetConfig("RawDataPath");
     
    145145  // Create instance of HV feedback (must be called after board detection)
    146146  HVFB    = new HVFeedback(this); 
     147
     148  // Install DIM command (after all initialized)
     149  Command = new DimCommand((char *) SERVER_NAME"/Command", (char *) "C", this);
    147150}
    148151
     
    153156DAQReadout::~DAQReadout() {
    154157
    155   delete EventService;
    156   delete[] DIMEventData;
     158  delete Command;
     159
     160  delete EventService;  delete[] DIMEventData;
    157161  delete RHeader;               delete EHeader;
    158162  delete HVFB;                  delete[] ACalibTemp;
     
    160164  delete[] DRSFreq;     delete[] BStruct;
    161165  delete[] WaveForm;    delete[] TriggerCell;
    162  
    163   // Destroy mutex
    164   if (pthread_mutex_destroy(&Mutex) != 0) State(ERROR, "pthread_mutex_destroy() failed");
     166
     167  delete ConsoleOut;
     168  free(ConsoleText);
     169 
     170  if (pthread_mutex_destroy(&Mutex) != 0) Message(ERROR, "pthread_mutex_destroy() failed");
    165171}
    166172
     
    171177void DAQReadout::Execute(char *Command) {
    172178
    173   if (strlen(Command)==0) return;  // Ignore empty commands
    174 
    175   if(Command[0]=='.') {   // Shell command
     179  if (Command[0]=='.') {   // Shell command
    176180    system(&(Command[1]));
    177181    return;
    178182  }
    179183
    180   for(int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = "";  // All pointers point initially to empty string
     184  for (int i=0; i<MAX_NUM_TOKEN; i++) Param[i] = "";  // All pointers point initially to empty string
    181185  NParam = ParseInput(Command, Param);
    182 
    183   for(CmdNumber=0; CmdNumber<sizeof(CommandList)/sizeof(CL_Struct); CmdNumber++)
    184     if (Match(Param[0], CommandList[CmdNumber].Name)) {
    185       if(CommandList[CmdNumber].NeedNotBusy && daq_state==active) PrintMessage("DAQ is busy\n");
    186       else if(CommandList[CmdNumber].NeedNotBusy && NumBoards==0) PrintMessage("No boards available\n");
    187       else {
    188                 pthread_mutex_lock(&Mutex);
    189             (this->*CommandList[CmdNumber].CommandPointer)();
    190                 pthread_mutex_unlock(&Mutex);
    191           }
    192       return; 
    193     }
    194   PrintMessage("Unknown command '%s'\n",Param[0]);
     186 
     187  // Search for command
     188  unsigned int Count;
     189  for (Count=0; Count<sizeof(CommandList)/sizeof(CL_Struct); Count++) {
     190    if (Match(Param[0], CommandList[Count].Name)) break;
     191  }
     192 
     193  // Command not found?
     194  if (Count == sizeof(CommandList)/sizeof(CL_Struct)) {
     195        PrintMessage("Unknown command '%s'\n", Param[0]);
     196        return;
     197  }
     198
     199  if(CommandList[Count].NeedNotBusy && daq_state==active) PrintMessage("DAQ is busy\n");
     200  else if(CommandList[Count].NeedNotBusy && NumBoards==0) PrintMessage("No boards available\n");
     201  else {
     202        int Ret;
     203
     204        // Lock (Execute() runs in thread spawned by commandHandler())
     205        if ((Ret = pthread_mutex_lock(&Mutex)) != 0) {
     206          Message(FATAL, "pthread_mutex_lock() failed (%s)", strerror(Ret));
     207        }
     208        // Run command
     209        CmdNumber = Count;
     210        (this->*CommandList[CmdNumber].CommandPointer)();
     211        // Unlock
     212        if ((Ret = pthread_mutex_unlock(&Mutex)) != 0) {
     213          Message(FATAL, "pthread_mutex_unlock() failed (%s)", strerror(Ret));
     214        }
     215  }
    195216}
    196217         
     
    199220  time_t ActualT;
    200221  time (&ActualT);
    201   PrintMessage("%d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60);
     222  PrintMessage("%02d:%02d:%02d\n", (int) difftime(ActualT, StartTime)/3600, ((int) difftime(ActualT, StartTime)/60)%60, (int) difftime(ActualT, StartTime)%60);
    202223}
    203224
     
    11161137  }
    11171138 
    1118   // Event data (It is required that at least three chunks can be written with writev(), therefore
    1119   // IOV_MAX>=3 is checked at startup
    1120  
    1121 
    1122   // First chunk: trigger cells
    1123   //DataPart[Count].iov_base = (char *) TriggerCell + FirstBoard*RHeader->NChips*sizeof(int); // TriggerCell is without cast a pointer to an 8-byte unit (two ints) !
    1124   //DataPart[Count++].iov_len = RHeader->NBoards * RHeader->NChips * sizeof(int);
    1125   //Size += DataPart[Count-1].iov_len;
    1126 
    1127   // Remaining chunks: ADC data (two chucks per channel if wrap around of pipeline occurred)
     1139  // ADC data (two chucks per channel if wrap around of pipeline occurred, therefore
     1140  // IOV_MAX>=2 is checked at startup
    11281141  for (int i=FirstBoard; (i<=LastBoard + (NumBoards==0)); i++) {
    11291142    for (unsigned int k=0; k<RHeader->NChips; k++) {
     
    12021215void DAQReadout::DoPrintMessage(const char *Format, va_list ArgumentPointer, int Target) {
    12031216
    1204   static char Textbuffer[MAX_COM_SIZE];
    1205  
    1206   memset(Textbuffer, 0, sizeof(Textbuffer)); 
    1207   vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
     1217  static char Error[] = "vasprintf() failed in DoPrintMessage()";
     1218  char *Text;
     1219
     1220  // Evaluate arguments   
     1221  if (vasprintf(&Text, Format, ArgumentPointer) == -1) Text = Error;
    12081222 
    12091223  // Print to console
    12101224  if(Target & MsgToConsole) {
    1211     if(strlen(Textbuffer)>0 && Textbuffer[strlen(Textbuffer)-1]=='\n') {
    1212       printf("\r%s%s", Textbuffer, Prompt);   // New prompt
    1213     }
    1214     else printf("%s", Textbuffer);
     1225    if(strlen(Text)>0 && Text[strlen(Text)-1]=='\n') printf("\r%s%s", Text, Prompt);  // New prompt
     1226    else printf("%s", Text);
    12151227        fflush(stdout);
    12161228  }
    12171229 
    1218   // Send to DIM service
    1219   SetStdOut(Textbuffer);
    1220 
    1221   // Send to log
    1222   if(Target & MsgToLog) {
    1223     char *Buf;
    1224     if (asprintf(&Buf, "%s %s", SERVER_NAME, Textbuffer) != -1) {
    1225       DimClient::sendCommandNB("DColl/Log", Buf);
    1226       free(Buf);
    1227     }
    1228     else DimClient::sendCommandNB("DColl/Log", SERVER_NAME" asprintf() failed");
    1229   }
     1230  // Send to DIM console service and to log if requested
     1231  ConsoleOut->updateService(Text);
     1232  if(Target & MsgToLog) SendToLog("%s %s", SERVER_NAME, Text);
     1233
     1234  // Free old text
     1235  if (ConsoleText != Error) free(ConsoleText);
     1236  ConsoleText = Text;
    12301237}
    12311238
     
    12331240void DAQReadout::commandHandler() {
    12341241
    1235   // Copy command to new buffer (must be freed by the new thread)
     1242  // Ignore empty or illegal strings
     1243  if (getCommand()->getSize() == 0 ||
     1244          *((char *) getCommand()->getData()+getCommand()->getSize()-1) != '\0' ||
     1245          strlen(getCommand()->getString()) == 0) return;
     1246
     1247  // Copy command to new buffer (will be freed by global Execute() function)
    12361248  char *Command;
    1237   if (asprintf(&Command, "%s", getString()) == -1) {
     1249  if (asprintf(&Command, "%s", getCommand()->getString()) == -1) {
    12381250        PrintMessage("asprintf() failed in DRSReadout::commandHandler() (%s)\n", strerror(errno));
    12391251        return;
     
    13141326      else if (daq_runtype == pedestal) StopDRS();   // ..or for software trigger
    13151327
    1316       // Read event data
     1328      // Read event data and restart (reduces dead-time because waiting for next trigger while writing)
    13171329          ReadCalibratedDRSData();
    1318          
    1319           // Restart here reduces dead-time (already waiting for next trigger while writing)
    13201330          StartDRS();
    13211331
     
    13861396  else PrintMessage("\rRun #%d (%s) aborted due to error after %d events\n", RunNumber, daq_runtype_str[daq_runtype], NumEvents);
    13871397
    1388   // Write run summary to slow data file
    1389   //m->SlowDataClass->NewEntry("Runinfo");
    1390   //m->SlowDataClass->AddToEntry("%d %s %s %d %d %s", m->RunNumber, WriteError?"Error":"OK", daq_runtype_str[m->daq_runtype], m->NumEvents, m->FileNumber, m->RHeader->Description);
    1391 
    13921398  // Print run statistics
    13931399  if (NumEvents>0 && !WriteError) {
     
    14451451}
    14461452
     1453// Stub to call Execute() metho of class and free command memory
    14471454void Execute(char *Command) {
    14481455
  • drsdaq/DAQReadout.h

    r211 r226  
    3333enum runtype_enum {data, pedestal, reserved, test};
    3434
    35 class DAQReadout : public DRS, public DRSCallback, public DimCommand, public EvidenceServer {
     35class DAQReadout : public DRS, public DRSCallback, public EvidenceServer {
    3636
    37     time_t StartTime;
     37        time_t StartTime;
    3838        pid_t MainThread;
    3939        DimService *EventService;
    4040        int MinDelay;
    4141    unsigned int CmdNumber;
     42        DimCommand *Command;
     43        DimService *ConsoleOut;
     44        char *ConsoleText;
    4245
    4346    void PrintUsage();
  • drsdaq/HVFeedback.cc

    r211 r226  
    2525// Constructor: Initialise feedback
    2626//
    27 HVFeedback::HVFeedback(DAQReadout* DAQClass){//:
    28                         //EvidenceServer(SERVER_NAME){
     27HVFeedback::HVFeedback(DAQReadout* DAQClass){
    2928
    3029  m = DAQClass;
     
    139138  }
    140139 
    141   // Update DIM service regularly
     140  // Update DIM count service regularly
    142141  if (time(NULL)-LastServiceUpdate > 2) {
    143142    LastServiceUpdate = time(NULL);
     
    148147
    149148  // Feedback action
     149  std::stringstream Cmd;
     150 
    150151  for (i=m->FirstBoard; i<=m->LastBoard; i++) {
    151152  for (j=0; j<fNumberOfChips; j++) {
     
    165166
    166167                if(fabs(Average[i][j][k]) < 2*Sigma[i][j][k]) printf("Too noisy!\n");
    167                 else WriteHVCommand("hv %s %+f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), Correction);
    168 
     168                else {
     169                  Cmd << PixMap->DRS_to_Pixel(i,j,k)+" " << std::showpos << Correction << " ";
     170                }
    169171            break;
    170172
     
    175177          case FB_ResponseFirst:  // First point of response measurement done 
    176178            Buffer[i][j][k] = Average[i][j][k];
    177             if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv %s %+f",PixMap->DRS_to_Pixel(i,j,k).c_str(), DiffVoltage);
     179            if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
     180                  Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << DiffVoltage << " ";               
     181                }
    178182            break;
    179183
     
    184188            }
    185189            else Response[i][j][k] = DiffVoltage/(Buffer[i][j][k]-Average[i][j][k]);
    186             if(!PixMap->DRS_to_Pixel(i,j,k).empty()) WriteHVCommand("hv %s %+f",PixMap->DRS_to_Pixel(i,j,k).c_str(), -DiffVoltage/2);
     190            if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
     191                  Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << -DiffVoltage/2 << " ";                             
     192                }
    187193            break;
    188194
     
    196202  FeedbackAverage->updateService();
    197203  FeedbackSigma->updateService();
     204
     205  // Send command
     206  if (!Cmd.str().empty()) {
     207        DimClient::sendCommand("Bias/Command", ("hv "+Cmd.str()).c_str());
     208  }
    198209
    199210  switch (FBMode) {
     
    269280  else {
    270281    FBMode = Mode;
    271         if (Mode != FB_ResponseFirst) m->State(m->INFO, "%s", FBState_Description[FBMode]);
    272         else m->State(m->INFO, "%s (voltage difference %.3f)", FBState_Description[FBMode], DiffVoltage);
     282        if (Mode != FB_ResponseFirst) m->Message(m->INFO, "%s", FBState_Description[FBMode]);
     283        else m->Message(m->INFO, "%s (voltage difference %.3f)", FBState_Description[FBMode], DiffVoltage);
    273284    ClearAverages();
    274285  }
     
    320331void HVFeedback::MeasureResponse(float U) {
    321332
     333  std::stringstream Cmd;
     334
    322335  if (U==0) {
    323336    m->PrintMessage("HV Feedback: Error, voltage difference must not non-zero.\n");
     
    325338  }
    326339
    327   for (int i=m->FirstBoard; i<=m->LastBoard; i++)
    328     for (int j=0; j<fNumberOfChips; j++)
    329       for (int k=0; k<fNumberOfChannels; k++) {
    330                 if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
    331           WriteHVCommand("hv %s %+f\n",PixMap->DRS_to_Pixel(i,j,k).c_str(), -U/2);
    332         }
    333       }
     340  for (int i=m->FirstBoard; i<=m->LastBoard; i++) {
     341  for (int j=0; j<fNumberOfChips; j++) {
     342  for (int k=0; k<fNumberOfChannels; k++) {
     343        if(!PixMap->DRS_to_Pixel(i,j,k).empty()) {
     344          Cmd << PixMap->DRS_to_Pixel(i,j,k) << " " << std::showpos << -U/2 << " ";                               
     345    }
     346  }
     347  }
     348  }
     349 
     350  // Send command
     351  if (!Cmd.str().empty()) {
     352        DimClient::sendCommand("Bias/Command", ("hv "+Cmd.str()).c_str());
     353  }
     354
    334355  DiffVoltage = U;
    335356  SetFBMode(FB_ResponseFirst, true);
     
    351372
    352373//
    353 // Write bias voltage commmand
    354 //
    355 bool HVFeedback::WriteHVCommand(const char *Format, ...) {
    356 
    357   char Textbuffer[MAX_COM_SIZE];
    358  
    359   va_list ArgumentPointer;  va_start(ArgumentPointer, Format);
    360   vsnprintf(Textbuffer, sizeof(Textbuffer), Format, ArgumentPointer);
    361 
    362   DimClient::sendCommand("Bias/Command", Textbuffer);
    363   return true;
    364 }
    365 
    366 //
    367374// Print feedback configuration
    368375//
  • drsdaq/HVFeedback.h

    r211 r226  
    66#include <stdlib.h>
    77#include <math.h>
     8#include <sstream>
    89
    910#include "RawDataCTX.h"
     
    1213enum FBState {FB_Off, FB_Active, FB_Targets, FB_ResponseFirst, FB_ResponseSecond};
    1314
    14 class HVFeedback: public DimServer {//EvidenceServer {
     15class HVFeedback: public DimServer {
    1516
    1617    class DAQReadout *m;
     
    7071    void GetResponse();
    7172    void ClearAverages();
    72     bool WriteHVCommand(const char *, ...);
    7373    void PrintConfig(int);
    7474};
  • drsdaq/drsdaq.cpp

    r211 r226  
    3636  int LockDescriptor;
    3737
    38   // Readline library uses getc() (allows interruption by signal)
    39   rl_getc_function = getc;
    40 
    41   // writev() in DAQ thread needs to be able to write at least 3 chunks
    42   if(IOV_MAX < 3) {
    43         printf("Fatal error: IOV_MAX is less than 3, cannot use writev() to write event data.\n");
    44         exit(EXIT_FAILURE);
    45   }
    46    
    4738  // Assure only one instance of program runs (lock creator written to log file)
    48   // Lock file deleted by ExitFunction()
     39  // Lock file deleted by destructor
    4940  if((LockDescriptor = open(LOCKFILE,O_WRONLY|O_CREAT|O_EXCL, S_IWUSR|S_IRUSR|S_IRGRP|S_IROTH)) == -1) {
    5041    if(errno==EEXIST) {
     
    5950  sprintf(str,"echo Created >%s; date >>%s; echo by $USER@$HOSTNAME >>%s",LOCKFILE,LOCKFILE,LOCKFILE);
    6051  system(str);
    61  
     52
     53  // Readline library uses getc() (allows interruption by signal)
     54  rl_getc_function = getc;
     55
     56  // writev() in DAQ thread needs to be able to write at least 3 chunks
     57  if(IOV_MAX < 2) {
     58        printf("Fatal error: IOV_MAX is less than 2, cannot use writev() to write event data.\n");
     59        exit(EXIT_FAILURE);
     60  }
     61     
    6262  system("clear");
    6363  printf("\n*** DRS readout (built %s, %s, revision %s) *** \n\n",__DATE__, __TIME__, REVISION);
     64
     65  // Set exit function
     66  atexit(&ExitFunction);
    6467
    6568  // Construct main instance (static ensures destructor is called with exit())
    6669  static DAQReadout M;
    6770
    68   // Set signal and exit handlers
    69   atexit(&ExitFunction);
     71  // Set signal handlers
    7072  signal(SIGILL, &CrashHandler);
    7173  signal(SIGABRT, &CrashHandler);
     
    8890    // Process command
    8991        DimClient::sendCommand(SERVER_NAME"/Command", Command);
    90 
    9192    free(Command);
    9293  } 
     
    9495
    9596
    96 //*****************
    97 //  Signal handlers
    98 //*****************
    99 
    10097// Remove lock file before running default signal code
    10198void CrashHandler(int Signal) {
    10299  remove(LOCKFILE);
    103   printf("Caught signal number %d. Removing lockfile and performing standard signal action. Good luck.\n",Signal);
     100  printf("Caught signal number %d. Removed lockfile and performing standard signal action. Good luck.\n",Signal);
    104101  signal(Signal, SIG_DFL);
    105102  raise(Signal);
     
    109106void ExitFunction() {
    110107
    111   if (remove(LOCKFILE)==-1) {
     108  if (remove(LOCKFILE) == -1) {
    112109    printf("Could not remove lock file %s (%s)\n", LOCKFILE, strerror(errno));
    113110  }
    114 
    115   return;         
    116111}
Note: See TracChangeset for help on using the changeset viewer.