Skip to content

Commit

Permalink
feat: replace logbypass static storages with EnvironmentData
Browse files Browse the repository at this point in the history
PR-URL: #129
Reviewed-BY: hyj1991 <[email protected]>
  • Loading branch information
legendecas authored Feb 8, 2022
1 parent 21ade0e commit 3718573
Show file tree
Hide file tree
Showing 21 changed files with 524 additions and 291 deletions.
3 changes: 2 additions & 1 deletion .clang-format
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# http://clang.llvm.org/docs/ClangFormatStyleOptions.html
BasedOnStyle: Google
MaxEmptyLinesToKeep: 2
DerivePointerAlignment: false
MaxEmptyLinesToKeep: 1
1 change: 1 addition & 0 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"target_name": "xprofiler",
"win_delay_load_hook": "false",
"sources": [
"src/environment_data.cc",
"src/xprofiler.cc",
"src/configure.cc",
"src/logger.cc",
Expand Down
71 changes: 71 additions & 0 deletions src/environment_data.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#include "environment_data.h"

#include <memory>

#include "util.h"
#include "xpf_node.h"

namespace xprofiler {
using Nan::HandleScope;
using v8::Isolate;

namespace per_process {
// TODO(legendecas): environment registry.
std::unique_ptr<EnvironmentData> environment_data;
} // namespace per_process

EnvironmentData* EnvironmentData::GetCurrent() {
CHECK_NE(per_process::environment_data, nullptr);
return per_process::environment_data.get();
}

EnvironmentData* EnvironmentData::GetCurrent(v8::Isolate* isolate) {
// TODO(legendecas): environment registry.
CHECK_NE(per_process::environment_data, nullptr);
return per_process::environment_data.get();
}

EnvironmentData* EnvironmentData::GetCurrent(
const Nan::FunctionCallbackInfo<v8::Value>& info) {
// TODO(legendecas): environment registry.
CHECK_NE(per_process::environment_data, nullptr);
return per_process::environment_data.get();
}

EnvironmentData* EnvironmentData::Create(v8::Isolate* isolate) {
// TODO(legendecas): environment registry.
CHECK_EQ(per_process::environment_data, nullptr);

CHECK_EQ(isolate, Isolate::GetCurrent());
HandleScope scope;

per_process::environment_data =
std::unique_ptr<EnvironmentData>(new EnvironmentData(isolate));
xprofiler::AtExit(isolate, AtExit, nullptr);

return per_process::environment_data.get();
}

EnvironmentData::EnvironmentData(v8::Isolate* isolate) : isolate_(isolate) {
uv_loop_t* loop = node::GetCurrentEventLoop(isolate);
CHECK_EQ(0, uv_async_init(loop, &statistics_async_, CollectStatistics));
uv_unref(reinterpret_cast<uv_handle_t*>(&statistics_async_));
}

void EnvironmentData::AtExit(void* arg) {
// TODO(legendecas): environment registry.
per_process::environment_data.reset();
}

void EnvironmentData::SendCollectStatistics() {
uv_async_send(&statistics_async_);
}

void EnvironmentData::CollectStatistics(uv_async_t* handle) {
EnvironmentData* env_data =
ContainerOf(&EnvironmentData::statistics_async_, handle);
CollectMemoryStatistics(env_data);
CollectLibuvHandleStatistics(env_data);
}

} // namespace xprofiler
48 changes: 48 additions & 0 deletions src/environment_data.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#ifndef XPROFILER_SRC_ENVIRONMENT_DATA_H
#define XPROFILER_SRC_ENVIRONMENT_DATA_H

#include "logbypass/gc.h"
#include "logbypass/heap.h"
#include "logbypass/http.h"
#include "logbypass/libuv.h"
#include "nan.h"

namespace xprofiler {

class EnvironmentData {
public:
// TODO(legendecas): remove this no-args GetCurrent.
static EnvironmentData* GetCurrent();
static EnvironmentData* GetCurrent(v8::Isolate* isolate);
static EnvironmentData* GetCurrent(
const Nan::FunctionCallbackInfo<v8::Value>& info);
static EnvironmentData* Create(v8::Isolate* isolate);

void SendCollectStatistics();

inline v8::Isolate* isolate() { return isolate_; }

inline GcStatistics* gc_statistics() { return &gc_statistics_; }
inline HttpStatistics* http_statistics() { return &http_statistics_; }
inline MemoryStatistics* memory_statistics() { return &memory_statistics_; }
inline UvHandleStatistics* uv_handle_statistics() {
return &uv_handle_statistics_;
}

private:
static void AtExit(void* arg);
static void CollectStatistics(uv_async_t* handle);
EnvironmentData(v8::Isolate* isolate);

v8::Isolate* isolate_;
uv_async_t statistics_async_;

GcStatistics gc_statistics_;
MemoryStatistics memory_statistics_;
HttpStatistics http_statistics_;
UvHandleStatistics uv_handle_statistics_;
};

} // namespace xprofiler

#endif /* XPROFILER_SRC_ENVIRONMENT_DATA_H */
2 changes: 1 addition & 1 deletion src/logbypass/cpu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace xprofiler {
V(600)

#define INIT_CPU_PERIOD(period) \
static double *cpu_##period = new double[period]; \
static double* cpu_##period = new double[period]; \
static int cpu_##period##_array_index = 0; \
static int cpu_##period##_array_length = period; \
static int cpu_##period##_array_not_full = true;
Expand Down
6 changes: 3 additions & 3 deletions src/logbypass/cpu.h
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
#ifndef _SRC_LOGBYPASS_CPU_H
#define _SRC_LOGBYPASS_CPU_H
#ifndef XPROFILER_SRC_LOGBYPASS_CPU_H
#define XPROFILER_SRC_LOGBYPASS_CPU_H

namespace xprofiler {
void SetNowCpuUsage();
void WriteCpuUsageInPeriod(bool log_format_alinode);
} // namespace xprofiler

#endif
#endif /* XPROFILER_SRC_LOGBYPASS_CPU_H */
62 changes: 36 additions & 26 deletions src/logbypass/gc.cc
Original file line number Diff line number Diff line change
@@ -1,59 +1,71 @@
#include "gc.h"

#include "../library/common.h"
#include "../logger.h"
#include "environment_data.h"
#include "library/common.h"
#include "logger.h"

namespace xprofiler {
using Nan::AddGCEpilogueCallback;
using Nan::AddGCPrologueCallback;
using v8::GCType;
using v8::Isolate;

static gc_statistics_t *gc_statistics = new gc_statistics_t;
static uv_mutex_t gc_mutex;

unsigned int TotalGcTimes() {
if (gc_statistics == nullptr) {
uint32_t TotalGcTimes() {
Isolate* isolate = Isolate::GetCurrent();
EnvironmentData* env_data = EnvironmentData::GetCurrent(isolate);
if (env_data == nullptr) {
return 0;
}
GcStatistics* gc_statistics = env_data->gc_statistics();
return gc_statistics->total_gc_times;
}

unsigned long TotalGcDuration() {
if (gc_statistics == nullptr) {
uint32_t TotalGcDuration() {
Isolate* isolate = Isolate::GetCurrent();
EnvironmentData* env_data = EnvironmentData::GetCurrent(isolate);
if (env_data == nullptr) {
return 0;
}
GcStatistics* gc_statistics = env_data->gc_statistics();
return gc_statistics->total_gc_duration;
}

// gc prologue hook
NAN_GC_CALLBACK(GCPrologueCallback) {
uv_mutex_lock(&gc_mutex);
gc_statistics->start() = uv_hrtime();
uv_mutex_unlock(&gc_mutex);
EnvironmentData* env_data = EnvironmentData::GetCurrent(isolate);
if (env_data == nullptr) {
return;
}
GcStatistics* gc_statistics = env_data->gc_statistics();
Mutex::ScopedLock lock(gc_statistics->mutex);
gc_statistics->start = uv_hrtime();
}

// gc epilogue hook
NAN_GC_CALLBACK(GCEpilogueCallback) {
uv_mutex_lock(&gc_mutex);
EnvironmentData* env_data = EnvironmentData::GetCurrent(isolate);
if (env_data == nullptr) {
return;
}
GcStatistics* gc_statistics = env_data->gc_statistics();
Mutex::ScopedLock lock(gc_statistics->mutex);

uint64_t now = uv_hrtime();
uint64_t start = gc_statistics->start();
uint64_t start = gc_statistics->start;
if (start == 0 || now < start) {
uv_mutex_unlock(&gc_mutex);
return;
}

gc_statistics->total_gc_times++;
unsigned int duration = static_cast<int>((now - start) / 10e5); // cost, ms
uint32_t duration = static_cast<uint32_t>((now - start) / 10e5); // cost, ms

// check duration is legal
if (duration >= 5 * 60 * 1000) {
uv_mutex_unlock(&gc_mutex);
return;
}

// reset gc start time
gc_statistics->start() = 0;
gc_statistics->start = 0;

gc_statistics->total_gc_duration += duration;
gc_statistics->gc_time_during_last_record += duration;
Expand All @@ -72,19 +84,18 @@ NAN_GC_CALLBACK(GCEpilogueCallback) {
gc_statistics->total_incremental_marking_duration += duration;
gc_statistics->incremental_marking_duration_last_record += duration;
}
uv_mutex_unlock(&gc_mutex);
}

int InitGcStatusHooks() {
int rc = uv_mutex_init(&gc_mutex);
void InitGcStatusHooks() {
AddGCPrologueCallback(GCPrologueCallback);
AddGCEpilogueCallback(GCEpilogueCallback);
return rc;
}

void WriteGcStatusToLog(bool log_format_alinode) {
void WriteGcStatusToLog(EnvironmentData* env_data, bool log_format_alinode) {
GcStatistics* gc_statistics = env_data->gc_statistics();
Mutex::ScopedLock lock(gc_statistics->mutex);

// record gc status
uv_mutex_lock(&gc_mutex);
if (log_format_alinode)
Info("gc",
"gc_time_during_last_min: %lu, total: %lu, scavange_duration: %lu, "
Expand Down Expand Up @@ -118,6 +129,5 @@ void WriteGcStatusToLog(bool log_format_alinode) {
gc_statistics->incremental_marking_duration_last_record);
// reset last record
gc_statistics->reset();
uv_mutex_unlock(&gc_mutex);
}
} // namespace xprofiler
} // namespace xprofiler
47 changes: 24 additions & 23 deletions src/logbypass/gc.h
Original file line number Diff line number Diff line change
@@ -1,44 +1,45 @@
#ifndef _SRC_LOGBYPASS_GC_H
#define _SRC_LOGBYPASS_GC_H
#ifndef XPROFILER_SRC_LOGBYPASS_GC_H
#define XPROFILER_SRC_LOGBYPASS_GC_H

#include "nan.h"
#include "xpf_mutex-inl.h"

namespace xprofiler {
typedef struct GcStatistics {
class EnvironmentData;

class GcStatistics {
public:
// total gc times
unsigned int total_gc_times = 0;
uint32_t total_gc_times = 0;
// total gc duration
unsigned long total_gc_duration = 0;
unsigned long total_scavange_duration = 0;
unsigned long total_marksweep_duration = 0;
unsigned long total_incremental_marking_duration = 0;
uint32_t total_gc_duration = 0;
uint32_t total_scavange_duration = 0;
uint32_t total_marksweep_duration = 0;
uint32_t total_incremental_marking_duration = 0;
// last record
unsigned long gc_time_during_last_record = 0;
unsigned long scavange_duration_last_record = 0;
unsigned long marksweep_duration_last_record = 0;
unsigned long incremental_marking_duration_last_record = 0;
uint32_t gc_time_during_last_record = 0;
uint32_t scavange_duration_last_record = 0;
uint32_t marksweep_duration_last_record = 0;
uint32_t incremental_marking_duration_last_record = 0;
uint64_t start = 0;

// record start
uint64_t &start() { return start_; }
Mutex mutex;

// reset last record
void reset() {
start_ = 0;
start = 0;
gc_time_during_last_record = 0;
scavange_duration_last_record = 0;
marksweep_duration_last_record = 0;
incremental_marking_duration_last_record = 0;
}
};

private:
uint64_t start_ = 0;
} gc_statistics_t;
void InitGcStatusHooks();
void WriteGcStatusToLog(EnvironmentData* env_data, bool log_format_alinode);

int InitGcStatusHooks();
void WriteGcStatusToLog(bool log_format_alinode);
unsigned int TotalGcTimes();
unsigned long TotalGcDuration();
uint32_t TotalGcTimes();
uint32_t TotalGcDuration();
} // namespace xprofiler

#endif
#endif /* XPROFILER_SRC_LOGBYPASS_GC_H */
Loading

0 comments on commit 3718573

Please sign in to comment.