jruby-async-profiler 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.gitmodules +3 -0
- data/Gemfile +4 -0
- data/README.md +35 -0
- data/Rakefile +2 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/ext/Rakefile +6 -0
- data/ext/async-profiler/.gitattributes +1 -0
- data/ext/async-profiler/.gitignore +6 -0
- data/ext/async-profiler/.travis.yml +11 -0
- data/ext/async-profiler/CHANGELOG.md +107 -0
- data/ext/async-profiler/JavaHome.class +0 -0
- data/ext/async-profiler/LICENSE +201 -0
- data/ext/async-profiler/Makefile +66 -0
- data/ext/async-profiler/README.md +487 -0
- data/ext/async-profiler/demo/SwingSet2.svg +2247 -0
- data/ext/async-profiler/docs/cddl1.txt +358 -0
- data/ext/async-profiler/profiler.sh +240 -0
- data/ext/async-profiler/src/allocTracer.cpp +155 -0
- data/ext/async-profiler/src/allocTracer.h +74 -0
- data/ext/async-profiler/src/arch.h +69 -0
- data/ext/async-profiler/src/arguments.cpp +265 -0
- data/ext/async-profiler/src/arguments.h +152 -0
- data/ext/async-profiler/src/codeCache.cpp +128 -0
- data/ext/async-profiler/src/codeCache.h +99 -0
- data/ext/async-profiler/src/engine.cpp +50 -0
- data/ext/async-profiler/src/engine.h +38 -0
- data/ext/async-profiler/src/flameGraph.cpp +770 -0
- data/ext/async-profiler/src/flameGraph.h +118 -0
- data/ext/async-profiler/src/flightRecorder.cpp +727 -0
- data/ext/async-profiler/src/flightRecorder.h +39 -0
- data/ext/async-profiler/src/frameName.cpp +189 -0
- data/ext/async-profiler/src/frameName.h +56 -0
- data/ext/async-profiler/src/itimer.cpp +49 -0
- data/ext/async-profiler/src/itimer.h +43 -0
- data/ext/async-profiler/src/jattach/jattach.c +437 -0
- data/ext/async-profiler/src/java/one/profiler/AsyncProfiler.java +160 -0
- data/ext/async-profiler/src/java/one/profiler/AsyncProfilerMXBean.java +43 -0
- data/ext/async-profiler/src/java/one/profiler/Counter.java +25 -0
- data/ext/async-profiler/src/java/one/profiler/Events.java +28 -0
- data/ext/async-profiler/src/javaApi.cpp +124 -0
- data/ext/async-profiler/src/lockTracer.cpp +161 -0
- data/ext/async-profiler/src/lockTracer.h +55 -0
- data/ext/async-profiler/src/mutex.cpp +33 -0
- data/ext/async-profiler/src/mutex.h +49 -0
- data/ext/async-profiler/src/os.h +45 -0
- data/ext/async-profiler/src/os_linux.cpp +129 -0
- data/ext/async-profiler/src/os_macos.cpp +115 -0
- data/ext/async-profiler/src/perfEvents.h +60 -0
- data/ext/async-profiler/src/perfEvents_linux.cpp +550 -0
- data/ext/async-profiler/src/perfEvents_macos.cpp +64 -0
- data/ext/async-profiler/src/profiler.cpp +952 -0
- data/ext/async-profiler/src/profiler.h +238 -0
- data/ext/async-profiler/src/spinLock.h +66 -0
- data/ext/async-profiler/src/stackFrame.h +57 -0
- data/ext/async-profiler/src/stackFrame_aarch64.cpp +75 -0
- data/ext/async-profiler/src/stackFrame_arm.cpp +58 -0
- data/ext/async-profiler/src/stackFrame_i386.cpp +82 -0
- data/ext/async-profiler/src/stackFrame_x64.cpp +113 -0
- data/ext/async-profiler/src/symbols.h +37 -0
- data/ext/async-profiler/src/symbols_linux.cpp +354 -0
- data/ext/async-profiler/src/symbols_macos.cpp +156 -0
- data/ext/async-profiler/src/vmEntry.cpp +173 -0
- data/ext/async-profiler/src/vmEntry.h +105 -0
- data/ext/async-profiler/src/vmStructs.cpp +104 -0
- data/ext/async-profiler/src/vmStructs.h +112 -0
- data/ext/async-profiler/src/wallClock.cpp +96 -0
- data/ext/async-profiler/src/wallClock.h +56 -0
- data/ext/async-profiler/test/AllocatingTarget.java +26 -0
- data/ext/async-profiler/test/LoadLibraryTest.java +21 -0
- data/ext/async-profiler/test/Target.java +31 -0
- data/ext/async-profiler/test/ThreadsTarget.java +35 -0
- data/ext/async-profiler/test/alloc-smoke-test.sh +36 -0
- data/ext/async-profiler/test/load-library-test.sh +35 -0
- data/ext/async-profiler/test/smoke-test.sh +37 -0
- data/ext/async-profiler/test/thread-smoke-test.sh +32 -0
- data/jruby-async-profiler.gemspec +32 -0
- data/lib/jruby/async/profiler.rb +10 -0
- data/lib/jruby/async/profiler/version.rb +7 -0
- metadata +155 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2017 Andrei Pangin
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#ifndef _LOCKTRACER_H
|
18
|
+
#define _LOCKTRACER_H
|
19
|
+
|
20
|
+
#include <jvmti.h>
|
21
|
+
#include "engine.h"
|
22
|
+
|
23
|
+
|
24
|
+
typedef void (JNICALL *UnsafeParkFunc)(JNIEnv*, jobject, jboolean, jlong);
|
25
|
+
|
26
|
+
class LockTracer : public Engine {
|
27
|
+
private:
|
28
|
+
static jlong _start_time;
|
29
|
+
static jclass _LockSupport;
|
30
|
+
static jmethodID _getBlocker;
|
31
|
+
static UnsafeParkFunc _original_Unsafe_Park;
|
32
|
+
static bool _supports_lock_names;
|
33
|
+
|
34
|
+
static jclass getParkBlockerClass(jvmtiEnv* jvmti, JNIEnv* env);
|
35
|
+
static void recordContendedLock(jclass lock_class, jlong time);
|
36
|
+
static void bindUnsafePark(UnsafeParkFunc entry);
|
37
|
+
|
38
|
+
public:
|
39
|
+
const char* name() {
|
40
|
+
return "lock";
|
41
|
+
}
|
42
|
+
|
43
|
+
const char* units() {
|
44
|
+
return "ns";
|
45
|
+
}
|
46
|
+
|
47
|
+
Error start(Arguments& args);
|
48
|
+
void stop();
|
49
|
+
|
50
|
+
static void JNICALL MonitorContendedEnter(jvmtiEnv* jvmti, JNIEnv* env, jthread thread, jobject object);
|
51
|
+
static void JNICALL MonitorContendedEntered(jvmtiEnv* jvmti, JNIEnv* env, jthread thread, jobject object);
|
52
|
+
static void JNICALL UnsafeParkTrap(JNIEnv* env, jobject instance, jboolean isAbsolute, jlong time);
|
53
|
+
};
|
54
|
+
|
55
|
+
#endif // _LOCKTRACER_H
|
@@ -0,0 +1,33 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2018 Andrei Pangin
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#include "mutex.h"
|
18
|
+
|
19
|
+
|
20
|
+
Mutex::Mutex() {
|
21
|
+
pthread_mutexattr_t attr;
|
22
|
+
pthread_mutexattr_init(&attr);
|
23
|
+
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
|
24
|
+
pthread_mutex_init(&_mutex, &attr);
|
25
|
+
}
|
26
|
+
|
27
|
+
void Mutex::lock() {
|
28
|
+
pthread_mutex_lock(&_mutex);
|
29
|
+
}
|
30
|
+
|
31
|
+
void Mutex::unlock() {
|
32
|
+
pthread_mutex_unlock(&_mutex);
|
33
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2018 Andrei Pangin
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#ifndef _MUTEX_H
|
18
|
+
#define _MUTEX_H
|
19
|
+
|
20
|
+
#include <pthread.h>
|
21
|
+
|
22
|
+
|
23
|
+
class Mutex {
|
24
|
+
private:
|
25
|
+
pthread_mutex_t _mutex;
|
26
|
+
|
27
|
+
public:
|
28
|
+
Mutex();
|
29
|
+
|
30
|
+
void lock();
|
31
|
+
void unlock();
|
32
|
+
};
|
33
|
+
|
34
|
+
|
35
|
+
class MutexLocker {
|
36
|
+
private:
|
37
|
+
Mutex* _mutex;
|
38
|
+
|
39
|
+
public:
|
40
|
+
MutexLocker(Mutex& mutex) : _mutex(&mutex) {
|
41
|
+
_mutex->lock();
|
42
|
+
}
|
43
|
+
|
44
|
+
~MutexLocker() {
|
45
|
+
_mutex->unlock();
|
46
|
+
}
|
47
|
+
};
|
48
|
+
|
49
|
+
#endif // _MUTEX_H
|
@@ -0,0 +1,45 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2018 Andrei Pangin
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#ifndef _OS_H
|
18
|
+
#define _OS_H
|
19
|
+
|
20
|
+
#include <signal.h>
|
21
|
+
#include "arch.h"
|
22
|
+
|
23
|
+
|
24
|
+
class ThreadList {
|
25
|
+
public:
|
26
|
+
virtual ~ThreadList() {}
|
27
|
+
virtual int next() = 0;
|
28
|
+
};
|
29
|
+
|
30
|
+
|
31
|
+
class OS {
|
32
|
+
public:
|
33
|
+
static u64 nanotime();
|
34
|
+
static u64 millis();
|
35
|
+
static u64 hton64(u64 x);
|
36
|
+
static int threadId();
|
37
|
+
static bool isThreadRunning(int thread_id);
|
38
|
+
static bool isSignalSafeTLS();
|
39
|
+
static bool isJavaLibraryVisible();
|
40
|
+
static void installSignalHandler(int signo, void (*handler)(int, siginfo_t*, void*));
|
41
|
+
static void sendSignalToThread(int thread_id, int signo);
|
42
|
+
static ThreadList* listThreads();
|
43
|
+
};
|
44
|
+
|
45
|
+
#endif // _OS_H
|
@@ -0,0 +1,129 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2018 Andrei Pangin
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#ifdef __linux__
|
18
|
+
|
19
|
+
#include <arpa/inet.h>
|
20
|
+
#include <byteswap.h>
|
21
|
+
#include <dirent.h>
|
22
|
+
#include <fcntl.h>
|
23
|
+
#include <stdio.h>
|
24
|
+
#include <stdlib.h>
|
25
|
+
#include <string.h>
|
26
|
+
#include <sys/stat.h>
|
27
|
+
#include <sys/syscall.h>
|
28
|
+
#include <sys/time.h>
|
29
|
+
#include <sys/types.h>
|
30
|
+
#include <time.h>
|
31
|
+
#include <unistd.h>
|
32
|
+
#include "os.h"
|
33
|
+
|
34
|
+
|
35
|
+
class LinuxThreadList : public ThreadList {
|
36
|
+
private:
|
37
|
+
DIR* _dir;
|
38
|
+
|
39
|
+
public:
|
40
|
+
LinuxThreadList() {
|
41
|
+
_dir = opendir("/proc/self/task");
|
42
|
+
}
|
43
|
+
|
44
|
+
~LinuxThreadList() {
|
45
|
+
if (_dir != NULL) {
|
46
|
+
closedir(_dir);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
int next() {
|
51
|
+
if (_dir != NULL) {
|
52
|
+
struct dirent* entry;
|
53
|
+
while ((entry = readdir(_dir)) != NULL) {
|
54
|
+
if (entry->d_name[0] != '.') {
|
55
|
+
return atoi(entry->d_name);
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
return -1;
|
60
|
+
}
|
61
|
+
};
|
62
|
+
|
63
|
+
|
64
|
+
u64 OS::nanotime() {
|
65
|
+
struct timespec tp;
|
66
|
+
clock_gettime(CLOCK_MONOTONIC, &tp);
|
67
|
+
return (u64)tp.tv_sec * 1000000000 + tp.tv_nsec;
|
68
|
+
}
|
69
|
+
|
70
|
+
u64 OS::millis() {
|
71
|
+
struct timeval tv;
|
72
|
+
gettimeofday(&tv, NULL);
|
73
|
+
return (u64)tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
74
|
+
}
|
75
|
+
|
76
|
+
u64 OS::hton64(u64 x) {
|
77
|
+
return htonl(1) == 1 ? x : bswap_64(x);
|
78
|
+
}
|
79
|
+
|
80
|
+
int OS::threadId() {
|
81
|
+
return syscall(__NR_gettid);
|
82
|
+
}
|
83
|
+
|
84
|
+
bool OS::isThreadRunning(int thread_id) {
|
85
|
+
char buf[512];
|
86
|
+
sprintf(buf, "/proc/self/task/%d/stat", thread_id);
|
87
|
+
int fd = open(buf, O_RDONLY);
|
88
|
+
if (fd == -1) {
|
89
|
+
return false;
|
90
|
+
}
|
91
|
+
|
92
|
+
bool running = false;
|
93
|
+
if (read(fd, buf, sizeof(buf)) > 0) {
|
94
|
+
char* s = strchr(buf, ')');
|
95
|
+
running = s != NULL && (s[2] == 'R' || s[2] == 'D');
|
96
|
+
}
|
97
|
+
|
98
|
+
close(fd);
|
99
|
+
return running;
|
100
|
+
}
|
101
|
+
|
102
|
+
bool OS::isSignalSafeTLS() {
|
103
|
+
return true;
|
104
|
+
}
|
105
|
+
|
106
|
+
bool OS::isJavaLibraryVisible() {
|
107
|
+
return false;
|
108
|
+
}
|
109
|
+
|
110
|
+
void OS::installSignalHandler(int signo, void (*handler)(int, siginfo_t*, void*)) {
|
111
|
+
struct sigaction sa;
|
112
|
+
sigemptyset(&sa.sa_mask);
|
113
|
+
sa.sa_sigaction = handler;
|
114
|
+
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
115
|
+
|
116
|
+
sigaction(signo, &sa, NULL);
|
117
|
+
}
|
118
|
+
|
119
|
+
void OS::sendSignalToThread(int thread_id, int signo) {
|
120
|
+
static const int self_pid = getpid();
|
121
|
+
|
122
|
+
syscall(__NR_tgkill, self_pid, thread_id, signo);
|
123
|
+
}
|
124
|
+
|
125
|
+
ThreadList* OS::listThreads() {
|
126
|
+
return new LinuxThreadList();
|
127
|
+
}
|
128
|
+
|
129
|
+
#endif // __linux__
|
@@ -0,0 +1,115 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2018 Andrei Pangin
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#ifdef __APPLE__
|
18
|
+
|
19
|
+
#include <libkern/OSByteOrder.h>
|
20
|
+
#include <mach/mach.h>
|
21
|
+
#include <mach/mach_time.h>
|
22
|
+
#include <sys/time.h>
|
23
|
+
#include "os.h"
|
24
|
+
|
25
|
+
|
26
|
+
class MacThreadList : public ThreadList {
|
27
|
+
private:
|
28
|
+
thread_array_t _thread_array;
|
29
|
+
unsigned int _thread_count;
|
30
|
+
unsigned int _thread_index;
|
31
|
+
|
32
|
+
public:
|
33
|
+
MacThreadList() : _thread_array(NULL), _thread_count(0), _thread_index(0) {
|
34
|
+
task_threads(mach_task_self(), &_thread_array, &_thread_count);
|
35
|
+
}
|
36
|
+
|
37
|
+
~MacThreadList() {
|
38
|
+
task_t task = mach_task_self();
|
39
|
+
for (int i = 0; i < _thread_count; i++) {
|
40
|
+
mach_port_deallocate(task, _thread_array[i]);
|
41
|
+
}
|
42
|
+
vm_deallocate(task, (vm_address_t)_thread_array, sizeof(thread_t) * _thread_count);
|
43
|
+
}
|
44
|
+
|
45
|
+
int next() {
|
46
|
+
if (_thread_index < _thread_count) {
|
47
|
+
return (int)_thread_array[_thread_index++];
|
48
|
+
}
|
49
|
+
return -1;
|
50
|
+
}
|
51
|
+
};
|
52
|
+
|
53
|
+
|
54
|
+
static mach_timebase_info_data_t timebase = {0, 0};
|
55
|
+
|
56
|
+
u64 OS::nanotime() {
|
57
|
+
if (timebase.denom == 0) {
|
58
|
+
mach_timebase_info(&timebase);
|
59
|
+
}
|
60
|
+
return (u64)mach_absolute_time() * timebase.numer / timebase.denom;
|
61
|
+
}
|
62
|
+
|
63
|
+
u64 OS::millis() {
|
64
|
+
struct timeval tv;
|
65
|
+
gettimeofday(&tv, NULL);
|
66
|
+
return (u64)tv.tv_sec * 1000 + tv.tv_usec / 1000;
|
67
|
+
}
|
68
|
+
|
69
|
+
u64 OS::hton64(u64 x) {
|
70
|
+
return OSSwapHostToBigInt64(x);
|
71
|
+
}
|
72
|
+
|
73
|
+
int OS::threadId() {
|
74
|
+
// Used to be pthread_mach_thread_np(pthread_self()),
|
75
|
+
// but pthread_mach_thread_np is not async signal safe
|
76
|
+
mach_port_t port = mach_thread_self();
|
77
|
+
mach_port_deallocate(mach_task_self(), port);
|
78
|
+
return (int)port;
|
79
|
+
}
|
80
|
+
|
81
|
+
bool OS::isThreadRunning(int thread_id) {
|
82
|
+
struct thread_basic_info info;
|
83
|
+
mach_msg_type_number_t size = sizeof(info);
|
84
|
+
if (thread_info((thread_act_t)thread_id, THREAD_BASIC_INFO, (thread_info_t)&info, &size) != 0) {
|
85
|
+
return false;
|
86
|
+
}
|
87
|
+
return info.run_state == TH_STATE_RUNNING;
|
88
|
+
}
|
89
|
+
|
90
|
+
bool OS::isSignalSafeTLS() {
|
91
|
+
return false;
|
92
|
+
}
|
93
|
+
|
94
|
+
bool OS::isJavaLibraryVisible() {
|
95
|
+
return true;
|
96
|
+
}
|
97
|
+
|
98
|
+
void OS::installSignalHandler(int signo, void (*handler)(int, siginfo_t*, void*)) {
|
99
|
+
struct sigaction sa;
|
100
|
+
sigemptyset(&sa.sa_mask);
|
101
|
+
sa.sa_sigaction = handler;
|
102
|
+
sa.sa_flags = SA_RESTART | SA_SIGINFO;
|
103
|
+
|
104
|
+
sigaction(signo, &sa, NULL);
|
105
|
+
}
|
106
|
+
|
107
|
+
void OS::sendSignalToThread(int thread_id, int signo) {
|
108
|
+
asm volatile("syscall" : : "a"(0x2000148), "D"(thread_id), "S"(signo));
|
109
|
+
}
|
110
|
+
|
111
|
+
ThreadList* OS::listThreads() {
|
112
|
+
return new MacThreadList();
|
113
|
+
}
|
114
|
+
|
115
|
+
#endif // __APPLE__
|
@@ -0,0 +1,60 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2017 Andrei Pangin
|
3
|
+
*
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
5
|
+
* you may not use this file except in compliance with the License.
|
6
|
+
* You may obtain a copy of the License at
|
7
|
+
*
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
9
|
+
*
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
+
* See the License for the specific language governing permissions and
|
14
|
+
* limitations under the License.
|
15
|
+
*/
|
16
|
+
|
17
|
+
#ifndef _PERFEVENTS_H
|
18
|
+
#define _PERFEVENTS_H
|
19
|
+
|
20
|
+
#include <signal.h>
|
21
|
+
#include "engine.h"
|
22
|
+
|
23
|
+
|
24
|
+
class PerfEvent;
|
25
|
+
class PerfEventType;
|
26
|
+
|
27
|
+
class PerfEvents : public Engine {
|
28
|
+
private:
|
29
|
+
static int _max_events;
|
30
|
+
static PerfEvent* _events;
|
31
|
+
static PerfEventType* _event_type;
|
32
|
+
static long _interval;
|
33
|
+
static Ring _ring;
|
34
|
+
static bool _print_extended_warning;
|
35
|
+
|
36
|
+
static bool createForThread(int tid);
|
37
|
+
static void destroyForThread(int tid);
|
38
|
+
static void signalHandler(int signo, siginfo_t* siginfo, void* ucontext);
|
39
|
+
|
40
|
+
public:
|
41
|
+
const char* name() {
|
42
|
+
return "perf";
|
43
|
+
}
|
44
|
+
|
45
|
+
const char* units();
|
46
|
+
|
47
|
+
Error start(Arguments& args);
|
48
|
+
void stop();
|
49
|
+
|
50
|
+
void onThreadStart();
|
51
|
+
void onThreadEnd();
|
52
|
+
|
53
|
+
int getNativeTrace(void* ucontext, int tid, const void** callchain, int max_depth,
|
54
|
+
const void* jit_min_address, const void* jit_max_address);
|
55
|
+
|
56
|
+
static bool supported();
|
57
|
+
static const char* getEventName(int event_id);
|
58
|
+
};
|
59
|
+
|
60
|
+
#endif // _PERFEVENTS_H
|