/*
 * Copyright (c) 2008 Jamey Sharp
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>

struct source {
	pthread_mutex_t lock;
	FILE *in;
	double value;
	double max;
	int done;
};

static void *watch(void *priv)
{
	struct source *source = priv;
	int bytes, time;
	while(fscanf(source->in, " %d %d", &bytes, &time) == 2)
	{
		double value = bytes / (1024 * 1024 * 1e-9 * time);
		pthread_mutex_lock(&source->lock);
		if(source->value < value)
			source->value = value;
		if(source->max < value)
			source->max = value;
		pthread_mutex_unlock(&source->lock);
	}
	pthread_mutex_lock(&source->lock);
	source->done = 1;
	pthread_mutex_unlock(&source->lock);
	return 0;
}

static void spawn(struct source *source, FILE *in)
{
	pthread_t threadid;
	source->lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
	source->in = in;
	pthread_create(&threadid, 0, watch, source);
}

int main(int argc, char **argv)
{
	double delay = atof(argv[1]);
	struct timespec sleep;
	sleep.tv_sec = delay;
	sleep.tv_nsec = (long) (delay * 1000000000) % 1000000000;

	struct source sources[8] = { };
	int count;
	for(count = 0; count + 2 < argc && count < (sizeof(sources) / sizeof(*sources)); ++count)
		spawn(&sources[count], fopen(argv[count + 2], "r"));
	if(count == 0)
	{
		spawn(&sources[0], stdin);
		++count;
	}

	setlinebuf(stdout);
	while(1)
	{
		nanosleep(&sleep, 0);
		int i, did;
		for(i = 0, did = 0; i < count; ++i)
		{
			pthread_mutex_lock(&sources[i].lock);
			double value = 0, max = 0;
			if(!sources[i].done)
			{
				value = sources[i].value;
				max = sources[i].max;
				sources[i].value = 0;
				++did;
			}
			pthread_mutex_unlock(&sources[i].lock);
			printf("%f %f ", value, max);
		}
		printf("\n");
		if(!did)
			exit(EXIT_SUCCESS);
	}
}
