Пример #1
0
void categories_initialize(struct hash_table *categories, struct rmsummary *top, const char *summaries_file) {
	struct list *summaries = rmsummary_parse_file_multiple(summaries_file);

	if(!summaries) {
		fatal("Could not read '%s' file: %s\n", strerror(errno));
	}

	char *name;
	struct category *c;
	hash_table_firstkey(categories);
	while(hash_table_nextkey(categories, &name, (void **) &c)) {
		category_clear_histograms(c);
		if(c->first_allocation) {
			rmsummary_delete(c->first_allocation);
			c->first_allocation = rmsummary_create(-1);
		}
	}

	struct rmsummary *s;
	list_first_item(summaries);
	while((s = list_pop_head(summaries))) {
		if(s->category) {
			c = category_lookup_or_create(categories, s->category);
			category_accumulate_summary(c, s, NULL);
		}
		rmsummary_delete(s);
	}

	hash_table_firstkey(categories);
	while(hash_table_nextkey(categories, &name, (void **) &c)) {
		category_update_first_allocation(c, NULL);
		category_clear_histograms(c);
	}
}
Пример #2
0
/** Deletes task struct and frees contained data. */
void batch_task_delete(struct batch_task *t)
{
	if (!t)
		return;

	free(t->command);

	struct batch_file *f;
	list_first_item(t->input_files);
	while((f = list_next_item(t->input_files))){
		batch_file_delete(f);
	}
	list_delete(t->input_files);

	list_first_item(t->output_files);
	while((f = list_next_item(t->output_files))){
		batch_file_delete(f);
	}
	list_delete(t->output_files);

	rmsummary_delete(t->resources);

	jx_delete(t->envlist);

	batch_job_info_delete(t->info);

	free(t);
}
Пример #3
0
const struct rmsummary *category_dynamic_task_min_resources(struct category *c, struct rmsummary *user, category_allocation_t request) {

	static struct rmsummary *internal = NULL;

	const struct rmsummary *max = category_dynamic_task_max_resources(c, user, request);

	if(internal) {
		rmsummary_delete(internal);
	}

	internal = rmsummary_create(-1);

	/* load seen values */
	struct rmsummary *seen = c->max_resources_seen;

	if(c->allocation_mode != CATEGORY_ALLOCATION_MODE_FIXED) {
			internal->cores  = seen->cores;
			internal->memory = seen->memory;
			internal->disk   = seen->disk;
	}

	rmsummary_merge_override(internal, max);

	return internal;
}
Пример #4
0
const struct rmsummary *category_dynamic_task_max_resources(struct category *c, struct rmsummary *user, category_allocation_t request) {
	/* we keep an internal label so that the caller does not have to worry
	 * about memory leaks. */
	static struct rmsummary *internal = NULL;

	if(internal) {
		rmsummary_delete(internal);
	}

	internal = rmsummary_create(-1);

	struct rmsummary *max   = c->max_allocation;
	struct rmsummary *first = c->first_allocation;
	struct rmsummary *seen  = c->max_resources_seen;

	if(c->steady_state && c->allocation_mode != CATEGORY_ALLOCATION_MODE_FIXED) {
		internal->cores  = seen->cores;
		internal->memory = seen->memory;
		internal->disk   = seen->disk;
	}

	/* load max values */
	rmsummary_merge_override(internal, max);

	if(c->allocation_mode != CATEGORY_ALLOCATION_MODE_FIXED
			&& request == CATEGORY_ALLOCATION_FIRST) {
		rmsummary_merge_override(internal, first);
	}

	/* chip in user values */
	rmsummary_merge_override(internal, user);

	return internal;
}
Пример #5
0
int category_accumulate_summary(struct category *c, const struct rmsummary *rs, const struct rmsummary *max_worker) {
	int update = 0;

	const struct rmsummary *max  = c->max_allocation;
	const struct rmsummary *seen = c->max_resources_seen;

	int new_maximum ;
	if(rs
			&& (max->cores  > 0 || rs->cores  <= seen->cores)
			&& (max->memory > 0 || rs->memory <= seen->memory)
			&& (max->disk   > 0 || rs->disk   <= seen->disk)) {
		new_maximum = 0;
	} else {
		new_maximum = 1;
	}

	/* a new maximum has been seen, first-allocation is obsolete. */
	if(new_maximum) {
		rmsummary_delete(c->first_allocation);
		c->first_allocation =  NULL;
		c->completions_since_last_reset = 0;
		update = 1;
	}

	c->steady_state = c->completions_since_last_reset >= first_allocation_every_n_tasks;

	rmsummary_merge_max(c->max_resources_seen, rs);
	if(rs && (!rs->exit_type || !strcmp(rs->exit_type, "normal"))) {
		category_inc_histogram_count(c, cores,          rs);
		category_inc_histogram_count(c, cpu_time,       rs);
		category_inc_histogram_count(c, wall_time,      rs);
		category_inc_histogram_count(c, virtual_memory, rs);
		category_inc_histogram_count(c, memory,         rs);
		category_inc_histogram_count(c, swap_memory,    rs);
		category_inc_histogram_count(c, bytes_read,     rs);
		category_inc_histogram_count(c, bytes_written,  rs);
		category_inc_histogram_count(c, bytes_sent,     rs);
		category_inc_histogram_count(c, bytes_received, rs);
		category_inc_histogram_count(c, bandwidth,      rs);
		category_inc_histogram_count(c, total_files,    rs);
		category_inc_histogram_count(c, disk,           rs);
		category_inc_histogram_count(c, max_concurrent_processes, rs);
		category_inc_histogram_count(c, total_processes,rs);

		c->completions_since_last_reset++;

		if(new_maximum || c->completions_since_last_reset % first_allocation_every_n_tasks == 0) {
			update |= category_update_first_allocation(c, max_worker);
		}

		/* a task completed using a new maximum, so we consider that the new steady_state. */
		if(new_maximum) {
			c->steady_state = 1;
		}

        c->total_tasks++;
	}

	return update;
}
Пример #6
0
void rmDsummary_print(FILE *output, struct rmDsummary *so) {
	struct rmsummary *s = rmsummary_create(-1);

	s->command    = xxstrdup(so->command);

	if(so->category)
	{
		s->category   = xxstrdup(so->category);
	}
	else if(so->command)
	{
		s->category   = xxstrdup(so->command);
	}
	else
	{
		s->category   = xxstrdup(DEFAULT_CATEGORY);
		s->command    = xxstrdup(DEFAULT_CATEGORY);
	}

	if(so->task_id) {
		s->task_id = xxstrdup(so->task_id);
	}

	s->start     = so->start;
	s->end       = so->end;
	s->wall_time = so->wall_time;

	to_internal(so, s, start,     "us");
	to_internal(so, s, end,       "us");
	to_internal(so, s, wall_time, "s");
	to_internal(so, s, cpu_time,  "s");

	to_internal(so, s, cores,                   "cores");
	to_internal(so, s, total_processes,         "procs");
	to_internal(so, s, max_concurrent_processes,"procs");

	to_internal(so, s, memory,         "MB");
	to_internal(so, s, virtual_memory, "MB");
	to_internal(so, s, swap_memory,    "MB");

	to_internal(so, s, bytes_read,    "MB");
	to_internal(so, s, bytes_written, "MB");

	to_internal(so, s, bytes_received, "MB");
	to_internal(so, s, bytes_sent,     "MB");
	to_internal(so, s, bandwidth,      "Mbps");

	to_internal(so, s, total_files, "files");
	to_internal(so, s, disk, "MB");

	rmsummary_print(output, s, /* pprint */ 1, /* extra fields */ 0);
	rmsummary_delete(s);

	return;
}
Пример #7
0
void category_specify_first_allocation_guess(struct category *c, const struct rmsummary *s) {

	/* assume user knows what they are doing. */
	c->steady_state = 1;
	rmsummary_merge_max(c->max_resources_seen, s);

	rmsummary_delete(c->first_allocation);

	c->first_allocation = rmsummary_create(-1);

	rmsummary_merge_max(c->first_allocation, s);
}
Пример #8
0
void category_delete(struct hash_table *categories, const char *name) {
	struct category *c = hash_table_lookup(categories, name);

	if(!c)
		return;

	hash_table_remove(categories, name);

	if(c->name)
		free(c->name);

	if(c->wq_stats)
		free(c->wq_stats);

	category_delete_histograms(c);

	rmsummary_delete(c->max_allocation);
	rmsummary_delete(c->first_allocation);
	rmsummary_delete(c->autolabel_resource);
	rmsummary_delete(c->max_resources_seen);

	free(c);
}
Пример #9
0
static void batch_queue_wq_option_update (struct batch_queue *q, const char *what, const char *value)
{
	if(strcmp(what, "password") == 0) {
		if(value)
			work_queue_specify_password(q->data, value);
	} else if(strcmp(what, "master-mode") == 0) {
		if(strcmp(value, "catalog") == 0)
			work_queue_specify_master_mode(q->data, WORK_QUEUE_MASTER_MODE_CATALOG);
		else if(strcmp(value, "standalone") == 0)
			work_queue_specify_master_mode(q->data, WORK_QUEUE_MASTER_MODE_STANDALONE);
	} else if(strcmp(what, "name") == 0) {
		if(value)
			work_queue_specify_name(q->data, value);
	} else if(strcmp(what, "priority") == 0) {
		if(value)
			work_queue_specify_priority(q->data, atoi(value));
		else
			work_queue_specify_priority(q->data, 0);
	} else if(strcmp(what, "fast-abort") == 0) {
		if(value)
			work_queue_activate_fast_abort(q->data, atof(value));
	} else if(strcmp(what, "estimate-capacity") == 0) {
		work_queue_specify_estimate_capacity_on(q->data, string_istrue(value));
	} else if(strcmp(what, "keepalive-interval") == 0) {
		if(value)
			work_queue_specify_keepalive_interval(q->data, atoi(value));
		else
			work_queue_specify_keepalive_interval(q->data, WORK_QUEUE_DEFAULT_KEEPALIVE_INTERVAL);
	} else if(strcmp(what, "keepalive-timeout") == 0) {
		if(value)
			work_queue_specify_keepalive_timeout(q->data, atoi(value));
		else
			work_queue_specify_keepalive_timeout(q->data, WORK_QUEUE_DEFAULT_KEEPALIVE_TIMEOUT);
	} else if(strcmp(what, "master-preferred-connection") == 0) {
		if(value)
			work_queue_master_preferred_connection(q->data, value);
		else
			work_queue_master_preferred_connection(q->data, "by_ip");
	} else if(strcmp(what, "category-limits") == 0) {
		struct rmsummary *s = rmsummary_parse_string(value);
		if(s) {
			work_queue_specify_category_max_resources(q->data, s->category, s);
			rmsummary_delete(s);
		} else {
			debug(D_NOTICE, "Could no parse '%s' as a summary of resorces encoded in JSON\n", value);
		}
	}
}
Пример #10
0
struct rmDsummary *parse_summary(FILE *stream, char *filename, struct hash_table *categories)
{
	static FILE *last_stream = NULL;
	static int   summ_id     = 1;

	if(last_stream != stream)
	{
		last_stream = stream;
		summ_id     = 1;
	}
	else
	{
		summ_id++;
	}

	struct rmsummary  *so = rmsummary_parse_next(stream);
	if(!so)
		return NULL;

	if(categories) {
		struct category *c = category_lookup_or_create(categories, ALL_SUMMARIES_CATEGORY);
		category_accumulate_summary(c, so, NULL);
		if(so->category) {
			c = category_lookup_or_create(categories, so->category);
			category_accumulate_summary(c, so, NULL);
		}
	}

	struct rmDsummary *s  = rmsummary_to_rmDsummary(so);

	s->file = xxstrdup(filename);
	if(!s->task_id) {
		s->task_id = get_rule_number(filename);
	}

	rmsummary_delete(so);

	return s;
}
Пример #11
0
/** Sets the resources of batch_task.
 Uses rmsummary_copy to create a deep copy of resources.
*/
void batch_task_set_resources(struct batch_task *t, const struct rmsummary *resources)
{
	rmsummary_delete(t->resources);
	t->resources = rmsummary_copy(resources);
}
Пример #12
0
void category_specify_max_allocation(struct category *c, const struct rmsummary *s) {
	rmsummary_delete(c->max_allocation);
	c->max_allocation = rmsummary_create(-1);

	rmsummary_merge_max(c->max_allocation, s);
}
Пример #13
0
int category_update_first_allocation(struct category *c, const struct rmsummary *max_worker) {
	/* buffer used only for debug output. */
	static buffer_t *b = NULL;
	if(!b) {
		b = malloc(sizeof(buffer_t));
		buffer_init(b);
	}

	if(c->allocation_mode == CATEGORY_ALLOCATION_MODE_FIXED)
		return 0;

	if(c->total_tasks < 1)
		return 0;

	struct rmsummary *top = rmsummary_create(-1);
	rmsummary_merge_override(top, max_worker);
	rmsummary_merge_override(top, c->max_resources_seen);
	rmsummary_merge_override(top, c->max_allocation);

	if(!c->first_allocation) {
		c->first_allocation = rmsummary_create(-1);
	}

	update_first_allocation_field(c, top, 1, cpu_time);
	update_first_allocation_field(c, top, 1, wall_time);
	update_first_allocation_field(c, top, c->time_peak_independece, cores);
	update_first_allocation_field(c, top, c->time_peak_independece, virtual_memory);
	update_first_allocation_field(c, top, c->time_peak_independece, memory);
	update_first_allocation_field(c, top, c->time_peak_independece, swap_memory);
	update_first_allocation_field(c, top, c->time_peak_independece, bytes_read);
	update_first_allocation_field(c, top, c->time_peak_independece, bytes_written);
	update_first_allocation_field(c, top, c->time_peak_independece, bytes_received);
	update_first_allocation_field(c, top, c->time_peak_independece, bytes_sent);
	update_first_allocation_field(c, top, c->time_peak_independece, bandwidth);
	update_first_allocation_field(c, top, c->time_peak_independece, total_files);
	update_first_allocation_field(c, top, c->time_peak_independece, disk);
	update_first_allocation_field(c, top, c->time_peak_independece, max_concurrent_processes);
	update_first_allocation_field(c, top, c->time_peak_independece, total_processes);

	/* From here on we only print debugging info. */
	struct jx *jsum = rmsummary_to_json(c->first_allocation, 1);
	if(jsum) {
		char *str = jx_print_string(jsum);
		debug(D_DEBUG, "Updating first allocation '%s':", c->name);
		debug(D_DEBUG, "%s", str);
		jx_delete(jsum);
		free(str);
	}

	jsum = rmsummary_to_json(top, 1);
	if(jsum) {
		char *str = jx_print_string(jsum);
		debug(D_DEBUG, "From max resources '%s':", c->name);
		debug(D_DEBUG, "%s", str);
		jx_delete(jsum);
		free(str);
	}

	rmsummary_delete(top);

	return 1;
}