/*
 * realtime.c -- Code for making the process go real-time, on capable systems.
 *
 * Copyright 1998, John E. Stone
 *                 j.stone@acm.org
 *                 johns@cs.umr.edu
 *
 * $Id: realtime.c,v 1.6 1998/02/18 03:41:22 johns Exp $
 * 
 */

#ifdef NOREALTIME

#include "realtime.h"

int make_realtime(void) {
  return -1;
}

#endif /* NOREALTIME */



#ifdef POSIXREALTIME 

#include <sched.h>

int make_realtime(void) {
  struct sched_param sp;

  sp.sched_priority = 1;
  if (sched_setscheduler(0, SCHED_FIFO, &sp) == -1)
    return -1;

  return 0;
}

#endif /* POSIXREALTIME */



#ifdef SOLARISREALTIME

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/priocntl.h>
#include <sys/rtpriocntl.h>
#include <sys/tspriocntl.h>
#include <errno.h>

#include "realtime.h"

static id_t schedinfo(); /* proto */

int make_realtime() {
  pcparms_t  pcparms;
  rtparms_t  *rtparmsp;
  id_t  pid, rtID;
  short  maxrtpri;

  pid = getpid();

  /* Get highest valid RT priority. */
  if ((rtID = schedinfo("RT", &maxrtpri)) == -1) {
    return 2;
  }

  /* Change proc to RT, highest prio - 1, default time slice */
  pcparms.pc_cid = rtID;
  rtparmsp = (struct rtparms *) pcparms.pc_clparms;
  rtparmsp->rt_pri = maxrtpri - 1;
  rtparmsp->rt_tqnsecs = RT_TQDEF;

  if (priocntl(P_PID, pid, PC_SETPARMS, (caddr_t) &pcparms) == -1) {
    return 3;
  }

  return 0;
}




/*
 * Return class ID and maximum priority.
 * Input argument name is class name.
 * Maximum priority is returned in *maxpri.
 */

static id_t schedinfo(char *name, short *maxpri) {
  pcinfo_t   info;
  tsinfo_t   *tsinfop;
  rtinfo_t   *rtinfop;

  (void) strcpy(info.pc_clname, name);
  if (priocntl (0L, 0L, PC_GETCID, (caddr_t) &info) == -1L) {
    return (-1);
  }

  if (strcmp(name, "TS") == 0) {
    tsinfop = (struct tsinfo *) info.pc_clinfo;
    *maxpri = tsinfop->ts_maxupri;
  } 
  else if (strcmp(name, "RT") == 0) {
    rtinfop = (struct rtinfo *) info.pc_clinfo;
    *maxpri = rtinfop->rt_maxpri;
  } 
  else {
    return (-1);
  }

  return (info.pc_cid);
}

#endif /* SOLARISREALTIME */


