+/*
+ * Start logging when cpu usage is high. Meanwhile, moniter the cpu usage and
+ * stop logging when it drops down.
+ */
+static void start_tracing(void) {
+ ALOGD("High cpu usage, start logging.");
+
+ if (dfs_enable(true, dfs_control_path) != 0) {
+ ALOGE("Failed to start tracing.");
+ return;
+ }
+ tracing = true;
+
+ /* Stop logging when cpu usage drops or the daemon is suspended.*/
+ do {
+ usleep(tracing_check_period);
+ } while (!suspend && !dump_requested && is_heavy_load());
+
+ if (dfs_enable(false, dfs_control_path) != 0) {
+ ALOGE("Failed to stop tracing.");
+ err = true;
+ return;
+ }
+ tracing = false;
+
+ if (suspend) {
+ ALOGI("trace stopped due to suspend. Send SIGCONT to resume.");
+ } else if (dump_requested) {
+ ALOGI("trace stopped due to dump request.");
+ dump_trace();
+ dump_requested = false;
+ } else {
+ ALOGD("Usage back to low, stop logging.");
+ }
+}
+
+/*
+ * Set the tracing log buffer size.
+ * Note the actual buffer size will be buf_size_kb * number of cores.
+ */
+static int set_tracing_buffer_size(void) {
+ int fd = open(dfs_buffer_size_path, O_WRONLY);
+ if (fd == -1) {
+ err = true;
+ sprintf(err_msg, "Can't open atrace buffer size file under /d/tracing.");
+ return -1;
+ }
+ ssize_t len = strlen(buf_size_kb);
+ if (write(fd, buf_size_kb, len) != len) {
+ err = true;
+ sprintf(err_msg, "Error in writing to atrace buffer size file.");
+ }
+ close(fd);
+ return (err?-1:0);
+
+}
+
+/*
+ * Main loop to moniter the cpu usage and decided whether to start logging.
+ */
+static void start(void) {
+ if ((set_tracing_buffer_size()) != 0)
+ return;
+
+ dfs_set_property(tag, apps, true);
+ dfs_poke_binder();
+
+ get_cpu_stat(&old_cpu);
+ sleep(check_period);
+
+ while (!quit && !err) {
+ if (!suspend && is_heavy_load()) {
+ /*
+ * Increase process priority to make sure we can stop logging when
+ * necessary and do not overwrite the buffer
+ */
+ setpriority(PRIO_PROCESS, 0, -20);
+ start_tracing();
+ setpriority(PRIO_PROCESS, 0, 0);
+ }
+ sleep(check_period);
+ }
+ return;
+}
+
+/*
+ * If trace is not running, dump trace right away.
+ * If trace is running, request to dump trace.
+ */
+static void request_dump_trace()
+{
+ if (!tracing) {
+ dump_trace();
+ } else if (!dump_requested) {
+ dump_requested = true;
+ }
+}
+