Changeset 10757


Ignore:
Timestamp:
May 20, 2011, 10:03:04 AM (8 years ago)
Author:
ogrimm
Message:
Added thread cancellation handler to ensure mutex gets unlocked
Location:
fact/FADctrl
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • fact/FADctrl/FAD.cc

    r10642 r10757  
    2020                          const char *Help;
    2121  } CommandList[] =
    22   {{"board", &FAD::cmd_board, true, 1, "[+|-]<range>" ,"Activate or deactivate board(s)"},
     22  {{"board", &FAD::cmd_board, false, 1, "[+|-]<range>" ,"Activate or deactivate board(s)"},
    2323   {"status", &FAD::cmd_status, false, 0, "[range]", "Show board status information"},
    2424   {"domino", &FAD::cmd_domino, true, 1, "<on|off>", "Switch Domino wave"},
     
    2828   {"sclk", &FAD::cmd_sclk, true, 1, "<on|off>", "Set SCLK"},
    2929   {"trigger", &FAD::cmd_trigger, false, 0, "[n|cont [rate]|stop|enable|disable]", "Issue software triggers"},
    30    {"reset_trigger", &FAD::cmd_reset_trigger, true, 0, "", "Reset internal trigger counter"},
     30   {"reset", &FAD::cmd_reset, true, 0, "", "Reset internal trigger counter"},
    3131   {"runnumber", &FAD::cmd_runnumber, true, 1, "<n>", "Set runnumber"},
    3232   {"roi", &FAD::cmd_roi, true, 2, "<channel range> <value>", "Set region-of-interest to value"},
     
    199199//
    200200
    201 void FAD::cmd_reset_trigger() {
     201void FAD::cmd_reset() {
    202202
    203203  for (unsigned int i=0; i<Boards.size(); i++) Boards[i]->Send(CMD_RESET_TRIGGER_ID);
     
    379379        Buffer[2*i+1] = htons(Value);
    380380  }
    381  
    382   // Send command buffer
     381
     382  // Disable triggers for all boards and wait (workaround for firmware bug) 
     383  for (unsigned int i=0; i<Boards.size(); i++) Boards[i]->Send(CMD_TRIGGERS_OFF);
     384  usleep(500000);
     385
     386  // Send command buffer and enable triggers again
    383387  for (unsigned int i=0; i<Boards.size(); i++) {
    384388        Boards[i]->Send(Buffer, sizeof(Buffer));
     389        Boards[i]->Send(CMD_TRIGGERS_ON);
    385390  }
    386391}
     
    542547        FILE *File;
    543548        struct FADBoard::CalibData Data;
     549        bool Found = false;
    544550
    545551    // Open file
     
    553559            PrintMessage("Found calibration for board %d - %s", i, ctime(&Data.Time));
    554560            Boards[i]->ACalib = Data;
     561                Found = true;
    555562          }
    556563        }
     564        if (!Found) PrintMessage("Did not find calibration data for any board\n");
     565
    557566        //Close file
    558567        if (fclose(File) != 0) PrintMessage("Could not close file '%s'\n", Parameter[1].c_str());
     
    596605
    597606        // Print list of active boards
    598         PrintMessage("Active are %d boards(s)   ", Count);
     607        PrintMessage("Active (%d)\t", Count);
    599608        for (unsigned int i=0; i<Boards.size(); i++) {
    600609          if (Boards[i]->Active) PrintMessage(" %d%s", i, Boards[i]->CommOK ? "":"!");
    601610        }
     611        PrintMessage("\nInactive (%d)  ", Boards.size()-Count);
     612        for (unsigned int i=0; i<Boards.size(); i++) {
     613          if (!Boards[i]->Active) PrintMessage(" %d%s", i, Boards[i]->CommOK ? "":"!");
     614        }
    602615        PrintMessage("\n");
    603616
    604         // Current mode
     617        // Print current mode
    605618        if (Mode == idle) PrintMessage("Current mode is IDLE\n");
    606619        else if (Mode == acalib) PrintMessage("Current mode is ACALIB (3x%d events, slowest board %d has %d events)\n", NumEventsRequested, SlowestBoard, MinCount);
     
    945958          // Fill M0 BoardStructure             
    946959          S = Boards[Brd]->GetStatus();
    947           BStruct[Brd]->SerialNo = S.BoardID;
     960          BStruct[Brd]->SerialNo = (U32) S.DNA;
    948961          BStruct[Brd]->NomFreq = S.Frequency;
    949962          BStruct[Brd]->BoardTemp = 0;       
  • fact/FADctrl/FAD.h

    r10617 r10757  
    6969        void cmd_board();               void cmd_status();
    7070        void cmd_acalib();              void cmd_serial();
    71         void cmd_trigger();
    72         void cmd_runnumber();   void cmd_reset_trigger();
    73         void cmd_socketmode();
     71        void cmd_trigger();             void cmd_socketmode();
     72        void cmd_runnumber();   void cmd_reset();
    7473        void cmd_srclk();               void cmd_sclk();
    7574        void cmd_dwrite();              void cmd_domino();
  • fact/FADctrl/FADBoard.cc

    r10642 r10757  
    3333  pthread_mutexattr_t Attr;
    3434
     35  if ((Ret = pthread_mutexattr_init(&Attr)) != 0) {
     36    m->Message(m->ERROR, "pthread_mutex_init() failed in FADBoard constructor (%s)", strerror(Ret));
     37  }
    3538  if ((Ret = pthread_mutexattr_settype(&Attr, PTHREAD_MUTEX_ERRORCHECK)) != 0) {
    36     m->Message(m->ERROR, "pthread_mutex_settype() failed (%s)", strerror(Ret));
     39    m->Message(m->ERROR, "pthread_mutex_settype() failed in FADBoard constructor (%s)", strerror(Ret));
    3740  }
    3841  if ((Ret = pthread_mutex_init(&Mutex, &Attr)) != 0) {
    39     m->Message(m->FATAL, "pthread_mutex_init() failed (%s)", strerror(Ret));
     42    m->Message(m->FATAL, "pthread_mutex_init() failed in FADBoard constructor (%s)", strerror(Ret));
    4043  }
    4144
    4245  // Initialise condition variable for synchronization
    4346  if ((Ret = pthread_cond_init(&CondVar, NULL)) != 0) {
    44     m->Message(m->FATAL, "pthread_cond_init() failed (%s)", strerror(Ret));
     47    m->Message(m->FATAL, "pthread_cond_init() failed in FADBoard constructor (%s)", strerror(Ret));
    4548  }
    4649
     
    6366  SetStatus("Trying to connect...");
    6467
    65   if ((Ret = pthread_create(&Thread, NULL, (void * (*)(void *)) LaunchThread,(void *) this)) != 0) {
     68  if ((Ret = pthread_create(&Thread, NULL, (void * (*)(void *)) LaunchThread, (void *) this)) != 0) {
    6669    m->Message(m->FATAL, "pthread_create() failed in FADBoard() (%s)", strerror(Ret));
    6770  }
     
    177180        Count = 0;
    178181
    179         // Save initial board status, set all ROIs to 1024 and set DAC values
     182        // Save initial board status, set all ROIs to 1024 and set DAC values (no triggers while setting ROI)
    180183        InitialStatus = GetStatus();
     184
     185        Send(CMD_TRIGGERS_OFF);
     186        usleep(500000);
    181187
    182188        for (unsigned int i=0; i<NChips*NChannels; i++) {
     
    191197        Send(DACCmd, sizeof(DACCmd));
    192198
     199        Send(CMD_TRIGGERS_ON);
     200
    193201        // Clear sum vector and set state to accumulate
    194202        memset(Sum, 0, sizeof(Sum));
    195203        State = baseline;
     204        SetStatus("Starting calilbration");
    196205        break;
    197206
     
    319328        }
    320329
     330        SetStatus("Finished calibration");
    321331        State = cleanup;
    322332        break;
     
    325335  case cleanup:
    326336    // ROI values
     337        Send(CMD_TRIGGERS_OFF);
     338        usleep(100000);
     339
    327340        ROICmd.clear();
    328341        for (unsigned int i=0; i<NChips*NChannels; i++) {
     
    331344        }
    332345        Send(&ROICmd[0], ROICmd.size()*sizeof(unsigned short));
     346
     347        Send(CMD_TRIGGERS_ON);
    333348
    334349        // DAC values
     
    421436        // If not active, discard incoming data
    422437        if (!Active) continue;
    423        
     438
    424439        // Advance write pointer
    425440        Pos += Result;
     
    461476          Lock();
    462477          while (!Continue) {
    463                 if ((Ret = pthread_cond_wait(&CondVar, &Mutex)) != 0) {
    464                   m->Message(m->ERROR, "pthread_cond_wait() failed (%s)", strerror(Ret));
     478                struct timespec Wakeup;
     479                Wakeup.tv_sec = time(NULL)+5;
     480                Wakeup.tv_nsec = 0;
     481                if ((Ret = pthread_cond_timedwait(&CondVar, &Mutex, &Wakeup)) != 0) {
     482                  if (Ret == ETIMEDOUT) printf("Board %s timed out (5 s) waiting for condition\n", Name);
     483                  else m->Message(m->ERROR, "pthread_cond_wait() failed (%s)", strerror(Ret));
    465484                }
    466485          }
     
    580599
    581600//
    582 // Launch read thread inside class
     601// Install cleanup handler and launch read thread inside class
    583602//
    584603void FADBoard::LaunchThread(class FADBoard *m) {
    585604
     605  pthread_cleanup_push((void (*)(void *)) FADBoard::ThreadCleanup, (void *) m);
    586606  m->ReadLoop();
     607  pthread_cleanup_pop(0);
    587608}
    588609
     
    631652}
    632653
     654// Ensure that mutex is unlocked when before cancelling thread
     655void FADBoard::ThreadCleanup(class FADBoard *This) {
     656
     657  int Ret;
     658
     659  if ((Ret = pthread_mutex_trylock(&This->Mutex)) != 0) {
     660        if (Ret != EBUSY) This->m->Message(This->m->FATAL, "pthread_mutex_trylock() failed in FADBoard::ThreadCleanup (%s)", strerror(Ret));
     661  }
     662  This->Unlock();
     663}
    633664
    634665//
  • fact/FADctrl/FADBoard.h

    r10642 r10757  
    3333        void ReadLoop();
    3434        static void LaunchThread(class FADBoard *);
     35        static void ThreadCleanup(class FADBoard *);
    3536        void threadHandler();
    3637        void SetStatus(const char *, ...);
  • fact/FADctrl/History.txt

    r10617 r10757  
    25254/5/2011        Removed 'daqmode' (had no function). Added 'reset_trigger' and 'runnumber' commands.
    2626                        Event format adapted (ADC data not sent in network byte order anymore).
     2720/5/2011       Missing pthread_mutexattr_init() in FADBoard constructor caused spurious errors when
     28                        locking mutex
     29                        Added cleanup handler to thread in FADBoard class to ensure mutex is unlocked when thread
     30                        cancelled
Note: See TracChangeset for help on using the changeset viewer.