// Copyright 2021 The Bazel Authors. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include #include #include #include "src/main/cpp/util/logging.h" #include "src/main/native/darwin/util.h" #include "src/main/native/unix_jni.h" namespace blaze_jni { static int gThermalNotifyToken = 0; static int thermal_load_from_token(int token) { uint64_t state; uint32_t status = notify_get_state(token, &state); BAZEL_CHECK_EQ(status, NOTIFY_STATUS_OK); OSThermalPressureLevel thermalLevel = (OSThermalPressureLevel)state; int load = -1; switch (thermalLevel) { case kOSThermalPressureLevelNominal: BAZEL_LOG(USER) << "thermal pressure nominal (0) anomaly"; load = 0; break; case kOSThermalPressureLevelModerate: BAZEL_LOG(USER) << "thermal pressure moderate (33) anomaly "; load = 33; break; case kOSThermalPressureLevelHeavy: BAZEL_LOG(USER) << "thermal pressure heavy (50) anomaly"; load = 50; break; case kOSThermalPressureLevelTrapping: BAZEL_LOG(USER) << "thermal pressure trapping (90) anomaly"; load = 90; break; case kOSThermalPressureLevelSleeping: BAZEL_LOG(USER) << "thermal pressure sleeping (100) anomaly"; load = 100; break; } if (load == -1) { BAZEL_LOG(FATAL) << "unknown thermal pressure level: " << thermalLevel; } return load; } void portable_start_thermal_monitoring() { // To test use: // sudo thermal simulate cpu {nominal|moderate|heavy|trapping|sleeping} // Note that we install the test notification as well that can be used for // testing. static dispatch_once_t once_token; dispatch_once(&once_token, ^{ dispatch_queue_t queue = bazel::darwin::JniDispatchQueue(); notify_handler_t handler = (^(int token) { int value = thermal_load_from_token(token); thermal_callback(value); }); int status = notify_register_dispatch(kOSThermalNotificationPressureLevelName, &gThermalNotifyToken, queue, handler); BAZEL_CHECK_EQ(status, NOTIFY_STATUS_OK); // This is registered solely so we can test the system from end-to-end. // Using the Apple notification requires admin access. int testToken; status = notify_register_dispatch("com.google.bazel.test.thermalpressurelevel", &testToken, queue, handler); BAZEL_CHECK_EQ(status, NOTIFY_STATUS_OK); BAZEL_LOG(INFO) << "thermal monitoring registered"; }); } int portable_thermal_load() { return thermal_load_from_token(gThermalNotifyToken); } } // namespace blaze_jni