SignalLoggerManager.cpp
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:13k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2003 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. #include <ndb_global.h>
  14. #include "SignalLoggerManager.hpp"
  15. #include <LongSignal.hpp>
  16. #include <DebuggerNames.hpp>
  17. SignalLoggerManager::SignalLoggerManager()
  18. {
  19.   for (int i = 0; i < NO_OF_BLOCKS; i++){
  20.       logModes[i] = 0;
  21.   }
  22.   outputStream = 0;
  23.   m_ownNodeId = 0;
  24.   m_logDistributed = false;
  25. }
  26. SignalLoggerManager::~SignalLoggerManager()
  27. {
  28.   if(outputStream != 0){
  29.     fflush(outputStream);
  30.     fclose(outputStream);
  31.     outputStream = 0;
  32.   }
  33. }
  34. FILE *
  35. SignalLoggerManager::setOutputStream(FILE * output)
  36. {
  37.   if(outputStream != 0){
  38.     fflush(outputStream);
  39.   }
  40.   FILE * out = outputStream;
  41.   outputStream = output;
  42.   return out;
  43. }
  44. FILE *
  45. SignalLoggerManager::getOutputStream() const
  46. {
  47.   return outputStream;
  48. }
  49. void
  50. SignalLoggerManager::flushSignalLog()
  51. {
  52.   if(outputStream != 0)
  53.     fflush(outputStream);
  54. }
  55. void
  56. SignalLoggerManager::setTrace(unsigned long trace)
  57. {
  58.   traceId = trace;
  59. }
  60. unsigned long
  61. SignalLoggerManager::getTrace() const
  62. {
  63.   return traceId;
  64. }
  65. void
  66. SignalLoggerManager::setOwnNodeId(int nodeId){
  67.   m_ownNodeId = nodeId;
  68. }
  69.   
  70. void
  71. SignalLoggerManager::setLogDistributed(bool val){
  72.   m_logDistributed = val;
  73. }
  74. int
  75. getParameter(char *blocks[NO_OF_BLOCKS], const char * par, const char * line)
  76. {
  77.   const char * loc = strstr(line, par);
  78.   if(loc == NULL)
  79.     return 0;
  80.   loc += strlen(par);
  81.   int found = 0;
  82.   char * copy = strdup(loc);
  83.   char * tmp = copy;
  84.   bool done = false;
  85.   while(!done){
  86.     int len = strcspn(tmp, ", ;:");
  87.     if(len == 0)
  88.       done = true;
  89.     else {
  90.       if(* (tmp + len) != ',')
  91. done = true;
  92.       * (tmp + len) = 0;
  93.       blocks[found] = strdup(tmp);
  94.       found ++;
  95.       tmp += (len + 1);
  96.     } 
  97.   }
  98.   free(copy);
  99.   return found;
  100. }
  101. #define SLM_OFF    0
  102. #define SLM_ON     1
  103. #define SLM_TOGGLE 2
  104. int
  105. SignalLoggerManager::log(LogMode logMode, const char * params)
  106. {
  107.   char * blocks[NO_OF_BLOCKS];
  108.   const int count = getParameter(blocks, "BLOCK=", params);
  109.   
  110.   int cnt = 0;
  111.   if((count == 1 && blocks[0] == "ALL") ||
  112.      count == 0){
  113.     
  114.     for (int number = 0; number < NO_OF_BLOCKS; ++number){
  115.       cnt += log(SLM_ON, number, logMode);
  116.     }
  117.   } else {
  118.     for (int i = 0; i < count; ++i){
  119.       BlockNumber number = getBlockNo(blocks[i]);
  120.       cnt += log(SLM_ON, number-MIN_BLOCK_NO, logMode);
  121.     }
  122.   }
  123.   for(int i = 0; i<count; i++){
  124.     free(blocks[i]);
  125.   }
  126.   return cnt;
  127. }
  128. int
  129. SignalLoggerManager::log(int cmd, BlockNumber bno, LogMode logMode)
  130. {
  131.   // Normalise blocknumber for use in logModes array
  132.   const BlockNumber bno2 = bno-MIN_BLOCK_NO;
  133.   assert(bno2<NO_OF_BLOCKS);
  134.   switch(cmd){
  135.   case SLM_ON:
  136.     logModes[bno2] |= logMode;
  137.     return 1;
  138.     break;
  139.   case SLM_OFF:
  140.     logModes[bno2] &= (~logMode);
  141.     return 1;
  142.     break;
  143.   case SLM_TOGGLE:
  144.     logModes[bno2] ^= logMode;
  145.     return 1;
  146.     break;
  147.   }
  148.   return 0;
  149. }
  150. int
  151. SignalLoggerManager::logOn(bool allBlocks, BlockNumber bno, LogMode logMode)
  152. {
  153.   if(!allBlocks){
  154.     return log(SLM_ON, bno, logMode);
  155.   } 
  156.   int cnt = 0;
  157.   for(unsigned int i = MIN_BLOCK_NO; i <= MAX_BLOCK_NO; i++)
  158.     cnt += log(SLM_ON, i, logMode);
  159.   return cnt;
  160. }
  161. int
  162. SignalLoggerManager::logOff(bool allBlocks, BlockNumber bno, LogMode logMode)
  163. {
  164.   if(!allBlocks){
  165.     return log(SLM_OFF, bno, logMode);
  166.   } 
  167.   int cnt = 0;
  168.   for(unsigned int i = MIN_BLOCK_NO; i <= MAX_BLOCK_NO; i++)
  169.     cnt += log(SLM_OFF, i, logMode);
  170.   return cnt;
  171. }
  172. int
  173. SignalLoggerManager::logToggle(bool allBlocks, BlockNumber bno, LogMode logMode)
  174. {
  175.   if(!allBlocks){
  176.     return log(SLM_TOGGLE, bno, logMode);
  177.   } 
  178.   int cnt = 0;
  179.   for(unsigned int i = MIN_BLOCK_NO; i <= MAX_BLOCK_NO; i++)
  180.     cnt += log(SLM_TOGGLE, i, logMode);
  181.   return cnt;
  182. }
  183. void
  184. SignalLoggerManager::executeDirect(const SignalHeader& sh, 
  185.    Uint8 prio,  // in-out flag
  186.    const Uint32 * theData, Uint32 node)
  187. {
  188.   Uint32 trace = sh.theTrace;
  189.   Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
  190.   Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
  191.   
  192.   if(outputStream != 0 && 
  193.      (traceId == 0 || traceId == trace) &&
  194.      (logMatch(senderBlockNo, LogOut) || logMatch(receiverBlockNo, LogIn))){
  195.     const char* inOutStr = prio == 0 ? "In" : "Out";
  196. #ifdef VM_TRACE_TIME
  197.     fprintf(outputStream, "---- Direct --- Signal --- %s - %d ----n", inOutStr, time(0));
  198. #else
  199.     fprintf(outputStream, "---- Direct --- Signal --- %s ----------------n", inOutStr);
  200. #endif
  201.     // XXX pass in/out to print* function somehow
  202.     printSignalHeader(outputStream, sh, 0, node, true);
  203.     printSignalData(outputStream, sh, theData);
  204.   }
  205. }
  206. /**
  207.  * For input signals
  208.  */
  209. void
  210. SignalLoggerManager::executeSignal(const SignalHeader& sh, Uint8 prio, 
  211.    const Uint32 * theData, Uint32 node,
  212.                                    const SegmentedSectionPtr ptr[3], Uint32 secs)
  213. {
  214.   Uint32 trace = sh.theTrace;
  215.   //Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
  216.   Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
  217.   Uint32 senderNode = refToNode(sh.theSendersBlockRef);
  218.   if(outputStream != 0 && 
  219.      (traceId == 0 || traceId == trace) &&
  220.      (logMatch(receiverBlockNo, LogOut) ||
  221.       (m_logDistributed && m_ownNodeId != senderNode))){
  222. #ifdef VM_TRACE_TIME
  223.     fprintf(outputStream, "---- Received - Signal - %d ----n", time(0));
  224. #else
  225.     fprintf(outputStream, "---- Received - Signal ----------------n");
  226. #endif
  227.     printSignalHeader(outputStream, sh, prio, node, true);
  228.     printSignalData(outputStream, sh, theData);
  229.     for (unsigned i = 0; i < secs; i++)
  230.       printSegmentedSection(outputStream, sh, ptr, i);
  231.   }
  232. }
  233. void
  234. SignalLoggerManager::executeSignal(const SignalHeader& sh, Uint8 prio, 
  235.    const Uint32 * theData, Uint32 node,
  236.                                    const LinearSectionPtr ptr[3], Uint32 secs)
  237. {
  238.   Uint32 trace = sh.theTrace;
  239.   //Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
  240.   Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
  241.   Uint32 senderNode = refToNode(sh.theSendersBlockRef);
  242.   if(outputStream != 0 && 
  243.      (traceId == 0 || traceId == trace) &&
  244.      (logMatch(receiverBlockNo, LogOut) ||
  245.       (m_logDistributed && m_ownNodeId != senderNode))){
  246. #ifdef VM_TRACE_TIME
  247.     fprintf(outputStream, "---- Received - Signal - %d ----n", time(0));
  248. #else
  249.     fprintf(outputStream, "---- Received - Signal ----------------n");
  250. #endif
  251.     printSignalHeader(outputStream, sh, prio, node, true);
  252.     printSignalData(outputStream, sh, theData);
  253.     for (unsigned i = 0; i < secs; i++)
  254.       printLinearSection(outputStream, sh, ptr, i);
  255.   }
  256. }
  257. /**
  258.  * For output signals
  259.  */
  260. void
  261. SignalLoggerManager::sendSignal(const SignalHeader& sh,
  262.                                 Uint8 prio,
  263. const Uint32 * theData, Uint32 node,
  264.                                 const LinearSectionPtr ptr[3], Uint32 secs)
  265. {
  266.   Uint32 trace = sh.theTrace;
  267.   Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
  268.   //Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
  269.   if(outputStream != 0 && 
  270.      (traceId == 0 || traceId == trace) &&
  271.      (logMatch(senderBlockNo, LogOut) ||
  272.       (m_logDistributed && m_ownNodeId != node))){
  273. #ifdef VM_TRACE_TIME
  274.     fprintf(outputStream, "---- Send ----- Signal - %d ----n", time(0));
  275. #else
  276.     fprintf(outputStream, "---- Send ----- Signal ----------------n");
  277. #endif
  278.     printSignalHeader(outputStream, sh, prio, node, false);
  279.     printSignalData(outputStream, sh, theData);
  280.     for (unsigned i = 0; i < secs; i++)
  281.       printLinearSection(outputStream, sh, ptr, i);
  282.   }
  283. }
  284. /**
  285.  * For output signals
  286.  */
  287. void
  288. SignalLoggerManager::sendSignal(const SignalHeader& sh, Uint8 prio, 
  289. const Uint32 * theData, Uint32 node,
  290.                                 const SegmentedSectionPtr ptr[3], Uint32 secs)
  291. {
  292.   Uint32 trace = sh.theTrace;
  293.   Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
  294.   //Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
  295.   if(outputStream != 0 && 
  296.      (traceId == 0 || traceId == trace) &&
  297.      (logMatch(senderBlockNo, LogOut) ||
  298.       (m_logDistributed && m_ownNodeId != node))){
  299. #ifdef VM_TRACE_TIME
  300.     fprintf(outputStream, "---- Send ----- Signal - %d ----n", time(0));
  301. #else
  302.     fprintf(outputStream, "---- Send ----- Signal ----------------n");
  303. #endif
  304.     printSignalHeader(outputStream, sh, prio, node, false);
  305.     printSignalData(outputStream, sh, theData);
  306.     for (unsigned i = 0; i < secs; i++)
  307.       printSegmentedSection(outputStream, sh, ptr, i);
  308.   }
  309. }
  310. void
  311. SignalLoggerManager::sendSignalWithDelay(Uint32 delayInMilliSeconds,
  312.  const SignalHeader & sh, Uint8 prio, 
  313.  const Uint32 * theData, Uint32 node,
  314.                                          const SegmentedSectionPtr ptr[3], Uint32 secs)
  315. {
  316.   Uint32 trace = sh.theTrace;
  317.   Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
  318.   //Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
  319.   if(outputStream != 0 && 
  320.      (traceId == 0 || traceId == trace) &&
  321.      logMatch(senderBlockNo, LogOut)){
  322. #ifdef VM_TRACE_TIME
  323.     fprintf(outputStream, 
  324.     "---- Send ----- Signal (%d ms) %dn", 
  325.     delayInMilliSeconds, 
  326.     time(0));
  327. #else
  328.     fprintf(outputStream, "---- Send delay Signal (%d ms) ----------n", 
  329.     delayInMilliSeconds);
  330. #endif
  331.     printSignalHeader(outputStream, sh, prio, node, false);    
  332.     printSignalData(outputStream, sh, theData);
  333.     for (unsigned i = 0; i < secs; i++)
  334.       printSegmentedSection(outputStream, sh, ptr, i);
  335.   }
  336. }
  337. /**
  338.  * Generic messages in the signal log
  339.  */
  340. void
  341. SignalLoggerManager::log(BlockNumber bno, const char * msg)
  342. {
  343.   // Normalise blocknumber for use in logModes array
  344.   const BlockNumber bno2 = bno - MIN_BLOCK_NO;
  345.   assert(bno2<NO_OF_BLOCKS);
  346.   if(outputStream != 0 &&
  347.      logModes[bno2] != LogOff){
  348.     fprintf(outputStream, "%s: %sn", getBlockName(bno, "API"), msg);
  349.   }
  350. }
  351. void 
  352. SignalLoggerManager::printSignalHeader(FILE * output, 
  353.        const SignalHeader & sh,
  354.        Uint8 prio, 
  355.        Uint32 node,
  356.        bool printReceiversSignalId)
  357. {
  358.   Uint32 receiverBlockNo = sh.theReceiversBlockNumber;
  359.   Uint32 receiverProcessor = node;
  360.   Uint32 gsn = sh.theVerId_signalNumber;
  361.   Uint32 senderBlockNo = refToBlock(sh.theSendersBlockRef);
  362.   Uint32 senderProcessor = refToNode(sh.theSendersBlockRef);
  363.   Uint32 length = sh.theLength;
  364.   Uint32 trace = sh.theTrace;
  365.   Uint32 rSigId = sh.theSignalId;
  366.   Uint32 sSigId = sh.theSendersSignalId;
  367.   const char * signalName = getSignalName(gsn);
  368.   const char * rBlockName = getBlockName(receiverBlockNo, "API");
  369.   const char * sBlockName = getBlockName(senderBlockNo, "API");
  370.   
  371.   if(printReceiversSignalId)
  372.     fprintf(output, 
  373.     "r.bn: %d "%s", r.proc: %d, r.sigId: %d gsn: %d "%s" prio: %dn"
  374.     ,receiverBlockNo, rBlockName, receiverProcessor, rSigId, 
  375.     gsn, signalName, prio);
  376.   else 
  377.     fprintf(output,
  378.     "r.bn: %d "%s", r.proc: %d, gsn: %d "%s" prio: %dn",
  379.     receiverBlockNo, rBlockName, receiverProcessor, gsn, 
  380.     signalName, prio);
  381.   
  382.   fprintf(output, 
  383.   "s.bn: %d "%s", s.proc: %d, s.sigId: %d length: %d trace: %d "
  384.   "#sec: %d fragInf: %dn",
  385.   senderBlockNo, sBlockName, senderProcessor, sSigId, length, trace,
  386.   sh.m_noOfSections, sh.m_fragmentInfo);
  387. }
  388. void
  389. SignalLoggerManager::printSignalData(FILE * output, 
  390.      const SignalHeader & sh,
  391.      const Uint32 * signalData)
  392. {
  393.   Uint32 len = sh.theLength;
  394.   SignalDataPrintFunction printFunction = 
  395.     findPrintFunction(sh.theVerId_signalNumber);
  396.   
  397.   bool ok = false;      // done with printing
  398.   if(printFunction != 0){
  399.     ok = (* printFunction)(output, signalData, len, sh.theReceiversBlockNumber);
  400.   }
  401.   if(!ok){
  402.     while(len >= 7){
  403.       fprintf(output, 
  404.               " H'%.8x H'%.8x H'%.8x H'%.8x H'%.8x H'%.8x H'%.8xn",
  405.               signalData[0], signalData[1], signalData[2], signalData[3], 
  406.               signalData[4], signalData[5], signalData[6]);
  407.       len -= 7;
  408.       signalData += 7;
  409.     }
  410.     if(len > 0){
  411.       for(Uint32 i = 0; i<len; i++)
  412.         fprintf(output, " H'%.8x", signalData[i]);
  413.       fprintf(output, "n");
  414.     }
  415.   }
  416. }
  417. void
  418. SignalLoggerManager::printLinearSection(FILE * output,
  419.                                         const SignalHeader & sh,
  420.                                         const LinearSectionPtr ptr[3],
  421.                                         unsigned i)
  422. {
  423.   fprintf(output, "SECTION %u type=linear", i);
  424.   if (i >= 3) {
  425.     fprintf(output, " *** invalid ***n");
  426.     return;
  427.   }
  428.   const Uint32 len = ptr[i].sz;
  429.   const Uint32 * data = ptr[i].p;
  430.   Uint32 pos = 0;
  431.   fprintf(output, " size=%un", (unsigned)len);
  432.   while (pos < len) {
  433.     printDataWord(output, pos, data[pos]);
  434.   }
  435.   if (len > 0)
  436.     putc('n', output);
  437. }
  438. void
  439. SignalLoggerManager::printDataWord(FILE * output, Uint32 & pos, const Uint32 data)
  440. {
  441.   const char* const hex = "0123456789abcdef";
  442.   if (pos > 0 && pos % 7 == 0)
  443.     putc('n', output);
  444.   putc(' ', output);
  445.   putc('H', output);
  446.   putc(''', output);
  447.   for (int i = 7; i >= 0; i--)
  448.     putc(hex[(data >> (i << 2)) & 0xf], output);
  449.   pos++;
  450. }