Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  Instruments.cpp   Sprache: C

 
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "Instruments.h"
#include "mozilla/Attributes.h"

#ifdef __APPLE__

#  include <dlfcn.h>
#  include <CoreFoundation/CoreFoundation.h>
#  include <unistd.h>

// There are now 2 paths to the DTPerformanceSession framework. We try to load
// the one contained in /Applications/Xcode.app first, falling back to the one
// contained in /Library/Developer/4.0/Instruments.
#  define DTPerformanceLibraryPath                                   \
    "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/" \
    "DTPerformanceSession.framework/Versions/Current/DTPerformanceSession"
#  define OldDTPerformanceLibraryPath                \
    "/Library/Developer/4.0/Instruments/Frameworks/" \
    "DTPerformanceSession.framework/Versions/Current/DTPerformanceSession"

extern "C" {

typedef CFTypeRef DTPerformanceSessionRef;

#  define DTPerformanceSession_TimeProfiler \
    "com.apple.instruments.dtps.timeprofiler"
// DTPerformanceSession_Option_SamplingInterval is measured in microseconds
#  define DTPerformanceSession_Option_SamplingInterval \
    "com.apple.instruments.dtps.option.samplinginterval"

typedef void (*dtps_errorcallback_t)(CFStringRef, CFErrorRef);
typedef DTPerformanceSessionRef (*DTPerformanceSessionCreateFunction)(
    CFStringRef, CFStringRef, CFDictionaryRef, CFErrorRef*);
typedef bool (*DTPerformanceSessionAddInstrumentFunction)(
    DTPerformanceSessionRef, CFStringRef, CFDictionaryRef, dtps_errorcallback_t,
    CFErrorRef*);
typedef bool (*DTPerformanceSessionIsRecordingFunction)(
    DTPerformanceSessionRef);
typedef bool (*DTPerformanceSessionStartFunction)(DTPerformanceSessionRef,
                                                  CFArrayRef, CFErrorRef*);
typedef bool (*DTPerformanceSessionStopFunction)(DTPerformanceSessionRef,
                                                 CFArrayRef, CFErrorRef*);
typedef bool (*DTPerformanceSessionSaveFunction)(DTPerformanceSessionRef,
                                                 CFStringRef, CFErrorRef*);

}  // extern "C"

namespace Instruments {

static const int kSamplingInterval = 20;  // microseconds

template <typename T>
class AutoReleased {
 public:
  MOZ_IMPLICIT AutoReleased(T aTypeRef) : mTypeRef(aTypeRef) {}
  ~AutoReleased() {
    if (mTypeRef) {
      CFRelease(mTypeRef);
    }
  }

  operator T() { return mTypeRef; }

 private:
  T mTypeRef;
};

#  define DTPERFORMANCE_SYMBOLS               \
    SYMBOL(DTPerformanceSessionCreate)        \
    SYMBOL(DTPerformanceSessionAddInstrument) \
    SYMBOL(DTPerformanceSessionIsRecording)   \
    SYMBOL(DTPerformanceSessionStart)         \
    SYMBOL(DTPerformanceSessionStop)          \
    SYMBOL(DTPerformanceSessionSave)

#  define SYMBOL(_sym) _sym##Function _sym = nullptr;

DTPERFORMANCE_SYMBOLS

#  undef SYMBOL

void* LoadDTPerformanceLibraries(bool dontLoad) {
  int flags = RTLD_LAZY | RTLD_LOCAL | RTLD_NODELETE;
  if (dontLoad) {
    flags |= RTLD_NOLOAD;
  }

  void* DTPerformanceLibrary = dlopen(DTPerformanceLibraryPath, flags);
  if (!DTPerformanceLibrary) {
    DTPerformanceLibrary = dlopen(OldDTPerformanceLibraryPath, flags);
  }
  return DTPerformanceLibrary;
}

bool LoadDTPerformanceLibrary() {
  void* DTPerformanceLibrary = LoadDTPerformanceLibraries(true);
  if (!DTPerformanceLibrary) {
    DTPerformanceLibrary = LoadDTPerformanceLibraries(false);
    if (!DTPerformanceLibrary) {
      return false;
    }
  }

#  define SYMBOL(_sym)                                                        \
    _sym =                                                                    \
        reinterpret_cast<_sym##Function>(dlsym(DTPerformanceLibrary, #_sym)); \
    if (!_sym) {                                                              \
      dlclose(DTPerformanceLibrary);                                          \
      DTPerformanceLibrary = nullptr;                                         \
      return false;                                                           \
    }

  DTPERFORMANCE_SYMBOLS

#  undef SYMBOL

  dlclose(DTPerformanceLibrary);

  return true;
}

static DTPerformanceSessionRef gSession;

bool Error(CFErrorRef error) {
  if (gSession) {
    CFErrorRef unused = nullptr;
    DTPerformanceSessionStop(gSession, nullptr, &unused);
    CFRelease(gSession);
    gSession = nullptr;
  }
#  ifdef DEBUG
  AutoReleased<CFDataRef> data = CFStringCreateExternalRepresentation(
      nullptr, CFErrorCopyDescription(error), kCFStringEncodingUTF8, '?');
  if (data != nullptr) {
    printf("%.*s\n\n", (int)CFDataGetLength(data), CFDataGetBytePtr(data));
  }
#  endif
  return false;
}

bool Start(pid_t pid) {
  if (gSession) {
    return false;
  }

  if (!LoadDTPerformanceLibrary()) {
    return false;
  }

  AutoReleased<CFStringRef> process =
      CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("%d"), pid);
  if (!process) {
    return false;
  }
  CFErrorRef error = nullptr;
  gSession = DTPerformanceSessionCreate(nullptr, process, nullptr, &error);
  if (!gSession) {
    return Error(error);
  }

  AutoReleased<CFNumberRef> interval =
      CFNumberCreate(0, kCFNumberIntType, &kSamplingInterval);
  if (!interval) {
    return false;
  }
  CFStringRef keys[1] = {CFSTR(DTPerformanceSession_Option_SamplingInterval)};
  CFNumberRef values[1] = {interval};
  AutoReleased<CFDictionaryRef> options = CFDictionaryCreate(
      kCFAllocatorDefault, (const void**)keys, (const void**)values, 1,
      &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
  if (!options) {
    return false;
  }

  if (!DTPerformanceSessionAddInstrument(
          gSession, CFSTR(DTPerformanceSession_TimeProfiler), options, nullptr,
          &error)) {
    return Error(error);
  }

  return Resume();
}

void Pause() {
  if (gSession && DTPerformanceSessionIsRecording(gSession)) {
    CFErrorRef error = nullptr;
    if (!DTPerformanceSessionStop(gSession, nullptr, &error)) {
      Error(error);
    }
  }
}

bool Resume() {
  if (!gSession) {
    return false;
  }

  CFErrorRef error = nullptr;
  return DTPerformanceSessionStart(gSession, nullptr, &error) || Error(error);
}

void Stop(const char* profileName) {
  Pause();

  CFErrorRef error = nullptr;
  AutoReleased<CFStringRef> name =
      CFStringCreateWithFormat(kCFAllocatorDefault, nullptr, CFSTR("%s%s"),
                               "/tmp/", profileName ? profileName : "mozilla");
  if (!DTPerformanceSessionSave(gSession, name, &error)) {
    Error(error);
    return;
  }

  CFRelease(gSession);
  gSession = nullptr;
}

}  // namespace Instruments

#endif /* __APPLE__ */

94%


¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge