Skip to content

Commit d4f97df

Browse files
authored
Merge pull request eclipse-openj9#20948 from adpopescu/jfr-threadstats
Adding in jfr thread statistics event.
2 parents fbdfdf3 + e434c1d commit d4f97df

8 files changed

+132
-1
lines changed

runtime/oti/j9consts.h

+1
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@ extern "C" {
953953
#define J9JFR_EVENT_TYPE_CLASS_LOADING_STATISTICS 7
954954
#define J9JFR_EVENT_TYPE_THREAD_CONTEXT_SWITCH_RATE 8
955955
#define J9JFR_EVENT_TYPE_THREAD_PARK 9
956+
#define J9JFR_EVENT_TYPE_THREAD_STATISTICS 10
956957

957958
/* JFR thread states */
958959

runtime/oti/j9nonbuilder.h

+10
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,14 @@ typedef struct J9JFRClassLoadingStatistics {
460460
I_64 unloadedClassCount;
461461
} J9JFRClassLoadingStatistics;
462462

463+
typedef struct J9JFRThreadStatistics {
464+
J9JFR_EVENT_COMMON_FIELDS
465+
U_32 activeThreadCount;
466+
U_32 daemonThreadCount;
467+
U_32 accumulatedThreadCount;
468+
U_32 peakThreadCount;
469+
} J9JFRThreadStatistics;
470+
463471
typedef struct J9JFRThreadContextSwitchRate {
464472
J9JFR_EVENT_COMMON_FIELDS
465473
float switchRate;
@@ -5880,6 +5888,8 @@ typedef struct J9JavaVM {
58805888
UDATA anonClassCount;
58815889
UDATA totalThreadCount;
58825890
UDATA daemonThreadCount;
5891+
UDATA accumulatedThreadCount;
5892+
UDATA peakThreadCount;
58835893
omrthread_t finalizeMainThread;
58845894
omrthread_monitor_t finalizeMainMonitor;
58855895
omrthread_monitor_t processReferenceMonitor; /* the monitor for synchronizing between reference process and j9gc_wait_for_reference_processing() (only for Java 9 and later) */

runtime/vm/JFRChunkWriter.cpp

+31
Original file line numberDiff line numberDiff line change
@@ -911,4 +911,35 @@ VM_JFRChunkWriter::writeThreadContextSwitchRateEvent(void *anElement, void *user
911911
_bufferWriter->writeLEB128PaddedU32(dataStart, (U_32)(_bufferWriter->getCursor() - dataStart));
912912
}
913913

914+
void
915+
VM_JFRChunkWriter::writeThreadStatisticsEvent(void *anElement, void *userData)
916+
{
917+
ThreadStatisticsEntry *entry = (ThreadStatisticsEntry *)anElement;
918+
VM_BufferWriter *_bufferWriter = (VM_BufferWriter *)userData;
919+
920+
/* reserve event size */
921+
U_8 *dataStart = _bufferWriter->getAndIncCursor(sizeof(U_32));
922+
923+
/* write event type */
924+
_bufferWriter->writeLEB128(ThreadStatisticsID);
925+
926+
/* write start ticks */
927+
_bufferWriter->writeLEB128(entry->ticks);
928+
929+
/* write active thread count */
930+
_bufferWriter->writeLEB128(entry->activeThreadCount);
931+
932+
/* write daemon thread count */
933+
_bufferWriter->writeLEB128(entry->daemonThreadCount);
934+
935+
/* write accumulated thread count */
936+
_bufferWriter->writeLEB128(entry->accumulatedThreadCount);
937+
938+
/* write peak thread count */
939+
_bufferWriter->writeLEB128(entry->peakThreadCount);
940+
941+
/* write size */
942+
_bufferWriter->writeLEB128PaddedU32(dataStart, _bufferWriter->getCursor() - dataStart);
943+
}
944+
914945
#endif /* defined(J9VM_OPT_JFR) */

runtime/vm/JFRChunkWriter.hpp

+8-1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ enum MetadataTypeID {
7676
CPULoadID = 95,
7777
ThreadCPULoadID = 96,
7878
ThreadContextSwitchRateID = 97,
79+
ThreadStatisticsID = 99,
7980
ClassLoadingStatisticsID = 100,
8081
PhysicalMemoryID = 108,
8182
ExecutionSampleID = 109,
@@ -170,6 +171,7 @@ class VM_JFRChunkWriter {
170171
static constexpr int INITIAL_ENVIRONMENT_VARIABLE_EVENT_SIZE = 6000;
171172
static constexpr int CLASS_LOADING_STATISTICS_EVENT_SIZE = 5 * sizeof(I_64);
172173
static constexpr int THREAD_CONTEXT_SWITCH_RATE_SIZE = sizeof(float) + (3 * sizeof(I_64));
174+
static constexpr int THREAD_STATISTICS_EVENT_SIZE = (6 * sizeof(U_64)) + sizeof(U_32);
173175

174176
static constexpr int METADATA_ID = 1;
175177

@@ -351,6 +353,8 @@ class VM_JFRChunkWriter {
351353

352354
pool_do(_constantPoolTypes.getThreadContextSwitchRateTable(), &writeThreadContextSwitchRateEvent, _bufferWriter);
353355

356+
pool_do(_constantPoolTypes.getThreadStatisticsTable(), &writeThreadStatisticsEvent, _bufferWriter);
357+
354358
/* Only write constant events in first chunk */
355359
if (0 == _vm->jfrState.jfrChunkCount) {
356360
writeJVMInformationEvent();
@@ -598,7 +602,6 @@ class VM_JFRChunkWriter {
598602
_bufferWriter->writeLEB128PaddedU32(dataStart, _bufferWriter->getCursor() - dataStart);
599603
}
600604

601-
602605
static void
603606
writeCPULoadEvent(void *anElement, void *userData)
604607
{
@@ -727,6 +730,8 @@ class VM_JFRChunkWriter {
727730

728731
static void writeThreadContextSwitchRateEvent(void *anElement, void *userData);
729732

733+
static void writeThreadStatisticsEvent(void *anElement, void *userData);
734+
730735
UDATA
731736
calculateRequiredBufferSize()
732737
{
@@ -793,6 +798,8 @@ class VM_JFRChunkWriter {
793798

794799
requiredBufferSize += _constantPoolTypes.getThreadContextSwitchRateCount() * THREAD_CONTEXT_SWITCH_RATE_SIZE;
795800

801+
requiredBufferSize += (_constantPoolTypes.getThreadStatisticsCount() * THREAD_STATISTICS_EVENT_SIZE);
802+
796803
return requiredBufferSize;
797804
}
798805

runtime/vm/JFRConstantPoolTypes.cpp

+22
Original file line numberDiff line numberDiff line change
@@ -1219,6 +1219,28 @@ VM_JFRConstantPoolTypes::addThreadContextSwitchRateEntry(J9JFRThreadContextSwitc
12191219
_threadContextSwitchRateCount += 1;
12201220
}
12211221

1222+
void
1223+
VM_JFRConstantPoolTypes::addThreadStatisticsEntry(J9JFRThreadStatistics *threadStatisticsData)
1224+
{
1225+
ThreadStatisticsEntry *entry = (ThreadStatisticsEntry *)pool_newElement(_threadStatisticsTable);
1226+
1227+
if (NULL == entry) {
1228+
_buildResult = OutOfMemory;
1229+
goto done;
1230+
}
1231+
1232+
entry->ticks = threadStatisticsData->startTicks;
1233+
entry->activeThreadCount = threadStatisticsData->activeThreadCount;
1234+
entry->daemonThreadCount = threadStatisticsData->daemonThreadCount;
1235+
entry->accumulatedThreadCount = threadStatisticsData->accumulatedThreadCount;
1236+
entry->peakThreadCount = threadStatisticsData->peakThreadCount;
1237+
1238+
_threadStatisticsCount += 1;
1239+
1240+
done:
1241+
return;
1242+
}
1243+
12221244
void
12231245
VM_JFRConstantPoolTypes::printTables()
12241246
{

runtime/vm/JFRConstantPoolTypes.hpp

+34
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,14 @@ struct ThreadContextSwitchRateEntry {
251251
float switchRate;
252252
};
253253

254+
struct ThreadStatisticsEntry {
255+
I_64 ticks;
256+
U_32 activeThreadCount;
257+
U_32 daemonThreadCount;
258+
U_32 accumulatedThreadCount;
259+
U_32 peakThreadCount;
260+
};
261+
254262
struct JVMInformationEntry {
255263
const char *jvmName;
256264
const char *jvmVersion;
@@ -338,6 +346,8 @@ class VM_JFRConstantPoolTypes {
338346
UDATA _classLoadingStatisticsCount;
339347
J9Pool *_threadContextSwitchRateTable;
340348
U_32 _threadContextSwitchRateCount;
349+
J9Pool *_threadStatisticsTable;
350+
UDATA _threadStatisticsCount;
341351

342352
/* Processing buffers */
343353
StackFrame *_currentStackFrameBuffer;
@@ -611,6 +621,8 @@ class VM_JFRConstantPoolTypes {
611621

612622
void addThreadContextSwitchRateEntry(J9JFRThreadContextSwitchRate *threadContextSwitchRateData);
613623

624+
void addThreadStatisticsEntry(J9JFRThreadStatistics *threadStatisticsData);
625+
614626
J9Pool *getExecutionSampleTable()
615627
{
616628
return _executionSampleTable;
@@ -661,6 +673,11 @@ class VM_JFRConstantPoolTypes {
661673
return _threadContextSwitchRateTable;
662674
}
663675

676+
J9Pool *getThreadStatisticsTable()
677+
{
678+
return _threadStatisticsTable;
679+
}
680+
664681
UDATA getExecutionSampleCount()
665682
{
666683
return _executionSampleCount;
@@ -711,6 +728,11 @@ class VM_JFRConstantPoolTypes {
711728
return _threadContextSwitchRateCount;
712729
}
713730

731+
UDATA getThreadStatisticsCount()
732+
{
733+
return _threadStatisticsCount;
734+
}
735+
714736
ClassloaderEntry *getClassloaderEntry()
715737
{
716738
return _firstClassloaderEntry;
@@ -869,6 +891,9 @@ class VM_JFRConstantPoolTypes {
869891
case J9JFR_EVENT_TYPE_THREAD_CONTEXT_SWITCH_RATE:
870892
addThreadContextSwitchRateEntry((J9JFRThreadContextSwitchRate *)event);
871893
break;
894+
case J9JFR_EVENT_TYPE_THREAD_STATISTICS:
895+
addThreadStatisticsEntry((J9JFRThreadStatistics *)event);
896+
break;
872897
default:
873898
Assert_VM_unreachable();
874899
break;
@@ -1201,6 +1226,8 @@ class VM_JFRConstantPoolTypes {
12011226
, _classLoadingStatisticsCount(0)
12021227
, _threadContextSwitchRateTable(NULL)
12031228
, _threadContextSwitchRateCount(0)
1229+
, _threadStatisticsTable(NULL)
1230+
, _threadStatisticsCount(0)
12041231
, _previousStackTraceEntry(NULL)
12051232
, _firstStackTraceEntry(NULL)
12061233
, _previousThreadEntry(NULL)
@@ -1333,6 +1360,12 @@ class VM_JFRConstantPoolTypes {
13331360
goto done;
13341361
}
13351362

1363+
_threadStatisticsTable = pool_new(sizeof(ThreadStatisticsEntry), 0, sizeof(U_64), 0, J9_GET_CALLSITE(), OMRMEM_CATEGORY_VM, POOL_FOR_PORT(privatePortLibrary));
1364+
if (NULL == _threadStatisticsTable ) {
1365+
_buildResult = OutOfMemory;
1366+
goto done;
1367+
}
1368+
13361369
/* Add reserved index for default entries. For strings zero is the empty or NUll string.
13371370
* For package zero is the deafult package, for Module zero is the unnamed module. ThreadGroup
13381371
* zero is NULL threadGroup.
@@ -1424,6 +1457,7 @@ class VM_JFRConstantPoolTypes {
14241457
pool_kill(_threadCPULoadTable);
14251458
pool_kill(_classLoadingStatisticsTable);
14261459
pool_kill(_threadContextSwitchRateTable);
1460+
pool_kill(_threadStatisticsTable);
14271461
j9mem_free_memory(_globalStringTable);
14281462
}
14291463

runtime/vm/jfr.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ jfrEventSize(J9JFREvent *jfrEvent)
103103
case J9JFR_EVENT_TYPE_THREAD_CONTEXT_SWITCH_RATE:
104104
size = sizeof(J9JFRThreadContextSwitchRate);
105105
break;
106+
case J9JFR_EVENT_TYPE_THREAD_STATISTICS:
107+
size = sizeof(J9JFRThreadStatistics);
108+
break;
106109
default:
107110
Assert_VM_unreachable();
108111
break;
@@ -1064,6 +1067,23 @@ jfrThreadContextSwitchRate(J9VMThread *currentThread)
10641067
}
10651068
}
10661069

1070+
void
1071+
jfrThreadStatistics(J9VMThread *currentThread)
1072+
{
1073+
J9JavaVM *vm = currentThread->javaVM;
1074+
J9JFRThreadStatistics *jfrEvent = (J9JFRThreadStatistics *)reserveBuffer(currentThread, sizeof(J9JFRThreadStatistics));
1075+
1076+
if (NULL != jfrEvent) {
1077+
initializeEventFields(currentThread, (J9JFREvent *)jfrEvent, J9JFR_EVENT_TYPE_THREAD_STATISTICS);
1078+
1079+
jfrEvent->activeThreadCount = vm->totalThreadCount;
1080+
jfrEvent->daemonThreadCount = vm->daemonThreadCount;
1081+
jfrEvent->accumulatedThreadCount = vm->accumulatedThreadCount;
1082+
jfrEvent->peakThreadCount = vm->peakThreadCount;
1083+
}
1084+
1085+
}
1086+
10671087
static int J9THREAD_PROC
10681088
jfrSamplingThreadProc(void *entryArg)
10691089
{
@@ -1082,6 +1102,7 @@ jfrSamplingThreadProc(void *entryArg)
10821102
internalAcquireVMAccess(currentThread);
10831103
jfrCPULoad(currentThread);
10841104
jfrClassLoadingStatistics(currentThread);
1105+
jfrThreadStatistics(currentThread);
10851106
if (0 == (count % 1000)) { // 10 seconds
10861107
J9SignalAsyncEvent(vm, NULL, vm->jfrThreadCPULoadAsyncKey);
10871108
jfrThreadContextSwitchRate(currentThread);

runtime/vm/vmthread.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,11 @@ allocateVMThread(J9JavaVM *vm, omrthread_t osThread, UDATA privateFlags, void *m
347347
/* Update counters for total # of threads and daemon threads and notify anyone waiting */
348348

349349
++(vm->totalThreadCount);
350+
++(vm->accumulatedThreadCount);
351+
if (vm->totalThreadCount > vm->peakThreadCount) {
352+
vm->peakThreadCount = vm->totalThreadCount;
353+
}
354+
350355
if (privateFlags & J9_PRIVATE_FLAGS_DAEMON_THREAD) {
351356
++(vm->daemonThreadCount);
352357
}

0 commit comments

Comments
 (0)