/* 
 * Real-Time and Multimedia Systems Laboratory
 * Copyright (c) 2000 Carnegie Mellon University
 * All Rights Reserved.
 * 
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 * 
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 * 
 * Carnegie Mellon requests users of this software to return to
 * 
 *  Real-Time and Multimedia Systems Laboratory
 *  Attn: Prof. Raj Rajkumar
 *  Electrical and Computer Engineering, and Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 *
 *  or via email to raj@ece.cmu.edu
 * 
 * any improvements or extensions that they make and grant Carnegie Mellon
 * the rights to redistribute these changes.
 */
/*
 * Portable QoS manager, implementing the comcepts described in
 * ``Adaptive Bandwidth Reservation for Multimedia Computing''
 * by L. Abeni and G. Buttazzo
 * IEEE Real Time Computing Systems and Applications 1999
 *
 *			program developed by Luca Abeni
 *					luca@sssup.it
 *					http://hartik.sssup.it/~luca
 */

/************************************************************************/
/*	This file implements the bandwidth assignment for PPS tasks	*/
/************************************************************************/
#include <stdlib.h>
#include <arch/basetype.h>

#include "ps.h"
#include "stats.h"

#define MAXPPS 64
static float W = 0;
static float B = 0;
static struct pscompr tpar[MAXPPS];

#define max(a,b)  (((a) > (b)) ? (a) : (b))

#ifdef __PS_STATS__
struct taskstat propstats[10000][10];
static int sk = 0;
#endif

void pscompr_init(float freebw)
{
    int i;

    for (i = 0; i < MAXPPS; i++) {
	tpar[i].weight = -1;
    }
    B = freebw;
}

struct pscompr *pscompr_create(float w)
{
    struct pscompr *parms;
    int i;
    int done;

    i = 0;
    done = 0;
    parms = NULL;
    while ((i < MAXPPS) && (!done)) {
	if (tpar[i].weight != -1) {
	    i++;
	} else {
	    parms = &(tpar[i]);
	    W += w;
	    parms->weight = w;
	    done = 1;
	}
    }
    return parms;
}
void pscompr_destroy(struct pscompr *p)
{
    W -= p->weight;
    p->weight = -1;
}

float pscompr_getweight(struct pscompr *p)
{
    return p->weight;
}

float pscompr_getband(struct pscompr *p)
{
#ifdef __PS_DEBUG__
    cprintf("GetBand: %f*%f/%f=%f\n", B, p->weight, W,
	    B * (p->weight / W));
#endif
    return B * (p->weight / W);
}
