AJA NTV2 SDK  18.1.0.2262
NTV2 SDK 18.1.0.2262
debug.cpp
Go to the documentation of this file.
1 /* SPDX-License-Identifier: MIT */
10 #include "ajabase/system/debug.h"
11 #include "ajabase/system/memory.h"
12 #include "ajabase/system/lock.h"
13 #include "ajabase/system/process.h"
14 #include "ajabase/system/system.h"
16 #include "ajabase/system/thread.h"
17 
18 #if defined(AJA_LINUX) || defined(AJA_BAREMETAL)
19  #include <stdarg.h>
20 #endif
21 #include <assert.h>
22 #include <string.h>
23 #include <stdio.h>
24 #include <time.h>
25 #include <iostream>
26 #include <iomanip>
27 #include <map>
28 
29 static std::vector<std::string> sGroupLabelVector;
30 static const std::string sSeverityString[] = {"emergency", "alert", "assert", "error", "warning", "notice", "info", "debug"};
31 static AJALock sLock;
33 static bool sDebug = false;
34 
35 #define addDebugGroupToLabelVector(x) sGroupLabelVector.push_back(#x)
36 
37 #define STAT_BIT_SHIFT (1ULL<<(inKey%64))
38 #define STAT_BIT_TEST (spShare->statAllocMask[inKey/(AJA_DEBUG_MAX_NUM_STATS/64)] & STAT_BIT_SHIFT)
39 #define IS_STAT_BAD !STAT_BIT_TEST
40 #define STAT_BIT_SET spShare->statAllocMask[inKey/(AJA_DEBUG_MAX_NUM_STATS/64)] |= STAT_BIT_SHIFT
41 #define STAT_BIT_CLEAR spShare->statAllocMask[inKey/(AJA_DEBUG_MAX_NUM_STATS/64)] &= 0xFFFFFFFFFFFFFFFF - STAT_BIT_SHIFT
42 
43 
44 AJAStatus AJADebug::Open (bool incrementRefCount)
45 {
46  if (!sLock.IsValid())
47  return AJA_STATUS_INITIALIZE;
48 
49  AJAAutoLock lock(&sLock);
50 
51  // set the debug flag
52  sDebug = false;
53 #if defined(AJA_DEBUG)
54  sDebug = true;
55 #endif
56 
57  try
58  {
59  // allocate the shared data structure for messages
60  if (!spShare)
61  {
62  // allocate the shared memory storage
63  size_t size (sizeof(AJADebugShare));
64  spShare = reinterpret_cast<AJADebugShare*>(AJAMemory::AllocateShared(&size, AJA_DEBUG_SHARE_NAME, false));
65  if (spShare == NULL || spShare == reinterpret_cast<void*>(-1))
66  {
67  spShare = NULL;
68  Close();
69  return AJA_STATUS_FAIL;
70  }
71 
72  if (size < (sizeof(AJADebugShare) - sizeof(AJADebugStat)*AJA_DEBUG_MAX_NUM_STATS))
73  { // Fail anything smaller than v110's size
74  Close();
75  return AJA_STATUS_FAIL;
76  }
77 
78  // check version
79  if (spShare->version == 0)
80  { // Initialize shared memory region...
81  ::memset(reinterpret_cast<void*>(spShare), 0, sizeof(AJADebugShare));
84  spShare->writeIndex = 0;
94  for (size_t num(0); num < size_t(AJA_DEBUG_MAX_NUM_STATS/64); num++)
95  spShare->statAllocMask[num] = 0;
97  }
98 
99  // shared data must be the correct version
101  {
102  Close();
103  return AJA_STATUS_FAIL;
104  }
105 
106  if (incrementRefCount)
107  {
108  // increment reference count;
110  }
111 
112  // Create the Unit Label Vector
113  sGroupLabelVector.clear();
181 
182  for (int i(AJA_DebugUnit_FirstUnused); i < AJA_DebugUnit_Size; i++)
183  {
184  std::string name("AJA_DebugUnit_Unused_");
185  name += aja::to_string(i);
186  sGroupLabelVector.push_back(name);
187  }
188 
189  assert(sGroupLabelVector.size() == AJA_DebugUnit_Size);
190  }
191  }
192  catch(...)
193  {
194  Close();
195  return AJA_STATUS_FAIL;
196  }
197 
198  return AJA_STATUS_SUCCESS;
199 }
200 
201 
202 AJAStatus AJADebug::Close (bool decrementRefCount)
203 {
204  AJAAutoLock lock(&sLock);
205  try
206  {
207  if (spShare)
208  {
209  if (decrementRefCount)
210  {
211  spShare->clientRefCount--; // decrement reference count
212  if (spShare->clientRefCount <= 0)
213  spShare->clientRefCount = 0;
214  }
215 
216  // free the shared data structure
217  if (spShare)
219  }
220  }
221  catch(...)
222  {
223  }
224  spShare = NULL;
225  return AJA_STATUS_SUCCESS;
226 }
227 
228 
229 AJAStatus AJADebug::Enable (int32_t index, uint32_t destination)
230 {
231  uint32_t currentDestination = 0;
232  AJAStatus status = GetDestination(index, &currentDestination);
233  if (status != AJA_STATUS_SUCCESS)
234  return status;
235  return SetDestination(index, currentDestination | destination);
236 }
237 
238 
239 AJAStatus AJADebug::Disable (int32_t index, uint32_t destination)
240 {
241  uint32_t currentDestination = 0;
242  AJAStatus status = GetDestination(index, &currentDestination);
243  if (status != AJA_STATUS_SUCCESS)
244  return status;
245  return SetDestination(index, currentDestination & ~destination);
246 }
247 
248 
249 AJAStatus AJADebug::SetDestination (int32_t index, uint32_t destination)
250 {
251  if (!spShare)
252  return AJA_STATUS_INITIALIZE; // Not open
253  if (index < 0 || index >= AJA_DEBUG_UNIT_ARRAY_SIZE)
254  return AJA_STATUS_RANGE; // Bad index
255  try
256  { // save the destination
257  spShare->unitArray[index] = destination;
258  }
259  catch(...)
260  {
261  return AJA_STATUS_FAIL;
262  }
263  return AJA_STATUS_SUCCESS;
264 }
265 
266 
267 AJAStatus AJADebug::GetDestination (const int32_t index, uint32_t & outDestination)
268 {
269  if (!spShare)
270  return AJA_STATUS_INITIALIZE;
271  if (index < 0 || index >= AJA_DEBUG_UNIT_ARRAY_SIZE)
272  return AJA_STATUS_RANGE;
273  try
274  {
275  outDestination = spShare->unitArray[index];
276  }
277  catch(...)
278  {
279  return AJA_STATUS_FAIL;
280  }
281  return AJA_STATUS_SUCCESS;
282 }
283 
284 
285 bool AJADebug::IsActive (int32_t index)
286 {
287  if (!spShare)
288  return false; // Not open
289  if (index < 0 || index >= AJA_DEBUG_UNIT_ARRAY_SIZE)
290  return false; // Bad index
291  try
292  { // if no destination return false
294  return false;
295  }
296  catch(...)
297  {
298  return false;
299  }
300  return true;
301 }
302 
303 uint32_t AJADebug::Version (void)
304 {
305  if (!spShare)
306  return 0; // Not open
307  return spShare->version;
308 }
309 
310 uint32_t AJADebug::TotalBytes (void)
311 {
312  if (!spShare)
313  return 0; // Not open
314  if (HasStats())
315  return uint32_t(sizeof(AJADebugShare));
316  return uint32_t(sizeof(AJADebugShare)) - AJA_DEBUG_MAX_NUM_STATS * uint32_t(sizeof(AJADebugStat));
317 }
318 
319 bool AJADebug::IsOpen (void)
320 {
321  return spShare != NULL;
322 }
323 
324 
326 {
327  return sDebug;
328 }
329 
330 inline int64_t debug_time (void)
331 {
332  int64_t ticks = AJATime::GetSystemCounter();
333  int64_t rate = AJATime::GetSystemFrequency();
334  int64_t time = ticks / rate * AJA_DEBUG_TICK_RATE;
335  time += (ticks % rate) * AJA_DEBUG_TICK_RATE / rate;
336  return time;
337 }
338 
339 inline uint64_t report_common(int32_t index, int32_t severity, const char* pFileName, int32_t lineNumber, uint64_t& writeIndex, int32_t& messageIndex)
340 {
341  static const char * spUnknown = "unknown";
342  if (!spShare)
343  return false;
344 
345  // check for active client to receive messages
346  if (spShare->clientRefCount <= 0)
347  {
348  // nobody is listening so bail quickly
349  return false;
350  }
351 
352  // check for valid index
353  if ((index < 0) || (index >= AJA_DEBUG_UNIT_ARRAY_SIZE))
354  {
355  index = AJA_DebugUnit_Unknown;
356  }
357  // check for destination
359  {
361  return false;
362  }
363 
364  // check for valid severity
365  if ((severity < 0) || (severity >= AJA_DebugSeverity_Size))
366  {
367  severity = AJA_DebugSeverity_Warning;
368  }
369 
370  // check for valid file name
371  if (!pFileName)
372  pFileName = spUnknown;
373 
374  // increment the message write index
375  writeIndex = AJAAtomic::Increment(&spShare->writeIndex);
376 
377  // modulo the ring size to determine the message array index
378  messageIndex = writeIndex % AJA_DEBUG_MESSAGE_RING_SIZE;
379 
380  // save the message data
381  spShare->messageRing[messageIndex].groupIndex = index;
382  spShare->messageRing[messageIndex].destinationMask = spShare->unitArray[index];
383  spShare->messageRing[messageIndex].time = debug_time();
384  spShare->messageRing[messageIndex].wallTime = (int64_t)time(NULL);
385  aja::safer_strncpy(spShare->messageRing[messageIndex].fileName, pFileName, strlen(pFileName), AJA_DEBUG_FILE_NAME_MAX_SIZE);
386  spShare->messageRing[messageIndex].lineNumber = lineNumber;
387  spShare->messageRing[messageIndex].severity = severity;
388  spShare->messageRing[messageIndex].pid = AJAProcess::GetPid();
389  spShare->messageRing[messageIndex].tid = AJAThread::GetThreadId();
390 
391  return true;
392 }
393 
394 
395 void AJADebug::Report (int32_t index, int32_t severity, const char* pFileName, int32_t lineNumber, ...)
396 {
397  if (!spShare)
398  return; // Not open
399  try
400  {
401  uint64_t writeIndex = 0;
402  int32_t messageIndex = 0;
403  if (report_common(index, severity, pFileName, lineNumber, writeIndex, messageIndex))
404  {
405  // format the message
406  va_list vargs;
407  va_start(vargs, lineNumber);
408  const char* pFormat = va_arg(vargs, const char*);
409  // check for valid message
410  if (pFormat == NULL)
411  {
412  pFormat = (char*) "no message";
413  }
414  ajavsnprintf(spShare->messageRing[messageIndex].messageText,
416  pFormat, vargs);
417  va_end(vargs);
418 
419  // set last to indicate message complete
420  AJAAtomic::Exchange(&spShare->messageRing[messageIndex].sequenceNumber, writeIndex);
422  }
423  }
424  catch (...)
425  {
426  }
427 }
428 
429 
430 void AJADebug::Report (int32_t index, int32_t severity, const char* pFileName, int32_t lineNumber, const std::string& message)
431 {
432  if (!spShare)
433  return; // Not open
434  try
435  {
436  uint64_t writeIndex = 0;
437  int32_t messageIndex = 0;
438  if (report_common(index, severity, pFileName, lineNumber, writeIndex, messageIndex))
439  {
440  // copy the message
441  aja::safer_strncpy(spShare->messageRing[messageIndex].messageText, message.c_str(), message.length()+1, AJA_DEBUG_MESSAGE_MAX_SIZE);
442 
443  // set last to indicate message complete
444  AJAAtomic::Exchange(&spShare->messageRing[messageIndex].sequenceNumber, writeIndex);
446  }
447  }
448  catch (...)
449  {
450  }
451 }
452 
453 void AJADebug::AssertWithMessage (const char* pFileName, int32_t lineNumber, const std::string& pExpression)
454 {
455 #if defined(AJA_DEBUG)
456  // check for open
457  if (!spShare)
458  assert(false);
459 
460  try
461  {
462  // check for active client to receive messages
463  if (spShare->clientRefCount > 0)
464  {
465  // check for valid file name
466  if (pFileName == NULL)
467  {
468  pFileName = (char*) "unknown";
469  }
470 
471  // increment the message write index
472  uint64_t writeIndex = AJAAtomic::Increment(&spShare->writeIndex);
473 
474  // modulo the ring size to determine the message array index
475  int32_t messageIndex = writeIndex % AJA_DEBUG_MESSAGE_RING_SIZE;
476 
477  // save the message data
480  spShare->messageRing[messageIndex].time = debug_time();
481  spShare->messageRing[messageIndex].wallTime = (int64_t)time(NULL);
482  aja::safer_strncpy(spShare->messageRing[messageIndex].fileName, pFileName, strlen(pFileName), AJA_DEBUG_FILE_NAME_MAX_SIZE);
483  spShare->messageRing[messageIndex].lineNumber = lineNumber;
485  spShare->messageRing[messageIndex].pid = AJAProcess::GetPid();
486  spShare->messageRing[messageIndex].tid = AJAThread::GetThreadId();
487 
488  // format the message
489  ajasnprintf(spShare->messageRing[messageIndex].messageText,
491  "assertion failed (file %s, line %d): %s\n",
492  pFileName, lineNumber, pExpression.c_str());
493 
494  // set last to indicate message complete
495  AJAAtomic::Exchange(&spShare->messageRing[messageIndex].sequenceNumber, writeIndex);
497  }
498  }
499  catch (...)
500  {
501  }
502 
503  assert(false);
504 #else
505  AJA_UNUSED(pFileName);
506  AJA_UNUSED(lineNumber);
507  AJA_UNUSED(pExpression);
508 #endif
509 }
510 
511 
513 {
514  if (!spShare)
515  return 0;
517 }
518 
519 
521 {
522  outRefCount = 0;
523  if (!spShare)
524  return AJA_STATUS_INITIALIZE;
525  try
526  {
527  outRefCount = spShare->clientRefCount;
528  }
529  catch(...)
530  {
531  return AJA_STATUS_FAIL;
532  }
533  return AJA_STATUS_SUCCESS;
534 }
535 
536 
538 {
539  if (!spShare)
540  return AJA_STATUS_INITIALIZE;
541  try
542  {
543  spShare->clientRefCount = refCount;
544  if (refCount <= 0)
545  {
546  // this will handle shuting everything down if ref count goes to 0 or less
547  AJADebug::Close();
548  }
549  }
550  catch(...)
551  {
552  return AJA_STATUS_FAIL;
553  }
554  return AJA_STATUS_SUCCESS;
555 }
556 
557 
558 AJAStatus AJADebug::GetSequenceNumber (uint64_t & outSequenceNumber)
559 {
560  if (!spShare)
561  return AJA_STATUS_INITIALIZE;
562  try
563  {
564  outSequenceNumber = spShare->writeIndex;
565  }
566  catch(...)
567  {
568  return AJA_STATUS_FAIL;
569  }
570  return AJA_STATUS_SUCCESS;
571 }
572 
573 
574 AJAStatus AJADebug::GetMessageSequenceNumber (const uint64_t sequenceNumber, uint64_t & outSequenceNumber)
575 {
576  if (!spShare)
577  return AJA_STATUS_INITIALIZE;
578  if (sequenceNumber > spShare->writeIndex)
579  return AJA_STATUS_RANGE;
580  try
581  {
582  outSequenceNumber = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].sequenceNumber;
583  }
584  catch(...)
585  {
586  return AJA_STATUS_FAIL;
587  }
588  return AJA_STATUS_SUCCESS;
589 }
590 
591 
592 AJAStatus AJADebug::GetMessageGroup (const uint64_t sequenceNumber, int32_t & outGroupIndex)
593 {
594  if (!spShare)
595  return AJA_STATUS_INITIALIZE;
596  if (sequenceNumber > spShare->writeIndex)
597  return AJA_STATUS_RANGE;
598  try
599  {
600  outGroupIndex = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].groupIndex;
601  }
602  catch(...)
603  {
604  return AJA_STATUS_FAIL;
605  }
606  return AJA_STATUS_SUCCESS;
607 }
608 
609 
610 AJAStatus AJADebug::GetMessageDestination (const uint64_t sequenceNumber, uint32_t & outDestination)
611 {
612  if (!spShare)
613  return AJA_STATUS_INITIALIZE;
614  if (sequenceNumber > spShare->writeIndex)
615  return AJA_STATUS_RANGE;
616  try
617  {
618  outDestination = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].destinationMask;
619  }
620  catch(...)
621  {
622  return AJA_STATUS_FAIL;
623  }
624  return AJA_STATUS_SUCCESS;
625 }
626 
627 
628 AJAStatus AJADebug::GetMessageTime (const uint64_t sequenceNumber, uint64_t & outTime)
629 {
630  if (!spShare)
631  return AJA_STATUS_INITIALIZE;
632  if (sequenceNumber > spShare->writeIndex)
633  return AJA_STATUS_RANGE;
634  try
635  {
636  outTime = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].time;
637  }
638  catch(...)
639  {
640  return AJA_STATUS_FAIL;
641  }
642  return AJA_STATUS_SUCCESS;
643 }
644 
645 AJAStatus AJADebug::GetMessageWallClockTime (const uint64_t sequenceNumber, int64_t & outTime)
646 {
647  if (!spShare)
648  return AJA_STATUS_INITIALIZE;
649  if (sequenceNumber > spShare->writeIndex)
650  return AJA_STATUS_RANGE;
651  try
652  {
653  outTime = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].wallTime;
654  }
655  catch(...)
656  {
657  return AJA_STATUS_FAIL;
658  }
659  return AJA_STATUS_SUCCESS;
660 }
661 
662 AJAStatus AJADebug::GetMessageFileName (const uint64_t sequenceNumber, std::string & outFileName)
663 {
664  outFileName.clear();
665  if (!spShare)
666  return AJA_STATUS_INITIALIZE;
667  if (sequenceNumber > spShare->writeIndex)
668  return AJA_STATUS_RANGE;
669  try
670  {
671  outFileName = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].fileName;
672  }
673  catch(...)
674  {
675  return AJA_STATUS_FAIL;
676  }
677  return AJA_STATUS_SUCCESS;
678 }
679 
680 AJAStatus AJADebug::GetMessageFileName (uint64_t sequenceNumber, const char** ppFileName)
681 {
682  if (!spShare)
683  return AJA_STATUS_INITIALIZE;
684  if (sequenceNumber > spShare->writeIndex)
685  return AJA_STATUS_RANGE;
686  if (ppFileName == NULL)
687  return AJA_STATUS_NULL;
688  try
689  {
690  *ppFileName = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].fileName;
691  }
692  catch(...)
693  {
694  return AJA_STATUS_FAIL;
695  }
696  return AJA_STATUS_SUCCESS;
697 }
698 
699 
700 AJAStatus AJADebug::GetMessageLineNumber (const uint64_t sequenceNumber, int32_t & outLineNumber)
701 {
702  if (!spShare)
703  return AJA_STATUS_INITIALIZE;
704  if (sequenceNumber > spShare->writeIndex)
705  return AJA_STATUS_RANGE;
706  try
707  {
708  outLineNumber = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].lineNumber;
709  }
710  catch(...)
711  {
712  return AJA_STATUS_FAIL;
713  }
714  return AJA_STATUS_SUCCESS;
715 }
716 
717 
718 AJAStatus AJADebug::GetMessageSeverity (const uint64_t sequenceNumber, int32_t & outSeverity)
719 {
720  if (!spShare)
721  return AJA_STATUS_INITIALIZE;
722  if (sequenceNumber > spShare->writeIndex)
723  return AJA_STATUS_RANGE;
724  try
725  {
726  outSeverity = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].severity;
727  }
728  catch(...)
729  {
730  return AJA_STATUS_FAIL;
731  }
732  return AJA_STATUS_SUCCESS;
733 }
734 
735 
736 AJAStatus AJADebug::GetMessageText (const uint64_t sequenceNumber, std::string & outMessage)
737 {
738  outMessage.clear();
739  if (!spShare)
740  return AJA_STATUS_INITIALIZE;
741  if (sequenceNumber > spShare->writeIndex)
742  return AJA_STATUS_RANGE;
743  try
744  {
745  outMessage = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].messageText;
746  }
747  catch(...)
748  {
749  return AJA_STATUS_FAIL;
750  }
751  return AJA_STATUS_SUCCESS;
752 }
753 
754 AJAStatus AJADebug::GetMessageText (uint64_t sequenceNumber, const char** ppMessage)
755 {
756  if (!spShare)
757  return AJA_STATUS_INITIALIZE;
758  if (sequenceNumber > spShare->writeIndex)
759  return AJA_STATUS_RANGE;
760  if (!ppMessage)
761  return AJA_STATUS_NULL;
762  try
763  {
764  *ppMessage = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].messageText;
765  }
766  catch(...)
767  {
768  return AJA_STATUS_FAIL;
769  }
770  return AJA_STATUS_SUCCESS;
771 }
772 
773 
774 AJAStatus AJADebug::GetProcessId (const uint64_t sequenceNumber, uint64_t & outPid)
775 {
776  if (!spShare)
777  return AJA_STATUS_INITIALIZE;
778  if (sequenceNumber > spShare->writeIndex)
779  return AJA_STATUS_RANGE;
780  try
781  {
782  outPid = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].pid;
783  }
784  catch(...)
785  {
786  return AJA_STATUS_FAIL;
787  }
788  return AJA_STATUS_SUCCESS;
789 }
790 
791 
792 AJAStatus AJADebug::GetThreadId (const uint64_t sequenceNumber, uint64_t & outTid)
793 {
794  if (!spShare)
795  return AJA_STATUS_INITIALIZE;
796  if (sequenceNumber > spShare->writeIndex)
797  return AJA_STATUS_RANGE;
798  try
799  {
800  outTid = spShare->messageRing[sequenceNumber%AJA_DEBUG_MESSAGE_RING_SIZE].tid;
801  }
802  catch(...)
803  {
804  return AJA_STATUS_FAIL;
805  }
806  return AJA_STATUS_SUCCESS;
807 }
808 
809 
811 {
812  if (!spShare)
813  return AJA_STATUS_INITIALIZE;
814  try
815  {
816  outCount = spShare->statsMessagesAccepted;
817  }
818  catch(...)
819  {
820  return AJA_STATUS_FAIL;
821  }
822  return AJA_STATUS_SUCCESS;
823 }
824 
825 
827 {
828  if (!spShare)
829  return AJA_STATUS_INITIALIZE;
830  try
831  {
832  outCount = spShare->statsMessagesIgnored;
833  }
834  catch(...)
835  {
836  return AJA_STATUS_FAIL;
837  }
838  return AJA_STATUS_SUCCESS;
839 }
840 
841 
842 const char* AJADebug::GetSeverityString (int32_t severity)
843 {
844  if (severity < 0 || severity > 7)
845  return "severity range error";
846  return sSeverityString[severity].c_str();
847 }
848 
849 const std::string & AJADebug::SeverityName (const int32_t severity)
850 { static const std::string emptystr;
851  if (severity < 0 || severity > 7)
852  return emptystr;
853  return sSeverityString[severity];
854 }
855 
856 
857 const char* AJADebug::GetGroupString (int32_t group)
858 {
859  if (group < 0 || group >= int32_t(sGroupLabelVector.size()))
860  return "index range error";
861  if (sGroupLabelVector.at(size_t(group)).empty())
862  return "no label";
863  return sGroupLabelVector.at(size_t(group)).c_str();
864 }
865 
866 
867 const std::string & AJADebug::GroupName (const int32_t group)
868 {
869  static const std::string sRangeErr("<bad index>");
870  static const std::string sNoLabelErr("<empty>");
871  if (group < 0 || group >= int32_t(sGroupLabelVector.size()))
872  return sRangeErr;
873  if (sGroupLabelVector.at(size_t(group)).empty())
874  return sNoLabelErr;
875  return sGroupLabelVector.at(size_t(group));
876 }
877 
878 
879 AJAStatus AJADebug::SaveState (const std::string & inFilePath)
880 {
881  FILE* pFile(0);
882  if (!spShare)
883  return AJA_STATUS_INITIALIZE;
884 
885  // open a new state file
886  pFile = ::fopen(inFilePath.c_str(), "w");
887  if (!pFile)
888  return AJA_STATUS_FAIL;
889 
890  try
891  { // write the header
892  fprintf(pFile, "AJADebugVersion: %d\n", spShare->version);
893  fprintf(pFile, "AJADebugStateFileVersion: %d\n", AJA_DEBUG_STATE_FILE_VERSION);
894  for (int i = 0; i < AJA_DEBUG_UNIT_ARRAY_SIZE; i++)
895  {
896  // write groups with destinations enabled
897  if (spShare->unitArray[i])
898  {
899  if (i < AJA_DebugUnit_Size)
900  fprintf(pFile, "GroupDestination: %6d : %08x\n", i, spShare->unitArray[i]);
901  else
902  fprintf(pFile, "CustomGroupDestination: %6d : %08x\n", i, spShare->unitArray[i]);
903  }
904  }
905  }
906  catch(...)
907  {
908  return AJA_STATUS_FAIL;
909  }
910  fclose(pFile);
911  return AJA_STATUS_SUCCESS;
912 }
913 
914 
915 AJAStatus AJADebug::RestoreState (const std::string & inFilePath)
916 {
917  FILE* pFile(0);
918  if (!spShare)
919  return AJA_STATUS_INITIALIZE;
920 
921  // open existing file
922  pFile = ::fopen(inFilePath.c_str(), "r");
923  if (!pFile)
924  return AJA_STATUS_FAIL;
925 
926  try
927  {
928  int32_t count;
929  uint32_t version;
930  int32_t index;
931  uint32_t destination;
932  int intVersion;
933 
934  // read the header
935  count = fscanf(pFile, " AJADebugVersion: %d", &intVersion);
936  version = intVersion;
937  if((count != 1) || (version != spShare->version))
938  {
939  fclose(pFile);
940  return AJA_STATUS_FAIL;
941  }
942  count = fscanf(pFile, " AJADebugStateFileVersion: %d", &intVersion);
943  version = intVersion;
944  if((count != 1) || (version != AJA_DEBUG_STATE_FILE_VERSION))
945  {
946  fclose(pFile);
947  return AJA_STATUS_FAIL;
948  }
949 
950  while(true)
951  {
952  // read groups that have destinations
953  count = fscanf(pFile, " GroupDestination: %d : %x", &index, &destination);
954  if (count != 2)
955  {
956  count = fscanf(pFile, " CustomGroupDestination: %d : %x", &index, &destination);
957  if (count != 2)
958  break;
959  }
960 
961  // index must be in range
962  if ((index < 0) || (index >= AJA_DEBUG_UNIT_ARRAY_SIZE))
963  continue;
964 
965  // update the destination
966  spShare->unitArray[index] = destination;
967  }
968  }
969  catch(...)
970  {
971  ::fclose(pFile);
972  return AJA_STATUS_FAIL;
973  }
974 
975  ::fclose(pFile);
976  return AJA_STATUS_SUCCESS;
977 }
978 
979 
980 int64_t AJADebug::DebugTime (void)
981 {
982  // wrapper around the inlined local version
983  return debug_time();
984 }
985 
986 
987 std::string AJAStatusToString (const AJAStatus inStatus, const bool inDetailed)
988 {
989  switch (inStatus)
990  {
991  case AJA_STATUS_SUCCESS: return inDetailed ? "Success" : "AJA_STATUS_SUCCESS";
992  case AJA_STATUS_TRUE: return inDetailed ? "True" : "AJA_STATUS_TRUE";
993  case AJA_STATUS_UNKNOWN: return inDetailed ? "Unknown Error" : "AJA_STATUS_UNKNOWN";
994  case AJA_STATUS_FAIL: return inDetailed ? "Failed" : "AJA_STATUS_FAIL";
995  case AJA_STATUS_TIMEOUT: return inDetailed ? "Timed Out" : "AJA_STATUS_TIMEOUT";
996  case AJA_STATUS_RANGE: return inDetailed ? "Out Of Range" : "AJA_STATUS_RANGE";
997  case AJA_STATUS_INITIALIZE: return inDetailed ? "Initialize" : "AJA_STATUS_INITIALIZE";
998  case AJA_STATUS_NULL: return inDetailed ? "Null" : "AJA_STATUS_NULL";
999  case AJA_STATUS_OPEN: return inDetailed ? "Not Open" : "AJA_STATUS_OPEN";
1000  case AJA_STATUS_IO: return inDetailed ? "I/O Error" : "AJA_STATUS_IO";
1001  case AJA_STATUS_DISABLED: return inDetailed ? "Disabled" : "AJA_STATUS_DISABLED";
1002  case AJA_STATUS_BUSY: return inDetailed ? "Busy" : "AJA_STATUS_BUSY";
1003  case AJA_STATUS_BAD_PARAM: return inDetailed ? "Bad Param" : "AJA_STATUS_BAD_PARAM";
1004  case AJA_STATUS_FEATURE: return inDetailed ? "Feature" : "AJA_STATUS_FEATURE";
1005  case AJA_STATUS_UNSUPPORTED: return inDetailed ? "Unsupported" : "AJA_STATUS_UNSUPPORTED";
1006  case AJA_STATUS_READONLY: return inDetailed ? "Read-Only" : "AJA_STATUS_READONLY";
1007  case AJA_STATUS_WRITEONLY: return inDetailed ? "Write-Only" : "AJA_STATUS_WRITEONLY";
1008  case AJA_STATUS_MEMORY: return inDetailed ? "Out Of Memory" : "AJA_STATUS_MEMORY";
1009  case AJA_STATUS_ALIGN: return inDetailed ? "Misaligned" : "AJA_STATUS_ALIGN";
1010  case AJA_STATUS_FLUSH: return inDetailed ? "Flush" : "AJA_STATUS_FLUSH";
1011  case AJA_STATUS_NOINPUT: return inDetailed ? "No Input" : "AJA_STATUS_NOINPUT";
1012  case AJA_STATUS_SURPRISE_REMOVAL: return inDetailed ? "Surprise Removal" : "AJA_STATUS_SURPRISE_REMOVAL";
1013  case AJA_STATUS_NOT_FOUND: return inDetailed ? "Not Found" : "AJA_STATUS_NOT_FOUND";
1014  case AJA_STATUS_NOBUFFER: return inDetailed ? "No Buffer" : "AJA_STATUS_NOBUFFER";
1015  case AJA_STATUS_INVALID_TIME: return inDetailed ? "Invalid Time" : "AJA_STATUS_INVALID_TIME";
1016  case AJA_STATUS_NOSTREAM: return inDetailed ? "No Stream" : "AJA_STATUS_NOSTREAM";
1017  case AJA_STATUS_TIMEEXPIRED: return inDetailed ? "Time Expired" : "AJA_STATUS_TIMEEXPIRED";
1018  case AJA_STATUS_BADBUFFERCOUNT: return inDetailed ? "Bad Buffer Count" : "AJA_STATUS_BADBUFFERCOUNT";
1019  case AJA_STATUS_BADBUFFERSIZE: return inDetailed ? "Bad Buffer Size" : "AJA_STATUS_BADBUFFERSIZE";
1020  case AJA_STATUS_STREAMCONFLICT: return inDetailed ? "Stream Conflict" : "AJA_STATUS_STREAMCONFLICT";
1021  case AJA_STATUS_NOTINITIALIZED: return inDetailed ? "Uninitialized" : "AJA_STATUS_NOTINITIALIZED";
1022  case AJA_STATUS_STREAMRUNNING: return inDetailed ? "Stream Running" : "AJA_STATUS_STREAMRUNNING";
1023  case AJA_STATUS_REBOOT: return inDetailed ? "Reboot" : "AJA_STATUS_REBOOT";
1024  case AJA_STATUS_POWER_CYCLE: return inDetailed ? "Power Cycle" : "AJA_STATUS_POWER_CYCLE";
1025 #if !defined(_DEBUG)
1026  default: break;
1027 #endif
1028  }
1029  return "<bad AJAStatus>";
1030 }
1031 
1032 
1034 {
1035  if (!sLock.IsValid())
1036  return NULL;
1037  AJAAutoLock lock(&sLock);
1038  return spShare;
1039 }
1040 
1041 
1043 {
1044  if (!sLock.IsValid())
1045  return 0;
1046  AJAAutoLock lock(&sLock);
1047  return spShare ? sizeof(AJADebugShare) : 0;
1048 }
1049 
1050 
1052 {
1053  if (!spShare)
1054  return 0;
1055  return spShare->statCapacity;
1056 }
1057 
1059 {
1060  return StatsCapacity() ? true : false;
1061 }
1062 
1063 AJAStatus AJADebug::StatAllocate (const uint32_t inKey)
1064 {
1065  if (!spShare)
1066  return AJA_STATUS_INITIALIZE;
1067  if (inKey >= spShare->statCapacity)
1068  return AJA_STATUS_RANGE;
1069  try
1070  {
1071  if (STAT_BIT_TEST)
1072  return AJA_STATUS_FAIL;
1073  STAT_BIT_SET;
1075  return StatReset(inKey);
1076  }
1077  catch(...)
1078  {
1079  return AJA_STATUS_FAIL;
1080  }
1081  return AJA_STATUS_SUCCESS;
1082 }
1083 
1084 AJAStatus AJADebug::StatFree (const uint32_t inKey)
1085 {
1086  if (!spShare)
1087  return AJA_STATUS_INITIALIZE;
1088  if (inKey >= spShare->statCapacity)
1089  return AJA_STATUS_RANGE;
1090  try
1091  {
1092  if (IS_STAT_BAD)
1093  return AJA_STATUS_FAIL;
1094  StatReset(inKey);
1097  }
1098  catch(...)
1099  {
1100  return AJA_STATUS_FAIL;
1101  }
1102  return AJA_STATUS_SUCCESS;
1103 }
1104 
1105 bool AJADebug::StatIsAllocated (const uint32_t inKey)
1106 {
1107  if (!spShare)
1108  return false;
1109  if (inKey >= spShare->statCapacity)
1110  return false;
1111  try
1112  {
1113  return IS_STAT_BAD ? false : true;
1114  }
1115  catch(...)
1116  {
1117  return false;
1118  }
1119 }
1120 
1121 AJAStatus AJADebug::StatReset (const uint32_t inKey)
1122 {
1123  if (!spShare)
1124  return AJA_STATUS_INITIALIZE;
1125  if (inKey >= spShare->statCapacity)
1126  return AJA_STATUS_RANGE;
1127  try
1128  {
1129  if (IS_STAT_BAD)
1130  return AJA_STATUS_FAIL;
1131  AJADebugStat & stat(spShare->stats[inKey]);
1132  stat.Reset();
1133  }
1134  catch(...)
1135  {
1136  return AJA_STATUS_FAIL;
1137  }
1138  return AJA_STATUS_SUCCESS;
1139 }
1140 
1141 AJAStatus AJADebug::StatTimerStart (const uint32_t inKey)
1142 {
1143  if (!spShare)
1144  return AJA_STATUS_INITIALIZE;
1145  if (inKey >= spShare->statCapacity)
1146  return AJA_STATUS_RANGE;
1147  try
1148  {
1149  if (IS_STAT_BAD)
1150  return AJA_STATUS_FAIL;
1151  AJADebugStat & stat(spShare->stats[inKey]);
1152  stat.Start();
1153  }
1154  catch(...)
1155  {
1156  return AJA_STATUS_FAIL;
1157  }
1158  return AJA_STATUS_SUCCESS;
1159 }
1160 
1161 AJAStatus AJADebug::StatTimerStop (const uint32_t inKey)
1162 {
1163  if (!spShare)
1164  return AJA_STATUS_INITIALIZE;
1165  if (inKey >= spShare->statCapacity)
1166  return AJA_STATUS_RANGE;
1167  try
1168  {
1169  if (IS_STAT_BAD)
1170  return AJA_STATUS_FAIL;
1171  AJADebugStat & stat(spShare->stats[inKey]);
1172  stat.Stop();
1173  }
1174  catch(...)
1175  {
1176  return AJA_STATUS_FAIL;
1177  }
1178  return AJA_STATUS_SUCCESS;
1179 }
1180 
1181 #define HEX0N(__x__,__n__) std::hex << std::uppercase << std::setw(int(__n__)) << std::setfill('0') << (__x__) << std::dec << std::setfill(' ') << std::nouppercase
1182 
1183 AJAStatus AJADebug::StatCounterIncrement (const uint32_t inKey, const uint32_t inIncrement)
1184 {
1185  if (!spShare)
1186  return AJA_STATUS_INITIALIZE;
1187  if (inKey >= spShare->statCapacity)
1188  return AJA_STATUS_RANGE;
1189  try
1190  {
1191  if (IS_STAT_BAD)
1192  return AJA_STATUS_FAIL;
1193  AJADebugStat & stat(spShare->stats[inKey]);
1194  stat.IncrementCount(inIncrement);
1195 if (inKey == 11)
1196 { const uint32_t * pU32(&stat.fMin);
1197  for (size_t num(0); num < 16; num++)
1198  std::cerr << " " << HEX0N(*pU32++,8);
1199  std::cerr << std::endl;
1200 }
1201  }
1202  catch(...)
1203  {
1204  return AJA_STATUS_FAIL;
1205  }
1206  return AJA_STATUS_SUCCESS;
1207 }
1208 
1209 AJAStatus AJADebug::StatSetValue (const uint32_t inKey, const uint32_t inValue)
1210 {
1211  if (!spShare)
1212  return AJA_STATUS_INITIALIZE;
1213  if (inKey >= spShare->statCapacity)
1214  return AJA_STATUS_RANGE;
1215  try
1216  {
1217  if (IS_STAT_BAD)
1218  return AJA_STATUS_FAIL;
1219  AJADebugStat & stat(spShare->stats[inKey]);
1220  stat.SetValue(inValue);
1221  }
1222  catch(...)
1223  {
1224  return AJA_STATUS_FAIL;
1225  }
1226  return AJA_STATUS_SUCCESS;
1227 }
1228 
1229 AJAStatus AJADebug::StatGetInfo (const uint32_t inKey, AJADebugStat & outInfo)
1230 {
1231  if (!spShare)
1232  return AJA_STATUS_INITIALIZE;
1233  if (inKey >= spShare->statCapacity)
1234  return AJA_STATUS_RANGE;
1235  try
1236  {
1237  if (IS_STAT_BAD)
1238  return AJA_STATUS_FAIL;
1239  outInfo = spShare->stats[inKey];
1240  }
1241  catch(...)
1242  {
1243  return AJA_STATUS_FAIL;
1244  }
1245  return AJA_STATUS_SUCCESS;
1246 }
1247 
1248 AJAStatus AJADebug::StatGetKeys (std::vector<uint32_t> & outKeys, uint32_t & outSeqNum)
1249 {
1250  outKeys.clear();
1251  outSeqNum = 0;
1252  if (!spShare)
1253  return AJA_STATUS_INITIALIZE;
1254  if (!spShare->statCapacity)
1255  return AJA_STATUS_FEATURE;
1256  try
1257  {
1258  for (uint32_t inKey(0); inKey < spShare->statCapacity; inKey++)
1259  if (STAT_BIT_TEST)
1260  outKeys.push_back(inKey);
1261  outSeqNum = spShare->statAllocChanges;
1262  }
1263  catch(...)
1264  {
1265  return AJA_STATUS_FAIL;
1266  }
1267  return AJA_STATUS_SUCCESS;
1268 }
1269 
1270 AJAStatus AJADebug::StatGetKeys (std::set<uint32_t> & outKeys, uint32_t & outSeqNum)
1271 {
1272  outKeys.clear();
1273  outSeqNum = 0;
1274  if (!spShare)
1275  return AJA_STATUS_INITIALIZE;
1276  if (!spShare->statCapacity)
1277  return AJA_STATUS_FEATURE;
1278  try
1279  {
1280  for (uint32_t inKey(0); inKey < spShare->statCapacity; inKey++)
1281  if (STAT_BIT_TEST)
1282  outKeys.insert(inKey);
1283  outSeqNum = spShare->statAllocChanges;
1284  }
1285  catch(...)
1286  {
1287  return AJA_STATUS_FAIL;
1288  }
1289  return AJA_STATUS_SUCCESS;
1290 }
1291 
1293 {
1294  outSeqNum = 0;
1295  if (!spShare)
1296  return AJA_STATUS_INITIALIZE;
1297  if (!spShare->statCapacity)
1298  return AJA_STATUS_FEATURE;
1299  outSeqNum = spShare->statAllocChanges;
1300  return AJA_STATUS_SUCCESS;
1301 }
1302 
1303 uint64_t AJADebugStat::Sum (size_t inNum) const
1304 {
1305  uint64_t result(0);
1306  if (!inNum)
1307  return result;
1308  if (inNum > AJA_DEBUG_STAT_DEQUE_SIZE)
1309  inNum = AJA_DEBUG_STAT_DEQUE_SIZE;
1310  for (size_t n(0); n < inNum; n++)
1311  result += fValues[n];
1312  return result;
1313 }
1314 
1315 uint32_t AJADebugStat::Minimum (size_t inNum) const
1316 {
1317  uint32_t result(0xFFFFFFFF);
1318  if (!inNum)
1319  return result;
1320  if (inNum > AJA_DEBUG_STAT_DEQUE_SIZE)
1321  inNum = AJA_DEBUG_STAT_DEQUE_SIZE;
1322  for (size_t n(0); n < inNum; n++)
1323  if (fValues[n] < result)
1324  result = fValues[n];
1325  return result;
1326 }
1327 
1328 uint32_t AJADebugStat::Maximum (size_t inNum) const
1329 {
1330  uint32_t result(0);
1331  if (!inNum)
1332  return result;
1333  if (inNum > AJA_DEBUG_STAT_DEQUE_SIZE)
1334  inNum = AJA_DEBUG_STAT_DEQUE_SIZE;
1335  for (size_t n(0); n < inNum; n++)
1336  if (fValues[n] > result)
1337  result = fValues[n];
1338  return result;
1339 }
1340 
1341 double AJADebugStat::Average(void) const
1342 {
1343  if (!fCount)
1344  return 0.00;
1345  if (fCount < 2)
1346  return double(fValues[0]);
1348 }
1349 
1351 {
1353 }
1354 
1356 {
1357  if (!fLastTimeStamp)
1358  return false; // Never started
1359  const uint64_t now(AJATime::GetSystemMicroseconds());
1360  if (now <= fLastTimeStamp)
1361  return false; // Should never happen
1362  SetValue(uint32_t(now - fLastTimeStamp));
1363  return true;
1364 }
1365 
1366 bool AJADebugStat::IncrementCount (uint32_t inIncrement, const bool inRollOver)
1367 {
1368  if (!inIncrement)
1369  return false; // Increment value must be non-zero
1370  if (!inRollOver && fCount == 0xFFFFFFFF)
1371  return false; // At rollover point, but not allowed
1372 
1373  while (inIncrement--)
1376  return true;
1377 }
1378 
1379 bool AJADebugStat::DecrementCount (uint32_t inDecrement, const bool inRollUnder)
1380 {
1381  if (!inDecrement)
1382  return false; // Decrement value must be non-zero
1383  if (!inRollUnder && !fCount)
1384  return false; // At rollunder point, but not allowed
1385 
1386  while (inDecrement--)
1389  return true;
1390 }
1391 
1392 void AJADebugStat::SetValue (const uint32_t inValue)
1393 {
1395  if (inValue < fMin)
1396  fMin = inValue;
1397  if (inValue > fMax)
1398  fMax = inValue;
1399  IncrementCount();
1400 }
1401 
1402 bool AJADebugStat::operator == (const AJADebugStat & inRHS) const
1403 {
1404  if (this == &inRHS)
1405  return true; // Same object, identical
1406  if (fCount != inRHS.fCount)
1407  return false;
1408  if (fLastTimeStamp != inRHS.fLastTimeStamp)
1409  return false;
1410  for (size_t n(0); n < AJA_DEBUG_STAT_DEQUE_SIZE; n++)
1411  if (fValues[n] != inRHS.fValues[n])
1412  return false;
1413  if (fMin != inRHS.fMin)
1414  return false;
1415  if (fMax != inRHS.fMax)
1416  return false;
1417  return true;
1418 }
1419 
1420 using namespace std;
1421 
1422 // Dictionary of Well-Known Stats:
1423 typedef map<int,string> StatKeyNameMap;
1424 typedef pair<int,string> StatKeyNamePair;
1425 typedef StatKeyNameMap::iterator StatKeyNameMapIter;
1426 typedef StatKeyNameMap::const_iterator StatKeyNameMapConstIter;
1428 static bool gStatKeyToStrReady(false);
1430 
1431 static void InitStatKeyNames (void)
1432 {
1457  gStatKeyToStr[AJA_DebugStat_ACXferRPCEncode] = "ACXferRPCEnc";
1458  gStatKeyToStr[AJA_DebugStat_ACXferRPCDecode] = "ACXferRPCDec";
1459  gStatKeyToStrReady = true;
1460  assert(gStatKeyToStr.size() == size_t(AJA_DebugStat_NUM_STATS)); // Be sure all are here
1461 }
1462 
1463 string AJADebugStat::StatKeyName (const int inKey)
1464 {
1466  if (!gStatKeyToStrReady)
1467  InitStatKeyNames();
1468  const StatKeyNameMapConstIter it(gStatKeyToStr.find(inKey));
1469  return it != gStatKeyToStr.end() ? it->second : string();
1470 }
1471 
1472 bool AJADebugStat::SetStatKeyName (const int inKey, const string & inName)
1473 {
1475  if (!gStatKeyToStrReady)
1476  InitStatKeyNames();
1477 
1478  const StatKeyNameMapIter it(gStatKeyToStr.find(inKey));
1479  if (inName.empty()) // Empty name === remove the defined name
1480  {
1481  if (it != gStatKeyToStr.end())
1482  gStatKeyToStr.erase(it);
1483  return true;
1484  }
1485  if (it != gStatKeyToStr.end())
1486  it->second = inName; // Replace existing name
1487  else
1488  gStatKeyToStr.insert(StatKeyNamePair(inKey, inName));
1489  return true;
1490 }
1491 
1493 {
1494  vector<int> result;
1496  if (!gStatKeyToStrReady)
1497  InitStatKeyNames();
1498  for (StatKeyNameMapConstIter it(gStatKeyToStr.begin()); it != gStatKeyToStr.end(); ++it)
1499  result.push_back(it->first);
1500  return result;
1501 }
1502 
1503 std::ostream & operator << (std::ostream & oss, const AJADebugStat & inStat)
1504 {
1505  oss << inStat.fMin << " (min), " << inStat.Average() << " (avg), " << inStat.fMax << " (max), " << inStat.fCount << " (cnt), " << inStat.fLastTimeStamp;
1506  return oss;
1507 }
static bool StatIsAllocated(const uint32_t inKey)
Definition: debug.cpp:1105
struct _AJADebugShare AJADebugShare
void Reset(void)
Definition: debugshare.h:275
uint32_t unitArraySize
Definition: debugshare.h:336
static uint32_t StatsCapacity(void)
Definition: debug.cpp:1051
static const std::string sSeverityString[]
Definition: debug.cpp:30
Declares the AJALock class.
uint64_t fLastTimeStamp
Definition: debugshare.h:268
static AJAStatus GetDestination(const int32_t inGroup, uint32_t &outDestination)
Definition: debug.cpp:267
#define STAT_BIT_CLEAR
Definition: debug.cpp:41
static const std::string & SeverityName(const int32_t severity)
Definition: debug.cpp:849
Declares the AJAMemory class.
static AJAStatus GetThreadId(const uint64_t sequenceNumber, uint64_t &outTid)
Definition: debug.cpp:792
static const char * GetGroupString(int32_t group)
Definition: debug.cpp:857
#define NULL
static AJAStatus GetMessageTime(const uint64_t sequenceNumber, uint64_t &outTime)
Definition: debug.cpp:628
static AJAStatus GetClientReferenceCount(int32_t &outRefCount)
Definition: debug.cpp:520
static AJAStatus StatReset(const uint32_t inKey)
Definition: debug.cpp:1121
#define AJA_DEBUG_SHARE_NAME
Definition: debugshare.h:188
AJAStatus
Definition: types.h:380
Declares the AJADebug class.
#define AJA_DEBUG_MESSAGE_MAX_SIZE
Definition: debugshare.h:185
static AJAStatus Open(bool incrementRefCount=false)
Definition: debug.cpp:44
uint64_t Sum(size_t inNum=11) const
Definition: debug.cpp:1303
static uint64_t GetPid()
Definition: process.cpp:35
static bool sDebug
Definition: debug.cpp:33
static int32_t Decrement(int32_t volatile *pTarget)
Definition: atomic.cpp:95
static bool HasStats(void)
Definition: debug.cpp:1058
static void * Exchange(void *volatile *pTarget, void *pValue)
Definition: atomic.cpp:13
uint32_t magicId
Definition: debugshare.h:328
static StatKeyNameMap gStatKeyToStr
Definition: debug.cpp:1427
static AJAStatus StatGetKeys(std::vector< uint32_t > &outKeys, uint32_t &outSeqNum)
Definition: debug.cpp:1248
void SetValue(const uint32_t inValue)
Definition: debug.cpp:1392
static void Report(int32_t index, int32_t severity, const char *pFileName, int32_t lineNumber,...)
Definition: debug.cpp:395
static uint32_t TotalBytes(void)
Definition: debug.cpp:310
Declares the AJATime class.
#define AJA_DEBUG_DESTINATION_CONSOLE
Definition: debugshare.h:167
static AJADebugShare * spShare
Definition: debug.cpp:32
Definition: lock.h:28
uint32_t fValues[11]
Definition: debugshare.h:269
int64_t debug_time(void)
Definition: debug.cpp:330
static int64_t DebugTime(void)
Definition: debug.cpp:980
Definition: json.hpp:5362
#define AJA_DEBUG_MAX_NUM_STATS
Definition: debugshare.h:183
static bool IsActive(int32_t index)
Definition: debug.cpp:285
static AJAStatus Enable(int32_t index, uint32_t destination=AJA_DEBUG_DESTINATION_NONE)
Definition: debug.cpp:229
uint32_t fMin
Definition: debugshare.h:265
void Start(void)
Definition: debug.cpp:1350
#define false
static AJAStatus StatGetSequenceNum(uint32_t &outSeqNum)
Definition: debug.cpp:1292
StatKeyNameMap::iterator StatKeyNameMapIter
Definition: debug.cpp:1425
static AJAStatus Close(bool decrementRefCount=false)
Definition: debug.cpp:202
static AJAStatus GetProcessId(const uint64_t sequenceNumber, uint64_t &outPid)
Definition: debug.cpp:774
StatKeyNameMap::const_iterator StatKeyNameMapConstIter
Definition: debug.cpp:1426
pair< int, string > StatKeyNamePair
Definition: debug.cpp:1424
static std::vector< int > NamedStatKeys(void)
Definition: debug.cpp:1492
bool DecrementCount(const uint32_t inDecrement=1, const bool inRollUnder=true)
Definition: debug.cpp:1379
static AJAStatus GetMessagesAccepted(uint64_t &outCount)
Definition: debug.cpp:810
static AJAStatus StatTimerStop(const uint32_t inKey)
Definition: debug.cpp:1161
static AJAStatus GetMessagesIgnored(uint64_t &outCount)
Definition: debug.cpp:826
static const std::string & GroupName(const int32_t group)
Definition: debug.cpp:867
int32_t volatile clientRefCount
Definition: debugshare.h:331
static AJAStatus GetMessageDestination(const uint64_t sequenceNumber, uint32_t &outDestination)
Definition: debug.cpp:610
unsigned int n
Definition: pstream.cpp:148
#define true
#define addDebugGroupToLabelVector(x)
Definition: debug.cpp:35
static AJAStatus StatFree(const uint32_t inKey)
Definition: debug.cpp:1084
static void * GetPrivateDataLoc(void)
Definition: debug.cpp:1033
Declares the AJAThread class.
#define STAT_BIT_TEST
Definition: debug.cpp:38
uint32_t Maximum(size_t inNum=11) const
Definition: debug.cpp:1328
std::string to_string(bool val)
Definition: common.cpp:180
int32_t severity
Definition: debugshare.h:208
static bool IsOpen(void)
Definition: debug.cpp:319
static uint64_t GetSystemMicroseconds(void)
Returns the current value of the host&#39;s high-resolution clock, in microseconds.
Definition: systemtime.cpp:221
uint32_t volatile statAllocChanges
Definition: debugshare.h:342
uint32_t messageTextCapacity
Definition: debugshare.h:334
int64_t wallTime
Definition: debugshare.h:205
AJADebugStat stats[256]
Definition: debugshare.h:347
static int32_t Increment(int32_t volatile *pTarget)
Definition: atomic.cpp:82
#define AJA_DEBUG_MAGIC_ID
Definition: debugshare.h:179
uint32_t volatile fCount
Definition: debugshare.h:267
#define AJA_UNUSED(_x_)
Definition: types.h:426
static uint32_t Version(void)
Definition: debug.cpp:303
bool Stop(void)
Definition: debug.cpp:1355
uint64_t volatile statsMessagesIgnored
Definition: debugshare.h:339
uint32_t unitArray[65536]
Definition: debugshare.h:345
static AJAStatus SaveState(const std::string &inFilePath)
Definition: debug.cpp:879
uint32_t version
Definition: debugshare.h:329
#define AJA_DEBUG_STAT_DEQUE_SIZE
Definition: debugshare.h:184
static int64_t GetSystemCounter(void)
Returns the current value of the host system&#39;s high-resolution time counter.
Definition: systemtime.cpp:112
static AJALock gStatKeyToStrLock
Definition: debug.cpp:1429
static AJAStatus StatAllocate(const uint32_t inKey)
Definition: debug.cpp:1063
static int64_t GetSystemFrequency(void)
Returns the frequency of the host system&#39;s high-resolution time counter.
Definition: systemtime.cpp:149
Declares the AJAProcess class.
bool IncrementCount(const uint32_t inIncrement=1, const bool inRollOver=true)
Definition: debug.cpp:1366
static AJAStatus GetMessageWallClockTime(const uint64_t sequenceNumber, int64_t &outTime)
Definition: debug.cpp:645
#define AJA_DEBUG_UNIT_ARRAY_SIZE
Definition: debugshare.h:181
static AJAStatus StatTimerStart(const uint32_t inKey)
Definition: debug.cpp:1141
static AJAStatus StatSetValue(const uint32_t inKey, const uint32_t inValue)
Definition: debug.cpp:1209
char fileName[512]
Definition: debugshare.h:212
Declares the AJAAtomic class.
static AJAStatus GetMessageGroup(const uint64_t sequenceNumber, int32_t &outGroupIndex)
Definition: debug.cpp:592
uint64_t statAllocMask[256/64]
Definition: debugshare.h:343
static bool IsDebugBuild(void)
Definition: debug.cpp:325
static AJAStatus GetMessageFileName(const uint64_t sequenceNumber, std::string &outFileName)
Definition: debug.cpp:662
#define AJA_DEBUG_VERSION
Definition: debugshare.h:180
double Average(void) const
Definition: debug.cpp:1341
static AJAStatus GetMessageText(const uint64_t sequenceNumber, std::string &outMessage)
Definition: debug.cpp:736
static void InitStatKeyNames(void)
Definition: debug.cpp:1431
#define IS_STAT_BAD
Definition: debug.cpp:39
uint32_t statCapacity
Definition: debugshare.h:341
static void * AllocateShared(size_t *size, const char *pShareName, bool global=true)
Definition: memory.cpp:169
uint64_t volatile writeIndex
Definition: debugshare.h:330
static uint32_t MessageRingCapacity(void)
Definition: debug.cpp:512
static void AssertWithMessage(const char *pFileName, int32_t lineNumber, const std::string &pExpression)
Definition: debug.cpp:453
uint64_t volatile statsMessagesAccepted
Definition: debugshare.h:338
static AJAStatus GetMessageSequenceNumber(const uint64_t sequenceNumber, uint64_t &outSequenceNumber)
Definition: debug.cpp:574
static bool FreeShared(void *pMemory)
Definition: memory.cpp:366
#define AJA_DEBUG_DESTINATION_NONE
Definition: debugshare.h:165
static AJAStatus StatCounterIncrement(const uint32_t inKey, const uint32_t inIncrement=1)
Definition: debug.cpp:1183
static std::vector< std::string > sGroupLabelVector
Definition: debug.cpp:29
uint64_t sequenceNumber
Definition: debugshare.h:203
char messageText[512]
Definition: debugshare.h:213
char * safer_strncpy(char *target, const char *source, size_t num, size_t maxSize)
Definition: common.cpp:492
uint32_t Minimum(size_t inNum=11) const
Definition: debug.cpp:1315
System specific functions.
#define AJA_DEBUG_TICK_RATE
Definition: debugshare.h:189
static AJAStatus SetClientReferenceCount(int32_t refCount)
Definition: debug.cpp:537
static AJAStatus GetMessageSeverity(const uint64_t sequenceNumber, int32_t &outSeverity)
Definition: debug.cpp:718
uint32_t messageFileNameCapacity
Definition: debugshare.h:335
static AJAStatus StatGetInfo(const uint32_t inKey, AJADebugStat &outInfo)
Definition: debug.cpp:1229
Private include file for all ajabase sources.
#define AJA_DEBUG_STATE_FILE_VERSION
Definition: debugshare.h:190
std::string AJAStatusToString(const AJAStatus inStatus, const bool inDetailed)
Definition: debug.cpp:987
static AJAStatus Disable(int32_t index, uint32_t destination=AJA_DEBUG_DESTINATION_NONE)
Definition: debug.cpp:239
map< int, string > StatKeyNameMap
Definition: debug.cpp:1423
static AJAStatus RestoreState(const std::string &inFilePath)
Definition: debug.cpp:915
AJADebugMessage messageRing[4096]
Definition: debugshare.h:346
static bool gStatKeyToStrReady(false)
#define AJA_DEBUG_MESSAGE_RING_SIZE
Definition: debugshare.h:186
#define HEX0N(__x__, __n__)
Definition: debug.cpp:1181
static size_t GetPrivateDataLen(void)
Definition: debug.cpp:1042
int32_t lineNumber
Definition: debugshare.h:209
static AJAStatus SetDestination(int32_t index, uint32_t destination=AJA_DEBUG_DESTINATION_NONE)
Definition: debug.cpp:249
std::ostream & operator<<(std::ostream &oss, const AJADebugStat &inStat)
Definition: debug.cpp:1503
uint32_t fMax
Definition: debugshare.h:266
static bool SetStatKeyName(const int inKey, const std::string &inName)
Definition: debug.cpp:1472
uint64_t report_common(int32_t index, int32_t severity, const char *pFileName, int32_t lineNumber, uint64_t &writeIndex, int32_t &messageIndex)
Definition: debug.cpp:339
static AJAStatus GetMessageLineNumber(const uint64_t sequenceNumber, int32_t &outLineNumber)
Definition: debug.cpp:700
uint32_t destinationMask
Definition: debugshare.h:207
static AJALock sLock
Definition: debug.cpp:31
static AJAStatus GetSequenceNumber(uint64_t &outSequenceNumber)
Definition: debug.cpp:558
int32_t groupIndex
Definition: debugshare.h:206
bool operator==(const AJADebugStat &inRHS) const
Definition: debug.cpp:1402
#define AJA_DEBUG_FILE_NAME_MAX_SIZE
Definition: debugshare.h:187
uint32_t messageRingCapacity
Definition: debugshare.h:333
static std::string StatKeyName(const int inKey)
Definition: debug.cpp:1463
static uint64_t GetThreadId()
Definition: thread.cpp:180
static const char * GetSeverityString(int32_t severity)
Definition: debug.cpp:842
virtual bool IsValid(void) const
Definition: lock.h:65
#define STAT_BIT_SET
Definition: debug.cpp:40