/*-=-=-=-=-=-=-=-=-=-=-=- RCCL/RCI Notice of Copyright -=-=-=-=-=-=-=-=-=-=-*
 *									    *
 *	Copyright (C) 1987, 1991 by John E. Lloyd.			    *
 *									    *
 *	Information on copyright permissions, as well as a complete	    *
 *	disclaimer of warranty, is given in the file COPYRIGHT.		    *
 *									    *
 *-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/*---------------------------------------------------------------------------
 *		
 * MODULE NAME:	arbMonitor
 *
 * DESCRIPTION:	This file is the counterpart of 'auxMonitor.c', and 
 *		contains code specific to the creation and execution of a
 *		monitor task on the arbiter CPU.
 *
 * AUTHOR/DATE:	John Lloyd, Fall 1987
 *
 * MODIFICATION HISTORY:
 *
 *--------------------------------------------------------------------------*/

#include <signal.h>

#include "../h/cdefs.h"
#include "../h/rciConfig.h"
#include "../h/errorCodes.h"
#include "../rci/monitorDefs.h"

extern int rciCpu;
extern TASK_ENTRY *residentTaskQueue;

/* ----- Error Messages. Defined externally to save space ----- */

extern monitorRun();

static char *nullMsg		= "%s --\n";

arbMonitorSetup (simflag)
int simflag;
{
	/* sets up the arbiter monitor. It is only called once per RCI
	   program, the first time that rciCreate() is called. It looks
	   for an available generic RCI device, which provides the kernel
	   interface necessary to execute RCI tasks on the arbiter.
	*/

	char *fxnName = "arbMonitorSetup()";
	int clkPeriod;

	if (rciHostOpen(SIGXCPU, &clkPeriod, simflag) < 0)
	 { errorMsg (getErrorCode(0), nullMsg, fxnName);
	   return (-1);
	 }
	rciCpu = ARBITER_CPU;
	monitorInit();
	return (1);

}

arbMonitorCommand ()
{

	/* Executes a command on the arbiter monitor */

	char *fxnName = "arbMonitorCommand()";

	extern char moncomCmd[];
	extern monitorCommand();

	if (rciTaskExec (monitorCommand, (int)moncomCmd[ARBITER_CPU]) < 0)
	 { errorMsg (getErrorCode(0), nullMsg, fxnName);
	   return (-1);
	 }
	moncomCmd[ARBITER_CPU] = 0;
	return (1);

}

arbMonitorRun ()
{

	/* executes the 'monitorRun()' function on the arbiter */

	char *fxnName = "arbMonitorRun()";

	if (rciTaskExec (monitorRun, (int)residentTaskQueue) < 0)
	 { errorMsg (getErrorCode(0), nullMsg, fxnName);
	   return (-1);
	 }
	return (1);

}
/* MS Linux uses Heartbeat to run the monitor every 10 cycles on JLS */
#ifdef LINUX_CFG
#define HEARTBEAT_INTERVAL	10
#else
#define HEARTBEAT_INTERVAL	100
#endif
arbMonitorHeartbeat (set)
int set;
{

	/* sets up a default 'pulse' associated with the arbiter
	   monitor, so that the arbiter monitor is called at some
	   minimum rate to ensure that it can perform functions like 
	   checking for timeouts and the like.
	*/

	char *fxnName = "arbMonitorHeartbeat()";


	if (set)
	 { if (rciClockExec (HEARTBEAT_INTERVAL, 
			     monitorRun, (int)residentTaskQueue) < 0)
	    { errorMsg (getErrorCode(0), nullMsg, fxnName);
	      return (-1);
	    }
	 }
	else 
	 { if (rciClockExec (0, NULLF, 0) < 0)
	    { errorMsg (getErrorCode(0), nullMsg, fxnName);
	      return (-1);
	    }
	 }

	return (1);

}
