Skip to content

Commit c48e8b1

Browse files
committed
new prototype
Signed-off-by: Gengchen Tuo <[email protected]>
1 parent 7af7e4e commit c48e8b1

File tree

7 files changed

+134
-108
lines changed

7 files changed

+134
-108
lines changed

runtime/oti/j9nonbuilder.h

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5862,10 +5862,9 @@ typedef struct J9VMThread {
58625862
#if defined(J9VM_OPT_JFR)
58635863
J9ThreadJFRState threadJfrState;
58645864
#endif /* defined(J9VM_OPT_JFR) */
5865-
U_64 parkWaitTime;
5865+
U_64 prevParkRateTime;
58665866
U_64 parkCount;
5867-
U_64 parkWaitSlidingWindowIndex;
5868-
U_64 *parkWaitSlidingWindow;
5867+
double parkRate;
58695868
volatile UDATA prePark;
58705869
} J9VMThread;
58715870

@@ -6158,23 +6157,18 @@ typedef struct J9JavaVM {
61586157
UDATA thrDeflationPolicy;
61596158
UDATA thrParkSpinCount1;
61606159
UDATA thrParkSpinCount2;
6161-
U_64 parkSpinWaitThreshold;
6162-
U_64 parkWaitSlidingWindowSize;
6163-
double parkSpinRatioOfAvgWait;
6164-
UDATA parkYield;
6165-
UDATA parkLock;
6166-
U_64 parkSleepMultiplier;
6160+
UDATA parkSleepMultiplier;
6161+
UDATA parkSleepTime;
6162+
UDATA parkPolicy;
61676163
U_64 yieldUsleepMultiplier;
61686164
UDATA gcOptions;
61696165
UDATA ( *unhookVMEvent)(struct J9JavaVM *javaVM, UDATA eventNumber, void * currentHandler, void * oldHandler) ;
61706166
UDATA classLoadingMaxStack;
61716167
U_8* callInReturnPC;
6172-
float machineTotal;
6173-
float jvmUser;
6174-
float jvmSystem;
6175-
J9SysinfoCPUTime prevSysCPUTime;
6176-
j9thread_process_time_t prevProcCPUTimes;
6177-
I_64 prevProcTimestamp;
6168+
float contextSwitchRate;
6169+
omrthread_t cpuUtilCalcThread;
6170+
omrthread_monitor_t cpuUtilCalcMutex;
6171+
I_64 prevContextSwitchTimestamp;
61786172
double thresholdMedium;
61796173
double thresholdHigh;
61806174
UDATA recalcThresholdNanos;

runtime/oti/vm_api.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4679,6 +4679,8 @@ threadParseArguments(J9JavaVM *vm, char *optArg);
46794679
UDATA
46804680
getJavaThreadPriority(struct J9JavaVM *vm, J9VMThread* thread );
46814681

4682+
void startcpuUtilCalcProc(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData);
4683+
46824684
#if JAVA_SPEC_VERSION >= 19
46834685
/* ---------------- ContinuationHelpers.cpp ---------------- */
46844686

runtime/vm/j9vm.tdf

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,6 @@ TraceEvent=Trc_VM_enterContinuation_Mount Overhead=1 Level=6 Template="enterCont
10251025
TraceEvent=Trc_VM_yieldContinuation_Unmount Overhead=1 Level=6 Template="yieldContinuation: Unmounted continuation %p, returnState (%zu), ownedMonitorCount (%zu), enteredMonitors (%p)"
10261026
TraceEvent=Trc_VM_detachMonitorInfo_Detach Overhead=1 Level=6 Template="Detach monitor: currentContinuation (%p), objectMonitor (%p), monitor (%p), monitor->owner (%p), monitor->count (%zu), osThread (%p)"
10271027
TraceEvent=Trc_VM_updateMonitorInfo_Attach Overhead=1 Level=6 Template="Attach monitor: currentContinuation (%p), objectMonitor (%p), monitor (%p), monitor->owner (%p), monitor->count (%zu), osThread (%p)"
1028-
TraceEvent=Trc_VM_ThreadHelp_timeCompensationHelper_parkWait Env Overhead=1 Level=5 Template="Park machineTotal=%f currentTime=%llu"
1029-
TraceEvent=Trc_VM_ThreadHelp_timeCompensationHelper_parkWaited Env Overhead=1 Level=5 Template="Park waited waittime=%llu policy=%llu earlybreak=%d count=%llu"
1030-
TraceEvent=Trc_VM_ThreadHelp_timeCompensationHelper_parkMachine Env Overhead=1 Level=5 Template="Park cpu calc currentCPUtime=%llu prevCPUtime=%llu numCPus=%d currentTime=%llu prevTime=%llu"
1028+
TraceEvent=Trc_VM_ThreadHelp_timeCompensationHelper_parkWait Env Overhead=1 Level=5 Template="Park switch_rate=%f"
1029+
TraceEvent=Trc_VM_ThreadHelp_timeCompensationHelper_parkWaited Env Overhead=1 Level=5 Template="Park waited waittime=%llu policy=%llu earlybreak=%d count=%llu parkRate=%.2f switchRate=%.2f"
1030+
TraceEvent=Trc_VM_ThreadHelp_timeCompensationHelper_parkMachine Env Overhead=1 Level=5 Template="Park cpu machineTotal=%f"

runtime/vm/jvminit.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7656,6 +7656,15 @@ protectedInitializeJavaVM(J9PortLibrary* portLibrary, void * userData)
76567656
}
76577657
}
76587658
#endif /* defined(J9VM_OPT_JFR) */
7659+
if (omrthread_monitor_init_with_name(&vm->cpuUtilCalcMutex, 0, "CPU Util Calc Mutex")) {
7660+
printf("error mutex\n");
7661+
goto error;
7662+
}
7663+
vmHooks = getVMHookInterface(vm);
7664+
if ((*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_INITIALIZED, startcpuUtilCalcProc, OMR_GET_CALLSITE(), NULL)) {
7665+
printf("error thread\n");
7666+
goto error;
7667+
}
76597668

76607669
/* Use this stage to load libraries which need to set up hooks as early as possible */
76617670
if (JNI_OK != runLoadStage(vm, EARLY_LOAD)) {

runtime/vm/threadhelp.cpp

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -462,73 +462,72 @@ timeCompensationHelper(J9VMThread *vmThread, U_8 threadHelperType, omrthread_mon
462462
break;
463463
case HELPER_TYPE_THREAD_PARK:
464464
{
465+
if (vm->parkPolicy == 0) {
466+
rc = omrthread_park(millis, nanos);
467+
break;
468+
}
465469
PORT_ACCESS_FROM_VMC(vmThread);
466-
UDATA policy = 0;
467470
BOOLEAN earlyBreak = false;
468471
I_64 currentTime = j9time_nano_time();
469472

470473
vmThread->prePark = 1;
471474

472-
if ((vm->prevProcTimestamp == 0)
473-
|| ((UDATA)(currentTime - vm->prevProcTimestamp) > vm->recalcThresholdNanos)
474-
) {
475-
476-
J9SysinfoCPUTime currentSysCPUTime = {0};
477-
j9sysinfo_get_CPU_utilization(&currentSysCPUTime);
478-
479-
UDATA numberOfCpus = j9sysinfo_get_number_CPUs_by_type(J9PORT_CPU_TARGET);
480-
481-
if (vm->prevSysCPUTime.timestamp == 0) {
482-
// first run
483-
} else {
484-
vm->machineTotal = OMR_MIN((currentSysCPUTime.cpuTime - vm->prevSysCPUTime.cpuTime) / ((double)numberOfCpus * (currentSysCPUTime.timestamp - vm->prevSysCPUTime.timestamp)), 1.0);
485-
Trc_VM_ThreadHelp_timeCompensationHelper_parkMachine(vmThread, currentSysCPUTime.cpuTime, vm->prevSysCPUTime.cpuTime, numberOfCpus, currentTime, vm->prevProcTimestamp);
486-
}
487-
vm->prevProcTimestamp = currentTime;
488-
vm->prevSysCPUTime = currentSysCPUTime;
489-
490-
Trc_VM_ThreadHelp_timeCompensationHelper_parkWait(vmThread, vm->machineTotal, currentTime);
491-
}
475+
// TODO enable park rate all the time
476+
if (vm->parkPolicy == 4) {
477+
vmThread->parkCount += 1;
492478

493-
if (vm->machineTotal != 0) {
494-
if (vm->machineTotal > (float)vm->thresholdHigh) {
495-
policy = 2;
496-
} else if (vm->machineTotal > (float)vm->thresholdMedium) {
497-
policy = 1;
498-
} else {
499-
policy = 0;
479+
if ((vmThread->prevParkRateTime == 0)
480+
|| ((UDATA)(currentTime - vmThread->prevParkRateTime) > vm->recalcThresholdNanos)
481+
) {
482+
if (vmThread->prevParkRateTime != 0) {
483+
vmThread->parkRate = double(vmThread->parkCount) / (currentTime - vmThread->prevParkRateTime) * 1e9;
484+
}
485+
vmThread->prevParkRateTime = currentTime;
486+
vmThread->parkCount = 0;
500487
}
501488
}
502489

503490
UDATA count = 0;
491+
UDATA policy = -1;
492+
if (vm->parkPolicy <= 2) {
493+
policy = vm->parkPolicy;
494+
} else if (vm->parkPolicy == 3) {
495+
double contextSwitchRate = vm->contextSwitchRate;
496+
if (contextSwitchRate > vm->thresholdHigh) policy = 2;
497+
else if (contextSwitchRate > vm->thresholdMedium) policy = 1;
498+
else policy = 0;
499+
} else {
500+
double parkRate = vmThread->parkRate;
501+
if (parkRate > vm->thresholdHigh) policy = 2;
502+
else if (parkRate > vm->thresholdMedium) policy = 1;
503+
else policy = 0;
504+
}
504505

505-
if (0 != policy) {
506-
507-
if (1 == policy) {
508-
/* spin */
509-
for (IDATA spinCount1 = vm->thrParkSpinCount1; spinCount1 > 0; --spinCount1) {
510-
VM_AtomicSupport::yieldCPU();
511-
count++;
512-
if (vmThread->prePark == 0) {
513-
earlyBreak = TRUE;
514-
break;
515-
}
506+
if (1 == policy) {
507+
/* spin */
508+
for (IDATA spinCount1 = vm->thrParkSpinCount1; spinCount1 > 0; --spinCount1) {
509+
VM_AtomicSupport::yieldCPU();
510+
count++;
511+
if (vmThread->prePark == 0) {
512+
earlyBreak = TRUE;
513+
break;
516514
}
517-
} else if (2 == policy) {
518-
for (IDATA spinCount2 = vm->thrParkSpinCount2; spinCount2 > 0; --spinCount2) {
519-
count++;
520-
usleep(((spinCount2 * vm->parkSleepMultiplier) + 1) * vm->yieldUsleepMultiplier);
521-
if (vmThread->prePark == 0) {
522-
earlyBreak = TRUE;
523-
break;
524-
}
515+
}
516+
} else if (2 == policy) {
517+
for (IDATA spinCount2 = vm->thrParkSpinCount2; spinCount2 > 0; --spinCount2) {
518+
count++;
519+
usleep(((spinCount2 * vm->parkSleepMultiplier) + 1) * vm->parkSleepTime);
520+
if (vmThread->prePark == 0) {
521+
earlyBreak = TRUE;
522+
break;
525523
}
526524
}
527-
rc = omrthread_park(millis, nanos);
528-
} else {
529-
rc = omrthread_park(millis, nanos);
530525
}
531-
Trc_VM_ThreadHelp_timeCompensationHelper_parkWaited(vmThread, j9time_nano_time()-currentTime, policy, earlyBreak, count);
526+
527+
rc = omrthread_park(millis, nanos);
528+
529+
// TODO add context switch rate
530+
Trc_VM_ThreadHelp_timeCompensationHelper_parkWaited(vmThread, j9time_nano_time()-currentTime, policy, earlyBreak, count, vmThread->parkRate, vm->contextSwitchRate);
532531
break;
533532
}
534533
case HELPER_TYPE_THREAD_SLEEP:

runtime/vm/vmthinit.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,6 @@ void freeVMThread(J9JavaVM *vm, J9VMThread *vmThread)
126126
/* Free J9RIParameters. */
127127
j9mem_free_memory(vmThread->riParameters);
128128
}
129-
j9mem_free_memory(vmThread->parkWaitSlidingWindow);
130129

131130
#endif /* defined(J9VM_PORT_RUNTIME_INSTRUMENTATION) */
132131
if (J9JAVAVM_COMPRESS_OBJECT_REFERENCES(vm)) {

runtime/vm/vmthread.cpp

Lines changed: 61 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -300,10 +300,9 @@ allocateVMThread(J9JavaVM *vm, omrthread_t osThread, UDATA privateFlags, void *m
300300
#if defined(J9VM_OPT_JFR)
301301
newThread->threadJfrState.prevTimestamp = -1;
302302
#endif /* defined(J9VM_OPT_JFR) */
303-
newThread->parkWaitSlidingWindow = (U_64*) j9mem_allocate_memory(vm->parkWaitSlidingWindowSize * sizeof(U_64), OMRMEM_CATEGORY_VM);
304-
if (NULL == newThread->parkWaitSlidingWindow) {
305-
goto fail;
306-
}
303+
newThread->parkCount = 0;
304+
newThread->prevParkRateTime = 0;
305+
newThread->parkRate = 0;
307306

308307
/* If an exclusive access request is in progress, mark this thread */
309308

@@ -598,20 +597,19 @@ threadParseArguments(J9JavaVM *vm, char *optArg)
598597
vm->thrDeflationPolicy = J9VM_DEFLATION_POLICY_ASAP;
599598
vm->thrParkSpinCount1 = 0;
600599
vm->thrParkSpinCount2 = 0;
601-
vm->parkSpinWaitThreshold = 0;
602-
vm->parkWaitSlidingWindowSize = 0;
603-
vm->parkSpinRatioOfAvgWait = 0.95;
604-
vm->parkLock = 0;
605-
vm->parkYield = 0;
600+
606601
vm->parkSleepMultiplier = 0;
602+
vm->parkSleepTime = 0;
607603
vm->yieldUsleepMultiplier = 0;
608-
vm->machineTotal = 0.0f;
609-
vm->jvmUser = 0.0f;
610-
vm->prevSysCPUTime = {0};
611-
vm->prevProcCPUTimes = {0};
612-
vm->prevProcTimestamp = 0;
604+
605+
vm->prevContextSwitchTimestamp = 0;
606+
613607
vm->thresholdHigh = 0.9f;
614608
vm->thresholdMedium = 0.6f;
609+
// 0: always system park, 1: always spin, 2: always sleep,
610+
// 3: controlled by context switch rate
611+
// 4: controlled by park rate
612+
vm->parkPolicy = 0;
615613
vm->recalcThresholdNanos = 500*1000*1000;
616614

617615
if (cpus > 1) {
@@ -886,38 +884,20 @@ threadParseArguments(J9JavaVM *vm, char *optArg)
886884
}
887885
continue;
888886
}
889-
if (try_scan(&scan_start, "parkSpinWaitThreshold=")) {
890-
if (scan_udata(&scan_start, &vm->parkSpinWaitThreshold)) {
891-
goto _error;
892-
}
893-
continue;
894-
}
895-
if (try_scan(&scan_start, "parkWaitSlidingWindowSize=")) {
896-
if (scan_udata(&scan_start, &vm->parkWaitSlidingWindowSize)) {
897-
goto _error;
898-
}
899-
continue;
900-
}
901-
if (try_scan(&scan_start, "parkSpinRatioOfAvgWait=")) {
902-
if (scan_double(&scan_start, &vm->parkSpinRatioOfAvgWait)) {
903-
goto _error;
904-
}
905-
continue;
906-
}
907-
if (try_scan(&scan_start, "parkYield=")) {
908-
if (scan_udata(&scan_start, &vm->parkYield)) {
887+
if (try_scan(&scan_start, "parkSleepMultiplier=")) {
888+
if (scan_udata(&scan_start, &vm->parkSleepMultiplier)) {
909889
goto _error;
910890
}
911891
continue;
912892
}
913-
if (try_scan(&scan_start, "parkLock=")) {
914-
if (scan_udata(&scan_start, &vm->parkLock)) {
893+
if (try_scan(&scan_start, "parkSleepTime=")) {
894+
if (scan_udata(&scan_start, &vm->parkSleepTime)) {
915895
goto _error;
916896
}
917897
continue;
918898
}
919-
if (try_scan(&scan_start, "parkSleepMultiplier=")) {
920-
if (scan_udata(&scan_start, &vm->parkSleepMultiplier)) {
899+
if (try_scan(&scan_start, "parkPolicy=")) {
900+
if (scan_udata(&scan_start, &vm->parkPolicy)) {
921901
goto _error;
922902
}
923903
continue;
@@ -2595,4 +2575,47 @@ threadAboutToStart(J9VMThread *currentThread)
25952575
TRIGGER_J9HOOK_THREAD_ABOUT_TO_START(vm->hookInterface, currentThread);
25962576
}
25972577

2578+
static int J9THREAD_PROC
2579+
cpuUtilCalcProc(void *entryArg)
2580+
{
2581+
J9JavaVM *vm = (J9JavaVM *)entryArg;
2582+
J9VMThread *currentThread = NULL;
2583+
static uint64_t prev_switches = 0;
2584+
2585+
if (JNI_OK == attachSystemDaemonThread(vm, &currentThread, "CPU util calc thread")) {
2586+
2587+
omrthread_monitor_enter(vm->cpuUtilCalcMutex);
2588+
PORT_ACCESS_FROM_JAVAVM(vm);
2589+
OMRPORT_ACCESS_FROM_J9PORT(PORTLIB);
2590+
while (1) {
2591+
I_64 currentTime = j9time_nano_time();
2592+
uint64_t switches = 0;
2593+
2594+
omrsysinfo_get_number_context_switches(&switches);
2595+
2596+
if (vm->prevContextSwitchTimestamp == 0) {
2597+
// first run
2598+
} else {
2599+
vm->contextSwitchRate = double(switches - prev_switches) / ((currentTime - vm->prevContextSwitchTimestamp) / 1e9);
2600+
Trc_VM_ThreadHelp_timeCompensationHelper_parkWait(currentThread, vm->contextSwitchRate);
2601+
}
2602+
prev_switches = switches;
2603+
vm->prevContextSwitchTimestamp = currentTime;
2604+
omrthread_monitor_wait_timed(vm->cpuUtilCalcMutex, vm->recalcThresholdNanos / 1e6, 0);
2605+
}
2606+
DetachCurrentThread((JavaVM*)vm);
2607+
omrthread_monitor_exit(vm->cpuUtilCalcMutex);
2608+
}
2609+
2610+
return 0;
2611+
}
2612+
2613+
void startcpuUtilCalcProc(J9HookInterface **hook, UDATA eventNum, void *eventData, void *userData) {
2614+
J9VMThread *currentThread = ((J9VMInitEvent *)eventData)->vmThread;
2615+
J9JavaVM *vm = currentThread->javaVM;
2616+
if (vm->parkPolicy == 3) {
2617+
omrthread_create(&(vm->cpuUtilCalcThread), vm->defaultOSStackSize, J9THREAD_PRIORITY_NORMAL, FALSE, cpuUtilCalcProc, (void*)vm);
2618+
}
2619+
}
2620+
25982621
} /* extern "C" */

0 commit comments

Comments
 (0)