Exemple #1
0
/* zero all the stats structures */
void
stats_zero(void)
{
	int dir;
	unsigned i;
	char *fname;

	fname = format("%s/stats", cache_dir);
	x_unlink(fname);
	free(fname);

	for (dir = 0; dir <= 0xF; dir++) {
		struct counters *counters = counters_init(STATS_END);
		fname = format("%s/%1x/stats", cache_dir, dir);
		if (lockfile_acquire(fname, lock_staleness_limit)) {
			stats_read(fname, counters);
			for (i = 0; stats_info[i].message; i++) {
				if (!(stats_info[i].flags & FLAG_NOZERO)) {
					counters->data[stats_info[i].stat] = 0;
				}
			}
			stats_write(fname, counters);
			lockfile_release(fname);
		}
		counters_free(counters);
		free(fname);
	}
}
Exemple #2
0
static void
init_counter_updates(void)
{
	if (!counter_updates) {
		counter_updates = counters_init(STATS_END);
	}
}
Exemple #3
0
// Sum and display the total stats for all cache dirs.
void
stats_summary(void)
{
	assert(conf);

	struct counters *counters = counters_init(STATS_END);
	time_t last_updated;
	stats_collect(counters, &last_updated);

	printf("cache directory                     %s\n", conf->cache_dir);
	printf("primary config                      %s\n",
	       primary_config_path ? primary_config_path : "");
	printf("secondary config      (readonly)    %s\n",
	       secondary_config_path ? secondary_config_path : "");
	if (last_updated > 0) {
		struct tm *tm = localtime(&last_updated);
		char timestamp[100];
		strftime(timestamp, sizeof(timestamp), "%c", tm);
		printf("stats updated                       %s\n", timestamp);
	}

	// ...and display them.
	for (int i = 0; stats_info[i].message; i++) {
		enum stats stat = stats_info[i].stat;

		if (stats_info[i].flags & FLAG_NEVER) {
			continue;
		}
		if (counters->data[stat] == 0 && !(stats_info[i].flags & FLAG_ALWAYS)) {
			continue;
		}

		char *value;
		if (stats_info[i].format_fn) {
			value = stats_info[i].format_fn(counters->data[stat]);
		} else {
			value = format("%8u", counters->data[stat]);
		}
		if (value) {
			printf("%-31s %s\n", stats_info[i].message, value);
			free(value);
		}

		if (stat == STATS_TOCACHE) {
			double percent = stats_hit_rate(counters);
			printf("cache hit rate                    %6.2f %%\n", percent);
		}
	}

	if (conf->max_files != 0) {
		printf("max files                       %8u\n", conf->max_files);
	}
	if (conf->max_size != 0) {
		char *value = format_size(conf->max_size);
		printf("max cache size                  %s\n", value);
		free(value);
	}

	counters_free(counters);
}
Exemple #4
0
// Zero all the stats structures.
void
stats_zero(void)
{
	assert(conf);

	char *fname = format("%s/stats", conf->cache_dir);
	x_unlink(fname);
	free(fname);

	time_t timestamp = time(NULL);

	for (int dir = 0; dir <= 0xF; dir++) {
		struct counters *counters = counters_init(STATS_END);
		struct stat st;
		fname = format("%s/%1x/stats", conf->cache_dir, dir);
		if (stat(fname, &st) != 0) {
			// No point in trying to reset the stats file if it doesn't exist.
			free(fname);
			continue;
		}
		if (lockfile_acquire(fname, lock_staleness_limit)) {
			stats_read(fname, counters);
			for (unsigned i = 0; stats_info[i].message; i++) {
				if (!(stats_info[i].flags & FLAG_NOZERO)) {
					counters->data[stats_info[i].stat] = 0;
				}
			}
			counters->data[STATS_ZEROTIMESTAMP] = timestamp;
			stats_write(fname, counters);
			lockfile_release(fname);
		}
		counters_free(counters);
		free(fname);
	}
}
Exemple #5
0
/* sum and display the total stats for all cache dirs */
void
stats_summary(struct conf *conf)
{
	int dir, i;
	struct counters *counters = counters_init(STATS_END);

	assert(conf);

	/* add up the stats in each directory */
	for (dir = -1; dir <= 0xF; dir++) {
		char *fname;

		if (dir == -1) {
			fname = format("%s/stats", conf->cache_dir);
		} else {
			fname = format("%s/%1x/stats", conf->cache_dir, dir);
		}

		stats_read(fname, counters);
		free(fname);
	}

	printf("cache directory                     %s\n", conf->cache_dir);
	printf("primary config                      %s\n",
	       primary_config_path ? primary_config_path : "");
	printf("secondary config      (readonly)    %s\n",
	       secondary_config_path ? secondary_config_path : "");

	/* and display them */
	for (i = 0; stats_info[i].message; i++) {
		enum stats stat = stats_info[i].stat;

		if (stats_info[i].flags & FLAG_NEVER) {
			continue;
		}
		if (counters->data[stat] == 0 && !(stats_info[i].flags & FLAG_ALWAYS)) {
			continue;
		}

		printf("%s ", stats_info[i].message);
		if (stats_info[i].fn) {
			stats_info[i].fn(counters->data[stat]);
			printf("\n");
		} else {
			printf("%8u\n", counters->data[stat]);
		}
	}

	if (conf->max_files != 0) {
		printf("max files                       %8u\n", conf->max_files);
	}
	if (conf->max_size != 0) {
		printf("max cache size                  ");
		display_size(conf->max_size);
		printf("\n");
	}

	counters_free(counters);
}
Exemple #6
0
/* Get the per directory limits */
void
stats_get_limits(const char *dir, unsigned *maxfiles, unsigned *maxsize)
{
	struct counters *counters = counters_init(STATS_END);
	char *sname = format("%s/stats", dir);
	stats_read(sname, counters);
	*maxfiles = counters->data[STATS_MAXFILES];
	*maxsize = counters->data[STATS_MAXSIZE];
	free(sname);
	counters_free(counters);
}
Exemple #7
0
/* Get the per directory limits */
void
stats_get_obsolete_limits(const char *dir, unsigned *maxfiles, uint64_t *maxsize)
{
	struct counters *counters = counters_init(STATS_END);
	char *sname = format("%s/stats", dir);
	stats_read(sname, counters);
	*maxfiles = counters->data[STATS_OBSOLETE_MAXFILES];
	*maxsize = (uint64_t)counters->data[STATS_OBSOLETE_MAXSIZE] * 1024;
	free(sname);
	counters_free(counters);
}
Exemple #8
0
// Count directory cleanup run.
void
stats_add_cleanup(const char *dir, unsigned count)
{
	struct counters *counters = counters_init(STATS_END);
	char *statsfile = format("%s/stats", dir);
	if (lockfile_acquire(statsfile, lock_staleness_limit)) {
		stats_read(statsfile, counters);
		counters->data[STATS_NUMCLEANUPS] += count;
		stats_write(statsfile, counters);
		lockfile_release(statsfile);
	}
	free(statsfile);
	counters_free(counters);
}
Exemple #9
0
// Set the per-directory sizes.
void
stats_set_sizes(const char *dir, unsigned num_files, uint64_t total_size)
{
	struct counters *counters = counters_init(STATS_END);
	char *statsfile = format("%s/stats", dir);
	if (lockfile_acquire(statsfile, lock_staleness_limit)) {
		stats_read(statsfile, counters);
		counters->data[STATS_NUMFILES] = num_files;
		counters->data[STATS_TOTALSIZE] = total_size / 1024;
		stats_write(statsfile, counters);
		lockfile_release(statsfile);
	}
	free(statsfile);
	counters_free(counters);
}
Exemple #10
0
/* sum and display the total stats for all cache dirs */
void
stats_summary(void)
{
	int dir, i;
	struct counters *counters = counters_init(STATS_END);

	/* add up the stats in each directory */
	for (dir = -1; dir <= 0xF; dir++) {
		char *fname;

		if (dir == -1) {
			fname = format("%s/stats", cache_dir);
		} else {
			fname = format("%s/%1x/stats", cache_dir, dir);
		}

		stats_read(fname, counters);
		free(fname);

		/* oh what a nasty hack ... */
		if (dir == -1) {
			counters->data[STATS_MAXSIZE] = 0;
		}
	}

	printf("cache directory                     %s\n", cache_dir);

	/* and display them */
	for (i = 0; stats_info[i].message; i++) {
		enum stats stat = stats_info[i].stat;

		if (counters->data[stat] == 0 && !(stats_info[i].flags & FLAG_ALWAYS)) {
			continue;
		}

		printf("%s ", stats_info[i].message);
		if (stats_info[i].fn) {
			stats_info[i].fn(counters->data[stat]);
			printf("\n");
		} else {
			printf("%8u\n", counters->data[stat]);
		}
	}

	counters_free(counters);
}
Exemple #11
0
/* set the per directory limits */
int
stats_set_limits(long maxfiles, long maxsize)
{
	int dir;

	if (maxfiles != -1) {
		maxfiles /= 16;
	}
	if (maxsize != -1) {
		maxsize /= 16;
	}

	if (create_dir(cache_dir) != 0) {
		return 1;
	}

	/* set the limits in each directory */
	for (dir = 0; dir <= 0xF; dir++) {
		char *fname, *cdir;

		cdir = format("%s/%1x", cache_dir, dir);
		if (create_dir(cdir) != 0) {
			free(cdir);
			return 1;
		}
		fname = format("%s/stats", cdir);
		free(cdir);

		if (lockfile_acquire(fname, lock_staleness_limit)) {
			struct counters *counters = counters_init(STATS_END);
			stats_read(fname, counters);
			if (maxfiles != -1) {
				counters->data[STATS_MAXFILES] = maxfiles;
			}
			if (maxsize != -1) {
				counters->data[STATS_MAXSIZE] = maxsize;
			}
			stats_write(fname, counters);
			lockfile_release(fname);
			counters_free(counters);
		}
		free(fname);
	}

	return 0;
}
Exemple #12
0
// Record that a number of bytes and files have been added to the cache. Size
// is in bytes.
void
stats_update_size(const char *sfile, int64_t size, int files)
{
	struct counters *updates;
	if (sfile == stats_file) {
		init_counter_updates();
		updates = counter_updates;
	} else {
		updates = counters_init(STATS_END);
	}
	updates->data[STATS_NUMFILES] += files;
	updates->data[STATS_TOTALSIZE] += size / 1024;
	if (sfile != stats_file) {
		stats_flush_to_file(sfile, updates);
		counters_free(updates);
	}
}
Exemple #13
0
// Print machine-parsable (tab-separated) statistics counters.
void
stats_print(void)
{
	assert(conf);

	struct counters *counters = counters_init(STATS_END);
	time_t last_updated;
	stats_collect(counters, &last_updated);

	printf("stats_updated_timestamp\t%llu\n", (unsigned long long)last_updated);

	for (int i = 0; stats_info[i].message; i++) {
		if (!(stats_info[i].flags & FLAG_NEVER)) {
			printf("%s\t%u\n", stats_info[i].id, counters->data[stats_info[i].stat]);
		}
	}

	counters_free(counters);
}
Exemple #14
0
/*
 * Write counter updates in counter_updates to disk.
 */
void
stats_flush(void)
{
	struct counters *counters;
	bool need_cleanup = false;
	bool should_flush = false;
	int i;

	assert(conf);

	if (!conf->stats) {
		return;
	}

	if (!counter_updates) {
		return;
	}

	for (i = 0; i < STATS_END; ++i) {
		if (counter_updates->data[i] > 0) {
			should_flush = true;
			break;
		}
	}
	if (!should_flush) {
		return;
	}

	if (!stats_file) {
		char *stats_dir;

		/*
		 * A NULL stats_file means that we didn't get past calculate_object_hash(),
		 * so we just choose one of stats files in the 16 subdirectories.
		 */
		stats_dir = format("%s/%x", conf->cache_dir, hash_from_int(getpid()) % 16);
		stats_file = format("%s/stats", stats_dir);
		free(stats_dir);
	}

	if (!lockfile_acquire(stats_file, lock_staleness_limit)) {
		return;
	}
	counters = counters_init(STATS_END);
	stats_read(stats_file, counters);
	for (i = 0; i < STATS_END; ++i) {
		counters->data[i] += counter_updates->data[i];
	}
	stats_write(stats_file, counters);
	lockfile_release(stats_file);

	if (!str_eq(conf->log_file, "")) {
		for (i = 0; i < STATS_END; ++i) {
			if (counter_updates->data[stats_info[i].stat] != 0
			    && !(stats_info[i].flags & FLAG_NOZERO)) {
				cc_log("Result: %s", stats_info[i].message);
			}
		}
	}

	if (conf->max_files != 0
	    && counters->data[STATS_NUMFILES] > conf->max_files / 16) {
		need_cleanup = true;
	}
	if (conf->max_size != 0
	    && counters->data[STATS_TOTALSIZE] > conf->max_size / 1024 / 16) {
		need_cleanup = true;
	}

	if (need_cleanup) {
		char *p = dirname(stats_file);
		cleanup_dir(conf, p);
		free(p);
	}

	counters_free(counters);
}
Exemple #15
0
// Sum and display the total stats for all cache dirs.
void
stats_summary(struct conf *conf)
{
	struct counters *counters = counters_init(STATS_END);

	assert(conf);

	// Add up the stats in each directory.
	for (int dir = -1; dir <= 0xF; dir++) {
		char *fname;

		if (dir == -1) {
			fname = format("%s/stats", conf->cache_dir);
		} else {
			fname = format("%s/%1x/stats", conf->cache_dir, dir);
		}

		stats_read(fname, counters);
		free(fname);
	}

	printf("cache directory                     %s\n", conf->cache_dir);
	printf("primary config                      %s\n",
	       primary_config_path ? primary_config_path : "");
	printf("secondary config      (readonly)    %s\n",
	       secondary_config_path ? secondary_config_path : "");

	// ...and display them.
	for (int i = 0; stats_info[i].message; i++) {
		enum stats stat = stats_info[i].stat;

		if (stats_info[i].flags & FLAG_NEVER) {
			continue;
		}
		if (counters->data[stat] == 0 && !(stats_info[i].flags & FLAG_ALWAYS)) {
			continue;
		}

		printf("%s ", stats_info[i].message);
		if (stats_info[i].fn) {
			stats_info[i].fn(counters->data[stat]);
			printf("\n");
		} else {
			printf("%8u\n", counters->data[stat]);
		}

		if (stat == STATS_TOCACHE) {
			unsigned direct = counters->data[STATS_CACHEHIT_DIR];
			unsigned preprocessed = counters->data[STATS_CACHEHIT_CPP];
			unsigned hit = direct + preprocessed;
			unsigned miss = counters->data[STATS_TOCACHE];
			unsigned total = hit + miss;
			double percent = total > 0 ? (100.0f * hit) / total : 0.0f;
			printf("cache hit rate                    %6.2f %%\n", percent);
		}
	}

	if (conf->max_files != 0) {
		printf("max files                       %8u\n", conf->max_files);
	}
	if (conf->max_size != 0) {
		printf("max cache size                  ");
		display_size(conf->max_size);
		printf("\n");
	}

	counters_free(counters);
}
Exemple #16
0
/*
 * Write counter updates in counter_updates to disk.
 */
void
stats_flush(void)
{
	struct counters *counters;
	bool need_cleanup = false;
	bool should_flush = false;
	int i;
	extern char *cache_logfile;

	if (getenv("CCACHE_NOSTATS")) return;

	init_counter_updates();

	for (i = 0; i < STATS_END; ++i) {
		if (counter_updates->data[i] > 0) {
			should_flush = true;
			break;
		}
	}
	if (!should_flush) return;

	if (!stats_file) {
		char *stats_dir;

		/*
		 * A NULL stats_file means that we didn't get past calculate_object_hash(),
		 * so we just choose one of stats files in the 16 subdirectories.
		 */
		if (!cache_dir) return;
		stats_dir = format("%s/%x", cache_dir, hash_from_int(getpid()) % 16);
		stats_file = format("%s/stats", stats_dir);
		create_dir(stats_dir);
		free(stats_dir);
	}

	if (!lockfile_acquire(stats_file, lock_staleness_limit)) {
		return;
	}
	counters = counters_init(STATS_END);
	stats_read(stats_file, counters);
	for (i = 0; i < STATS_END; ++i) {
		counters->data[i] += counter_updates->data[i];
	}
	stats_write(stats_file, counters);
	lockfile_release(stats_file);

	if (cache_logfile) {
		for (i = 0; i < STATS_END; ++i) {
			if (counter_updates->data[stats_info[i].stat] != 0
			    && !(stats_info[i].flags & FLAG_NOZERO)) {
				cc_log("Result: %s", stats_info[i].message);
			}
		}
	}

	if (counters->data[STATS_MAXFILES] != 0 &&
	    counters->data[STATS_NUMFILES] > counters->data[STATS_MAXFILES]) {
		need_cleanup = true;
	}
	if (counters->data[STATS_MAXSIZE] != 0 &&
	    counters->data[STATS_TOTALSIZE] > counters->data[STATS_MAXSIZE]) {
		need_cleanup = true;
	}

	if (need_cleanup) {
		char *p = dirname(stats_file);
		cleanup_dir(p,
		            counters->data[STATS_MAXFILES],
		            counters->data[STATS_MAXSIZE]);
		free(p);
	}
}
Exemple #17
0
// Write counter updates in counter_updates to disk.
void
stats_flush(void)
{
	assert(conf);

	if (!conf->stats) {
		return;
	}

	if (!counter_updates) {
		return;
	}

	bool should_flush = false;
	for (int i = 0; i < STATS_END; ++i) {
		if (counter_updates->data[i] > 0) {
			should_flush = true;
			break;
		}
	}
	if (!should_flush) {
		return;
	}

	if (!stats_file) {
		char *stats_dir;

		// A NULL stats_file means that we didn't get past calculate_object_hash(),
		// so we just choose one of stats files in the 16 subdirectories.
		stats_dir = format("%s/%x", conf->cache_dir, hash_from_int(getpid()) % 16);
		stats_file = format("%s/stats", stats_dir);
		free(stats_dir);
	}

	if (!lockfile_acquire(stats_file, lock_staleness_limit)) {
		return;
	}

	struct counters *counters = counters_init(STATS_END);
	stats_read(stats_file, counters);
	for (int i = 0; i < STATS_END; ++i) {
		counters->data[i] += counter_updates->data[i];
	}
	stats_write(stats_file, counters);
	lockfile_release(stats_file);

	if (!str_eq(conf->log_file, "") || conf->debug) {
		for (int i = 0; i < STATS_END; ++i) {
			if (counter_updates->data[stats_info[i].stat] != 0
			    && !(stats_info[i].flags & FLAG_NOZERO)) {
				cc_log("Result: %s", stats_info[i].message);
			}
		}
	}

	char *subdir = dirname(stats_file);
	bool need_cleanup = false;

	if (conf->max_files != 0
	    && counters->data[STATS_NUMFILES] > conf->max_files / 16) {
		cc_log("Need to clean up %s since it holds %u files (limit: %u files)",
		       subdir,
		       counters->data[STATS_NUMFILES],
		       conf->max_files / 16);
		need_cleanup = true;
	}
	if (conf->max_size != 0
	    && counters->data[STATS_TOTALSIZE] > conf->max_size / 1024 / 16) {
		cc_log("Need to clean up %s since it holds %u KiB (limit: %lu KiB)",
		       subdir,
		       counters->data[STATS_TOTALSIZE],
		       (unsigned long)conf->max_size / 1024 / 16);
		need_cleanup = true;
	}

	if (need_cleanup) {
		clean_up_dir(conf, subdir, conf->limit_multiple);
	}

	free(subdir);
	counters_free(counters);
}
Exemple #18
0
// 从汇编阶段,进入C语言的阶段,传承了Unix的典型思想
// 汇编只负责引导和必要的硬件打交道的阶段
void start_ling(start_info_t *si)
{
	//-------- init phase 1 --------
	//
	//start_info包含的是xen的初始化信息
	//是xen在启动GuestOS的时候,放在特定的地方
	memcpy(&start_info, si, sizeof(*si));
    
	phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;

	HYPERVISOR_update_va_mapping((unsigned long)&shared_info,
		__pte(start_info.shared_info | 7), UVMF_INVLPG);
	HYPERVISOR_shared_info = &shared_info;
//进行时钟初始化
	time_init();	// sets start_of_day_wall_clock

	// use the time value to seed PRNG
	mt_seed(start_of_day_wall_clock);
	
#if defined(__x86_64__)
	HYPERVISOR_set_callbacks(0, 0, 0);
#else /* __x86_64__ */
	HYPERVISOR_set_callbacks(0, 0, 0, 0);
#endif

	mm_init(start_info.nr_pages, start_info.pt_base, start_info.nr_pt_frames);
	nalloc_init();

	events_init();
	grants_init();

	console_init(mfn_to_virt(start_info.console.domU.mfn),
			start_info.console.domU.evtchn);
	xenstore_init(mfn_to_virt(start_info.store_mfn),
		start_info.store_evtchn);

	xenstore_read("name", my_domain_name, sizeof(my_domain_name));
	//print_xenstore_values();

	if (disk_vbd_is_present())
		disk_init();

	lwip_init();
	netfe_init();

	//-------- init phase 2 --------
	//
	if (nalloc_no_memory())
		fatal_error("init phase 2: no memory"); 	

	sys_stats_init();

	atoms_init();
	embed_init();
	code_base_init();
	scheduler_init();
	ets_init();
	pcre_init();
	counters_init();

	//print_start_info();
	//print_xenmem_info();
	//run_alloc_tests();
	//run_mm_tests();
	//print_xenstore_values();
	//run_bignum_tests();
	
	//printk("\r\nLing %s is here\r\n", quote_and_expand(LING_VER));

	proc_main(0); // preliminary run

	spawn_init_start(start_info.cmd_line);

	//while (1)
	//	HYPERVISOR_sched_op(SCHEDOP_block, 0);

	/* UNREACHABLE */
}