110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/**
210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @file daemon/init.c
310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Daemon set up and main loop for 2.6
410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @remark Copyright 2002 OProfile authors
610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @remark Read the file COPYING
710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @author John Levon
910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @author Philippe Elie
1010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @Modifications Daniel Hansel
1110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Modified by Aravind Menon for Xen
1210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * These modifications are:
1310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Copyright (C) 2005 Hewlett-Packard Co.
1410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */
1510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
1610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "config.h"
1710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
1810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "oprofiled.h"
1910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_stats.h"
2010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_sfile.h"
2110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_pipe.h"
2210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_kernel.h"
2310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_trans.h"
2410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_anon.h"
2510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_perfmon.h"
2610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "opd_printf.h"
277a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown#include "opd_extended.h"
2810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
2910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_version.h"
3010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_config.h"
3110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_deviceio.h"
3210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_get_time.h"
3310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_libiberty.h"
3410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_fileio.h"
3510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
3610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <fcntl.h>
3710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <stdio.h>
3810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <errno.h>
3910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <limits.h>
4010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <stdlib.h>
4110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sys/time.h>
4210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#if ANDROID
4310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sys/wait.h>
4410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#else
4510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <wait.h>
4610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#endif
4710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <string.h>
4810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
4910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectsize_t kernel_pointer_size;
5010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
5110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic fd_t devfd;
5210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic char * sbuf;
5310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic size_t s_buf_bytesize;
5410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectextern char * session_dir;
5510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic char start_time_str[32];
5610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic int jit_conversion_running;
5710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
5810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_sighup(void);
5910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_alarm(void);
6010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_sigterm(void);
6110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_sigchild(void);
6210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_do_jitdumps(void);
6310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
6410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/**
6510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * opd_open_files - open necessary files
6610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
6710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Open the device files and the log file,
6810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * and mmap() the hash map.
6910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */
7010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_open_files(void)
7110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
7210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	devfd = op_open_device("/dev/oprofile/buffer");
7310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	if (devfd == -1) {
7410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		if (errno == EINVAL)
7510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			fprintf(stderr, "Failed to open device. Possibly you have passed incorrect\n"
7610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				"parameters. Check /var/log/messages.");
7710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		else
7810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			perror("Failed to open profile device");
7910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		exit(EXIT_FAILURE);
8010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	}
8110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
8210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	/* give output before re-opening stdout as the logfile */
8310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	printf("Using log file %s\n", op_log_file);
8410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
8510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	/* set up logfile */
8610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	close(0);
8710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	close(1);
8810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
8910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	if (open("/dev/null", O_RDONLY) == -1) {
9010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		perror("oprofiled: couldn't re-open stdin as /dev/null: ");
9110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		exit(EXIT_FAILURE);
9210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	}
9310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
9410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_open_logfile();
9510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_create_pipe();
9610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
9710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	printf("oprofiled started %s", op_get_time());
9810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	printf("kernel pointer size: %lu\n",
9910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		(unsigned long)kernel_pointer_size);
10010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	fflush(stdout);
10110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
10210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
10310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
10410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/** Done writing out the samples, indicate with complete_dump file */
10510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void complete_dump(void)
10610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
10710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	FILE * status_file;
10810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
10910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectretry:
11010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	status_file = fopen(op_dump_status, "w");
11110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
11210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	if (!status_file && errno == EMFILE) {
11310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		if (sfile_lru_clear()) {
11410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			printf("LRU cleared but file open fails for %s.\n",
11510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			       op_dump_status);
11610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			abort();
11710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		}
11810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		goto retry;
11910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	}
12010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
12110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	if (!status_file) {
12210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		perror("warning: couldn't set complete_dump: ");
12310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		return;
12410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	}
12510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
12610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	fprintf(status_file, "1\n");
12710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	fclose(status_file);
12810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
12910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
13010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
13110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/**
13210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * opd_do_samples - process a sample buffer
13310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @param opd_buf  buffer to process
13410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
13510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Process a buffer of samples.
13610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
13710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * If the sample could be processed correctly, it is written
13810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * to the relevant sample file.
13910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */
14010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_do_samples(char const * opd_buf, ssize_t count)
14110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
14210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	size_t num = count / kernel_pointer_size;
14310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
14410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_stats[OPD_DUMP_COUNT]++;
14510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
14610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	verbprintf(vmisc, "Read buffer of %d entries.\n", (unsigned int)num);
14710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
14810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_process_samples(opd_buf, num);
14910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
15010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	complete_dump();
15110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
15210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
15310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_do_jitdumps(void)
15410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
15510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	pid_t childpid;
15610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	int arg_num;
15710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	unsigned long long end_time = 0ULL;
15810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	struct timeval tv;
15910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	char end_time_str[32];
16010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	char opjitconv_path[PATH_MAX + 1];
16110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	char * exec_args[6];
16210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
16310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	if (jit_conversion_running)
16410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		return;
16510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	jit_conversion_running = 1;
16610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
16710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	childpid = fork();
16810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	switch (childpid) {
16910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		case -1:
17010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			perror("Error forking JIT dump process!");
17110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			break;
17210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		case 0:
17310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			gettimeofday(&tv, NULL);
17410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			end_time = tv.tv_sec;
17510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			sprintf(end_time_str, "%llu", end_time);
17610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			sprintf(opjitconv_path, "%s/%s", OP_BINDIR, "opjitconv");
17710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			arg_num = 0;
1785a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			exec_args[arg_num++] = "opjitconv";
17910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			if (vmisc)
18010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				exec_args[arg_num++] = "-d";
18110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			exec_args[arg_num++] = session_dir;
18210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			exec_args[arg_num++] = start_time_str;
18310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			exec_args[arg_num++] = end_time_str;
18410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			exec_args[arg_num] = (char *) NULL;
1855a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng			execvp(opjitconv_path, exec_args);
18610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			fprintf(stderr, "Failed to exec %s: %s\n",
18710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			        exec_args[0], strerror(errno));
18810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			/* We don't want any cleanup in the child */
18910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			_exit(EXIT_FAILURE);
19010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		default:
19110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			break;
19210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	}
19310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
19410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
19510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
19610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/**
19710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * opd_do_read - enter processing loop
19810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @param buf  buffer to read into
19910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * @param size  size of buffer
20010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
20110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Read some of a buffer from the device and process
20210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * the contents.
20310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */
20410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_do_read(char * buf, size_t size)
20510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
20610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_open_pipe();
20710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
20810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	while (1) {
20910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		ssize_t count = -1;
21010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
21110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		/* loop to handle EINTR */
21210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		while (count < 0) {
21310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			count = op_read_device(devfd, buf, size);
21410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
21510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			/* we can lose an alarm or a hup but
21610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			 * we don't care.
21710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			 */
21810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			if (signal_alarm) {
21910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				signal_alarm = 0;
22010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				opd_alarm();
22110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			}
22210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
22310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			if (signal_hup) {
22410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				signal_hup = 0;
22510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				opd_sighup();
22610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			}
22710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
22810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			if (signal_term)
22910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				opd_sigterm();
23010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
23110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			if (signal_child)
23210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				opd_sigchild();
23310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
23410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			if (signal_usr1) {
23510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				signal_usr1 = 0;
23610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				perfmon_start();
23710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			}
23810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
23910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			if (signal_usr2) {
24010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				signal_usr2 = 0;
24110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				perfmon_stop();
24210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			}
24310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
24410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			if (is_jitconv_requested()) {
24510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				verbprintf(vmisc, "Start opjitconv was triggered\n");
24610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project				opd_do_jitdumps();
24710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project			}
24810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		}
24910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
25010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		opd_do_samples(buf, count);
25110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	}
25210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
25310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_close_pipe();
25410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
25510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
25610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
25710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/** opd_alarm - sync files and report stats */
25810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_alarm(void)
25910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
26010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	sfile_sync_files();
26110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_print_stats();
26210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	alarm(60 * 10);
26310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
26410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
26510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
26610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/** re-open files for logrotate/opcontrol --reset */
26710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_sighup(void)
26810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
26910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	printf("Received SIGHUP.\n");
27010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	/* We just close them, and re-open them lazily as usual. */
27110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	sfile_close_files();
27210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	close(1);
27310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	close(2);
27410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_open_logfile();
27510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
27610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
27710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
27810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void clean_exit(void)
27910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
28010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	perfmon_exit();
28110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	unlink(op_lock_file);
28210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
28310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
28410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
28510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_sigterm(void)
28610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
28710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_do_jitdumps();
28810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_print_stats();
28910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	printf("oprofiled stopped %s", op_get_time());
2907a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown	opd_ext_deinitialize();
2917a33c86eb98056ef0570c99e713214f8dc56b6efJeff Brown
29210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	exit(EXIT_FAILURE);
29310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
29410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
29510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/* SIGCHLD received from JIT dump child process. */
29610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_sigchild(void)
29710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
29810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	int child_status;
29910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	wait(&child_status);
30010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	jit_conversion_running = 0;
30110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	if (WIFEXITED(child_status) && (!WEXITSTATUS(child_status))) {
30210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		verbprintf(vmisc, "JIT dump processing complete.\n");
30310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	} else {
30410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		printf("JIT dump processing exited abnormally: %d\n",
30510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		       WEXITSTATUS(child_status));
30610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	}
30710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
30810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
30910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
31010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_26_init(void)
31110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
31210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	size_t i;
31310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	size_t opd_buf_size;
31410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	unsigned long long start_time = 0ULL;
31510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	struct timeval tv;
31610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
31710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_create_vmlinux(vmlinux, kernel_range);
31810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_create_xen(xenimage, xen_range);
31910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
32010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_buf_size = opd_read_fs_int("/dev/oprofile/", "buffer_size", 1);
32110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	kernel_pointer_size = opd_read_fs_int("/dev/oprofile/", "pointer_size", 1);
32210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
32310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	s_buf_bytesize = opd_buf_size * kernel_pointer_size;
32410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
32510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	sbuf = xmalloc(s_buf_bytesize);
32610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
32710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_reread_module_info();
32810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
32910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	for (i = 0; i < OPD_MAX_STATS; i++)
33010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		opd_stats[i] = 0;
33110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
33210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	perfmon_init();
33310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
33410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	cookie_init();
33510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	sfile_init();
33610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	anon_init();
33710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
33810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	/* must be /after/ perfmon_init() at least */
33910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	if (atexit(clean_exit)) {
34010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		perfmon_exit();
34110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		perror("oprofiled: couldn't set exit cleanup: ");
34210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project		exit(EXIT_FAILURE);
34310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	}
34410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
34510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	/* trigger kernel module setup before returning control to opcontrol */
34610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_open_files();
34710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	gettimeofday(&tv, NULL);
34810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	start_time = 0ULL;
34910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	start_time = tv.tv_sec;
35010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	sprintf(start_time_str, "%llu", start_time);
35110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
35210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
35310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
35410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
35510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_26_start(void)
35610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
35710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	/* simple sleep-then-process loop */
35810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_do_read(sbuf, s_buf_bytesize);
35910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
36010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
36110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
36210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstatic void opd_26_exit(void)
36310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
36410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	opd_print_stats();
36510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	printf("oprofiled stopped %s", op_get_time());
36610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
36710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	free(sbuf);
36810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	free(vmlinux);
36910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	/* FIXME: free kernel images, sfiles etc. */
37010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
37110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
37210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstruct oprofiled_ops opd_26_ops = {
37310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	.init = opd_26_init,
37410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	.start = opd_26_start,
37510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project	.exit = opd_26_exit,
37610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project};
377