modularize.c 4.58 KB
/*
 * Copyright (C) 1996-1998 by the Board of Trustees
 *    of Leland Stanford Junior University.
 * 
 * This file is part of the SimOS distribution. 
 * See LICENSE file for terms of the license. 
 *
 */

/* 
 *  modularize.c
 *
 *  This file is supposed to include all the typedefs, macros
 *  and function headers that allows diskdevice.c to compile
 *  independently of proteus.
 *
 * $Id: modularize.c,v 1.1.1.1 2002/05/29 01:09:11 blythe Exp $
 */

#include "modularize.h"
#include "heap.h"
#include "diskevent.h"
#include "simtypes.h"
#include "hd.h"

/* =======================The Timing Stuff ================================ */
/* keep the time struct within this file, i.e. modularize.c */
static struct timestruct system_timer;


/* returns the current time */
TICS GetTime(void)
{
  return (system_timer.currenttime);
}


/* returns the greater of timea and timeb;
   if (timea == timeb) return timeb */
TICS max(TICS timea, TICS timeb)
{
  return ((timea > timeb) ? timea : timeb);
}


/* returns the lesser of timea and timeb;
   if (timea == timeb) return timeb */
TICS min(TICS timea, TICS timeb)
{
  return ((timea < timeb) ? timea : timeb);
}


/* wait till system time is TICS, process the
   events if they happen before TICS */
void WaitTime(TICS donetime)
{
  extern Heap heap;
  HeapKey Hpkey;
  HeapData Hpdat;
  FuncPtr handler;

  
  while (TopHeap(heap, &Hpdat, &Hpkey) != FALSE && (Hpkey < donetime))
    {
      INVARIANT2((RemHeap(heap, &Hpdat, &Hpkey)),"WaitTime: heap empty!\n");
      system_timer.currenttime = Hpkey;
      handler = DDhandlers[Hpdat->req_code].handler;
      
      if (Hpdat->req_code != NOP)
	(*handler) (Hpdat->disk, Hpkey);
      free(Hpdat);		/* free up space allocated during AddHeap() */
    }
  system_timer.currenttime = donetime;
}



void WaitDuration(TICS duration)
{
  WaitTime(system_timer.currenttime + duration);
}



TICS InitTime(void)
{
  system_timer.currenttime = 0;
  DDEventInit();		/* initialize the event heap */
  return(system_timer.currenttime);
}


/* void thread_sleep(int tid) */
void thread_suspend(int tid)
{
  extern int wakeup;	        /* declared in modularize.h */
  extern Heap heap;
  HeapKey Hpkey;
  HeapData Hpdat;
  FuncPtr handler;

  wakeup = -1;
  do
    {
      INVARIANT2((RemHeap(heap, &Hpdat, &Hpkey) != FALSE), 
		 "thread_suspend: can't remove from empty heap\n");

      system_timer.currenttime = Hpkey;
      handler = DDhandlers[Hpdat->req_code].handler;
      if (Hpdat->req_code != NOP)
	(*handler) (Hpdat->disk, Hpkey);
      else
	{DEBUG0 printf("thread_suspend: removing NOP\n");}
      free(Hpdat);		/* free up space allocated during AddHeap() */
    }
  while (wakeup != tid);
}
#ifndef SOLO

#define TEMP_MAX_DISKS 16

static struct {
    int tid;
    void (*routine)(void *);
    void *arg;
} waitingThread[SIM_MAX_DISKS];
 
void thread_suspend_continue(int tid, void (*routine)(void *), void *arg)
{
#ifdef SOLO
   int disk = (int) arg;
#else
   int disk = PTR_TO_UINT64(arg);
#endif
    waitingThread[disk].tid = tid;
    waitingThread[disk].routine = routine;
    waitingThread[disk].arg = arg;
}

void thread_wakeup(int disk,int tid)
{
    if (tid == waitingThread[disk].tid) {
	waitingThread[disk].routine(waitingThread[disk].arg);
    }
    waitingThread[disk].tid = -1; 
    
    
}
    
#endif 

/* void thread_wakeup(int tid) 
void DDEventWakeup(int stid, TICS when)
{
  extern int wakeup;	        declared in modularize.h 
  wakeup = stid;
}
*/

/* ======================================================================== */
/*  time_print
 *
 *  Function to return the system time in a string.
 */
char* time_print(TICS t) {
  /* List of static buffers */
  static char buffers[100][21]; /* 20 digits holds a 64-bit number */
  static int next_buffer = 0;
  char* buffer;
  
  buffer = buffers[next_buffer];
  next_buffer = (next_buffer + 1) % 100;
  
#ifdef LONG_LONG_TIME
  /* Print out seven digits at a time */
  {
    unsigned long part1, part2, part3;
    
    
    part3 = (unsigned long) (t % 10000000);
    t = t / 10000000;
    
    part2 = (unsigned long) (t % 10000000);
    t = t / 10000000;
    
    part1 = (unsigned long) t;
    
    if (part1 > 0) {
      sprintf(buffer, "%lu%07lu%07lu", part1, part2, part3);
    }
    else if (part2 > 0) {
      sprintf(buffer, "%lu%07lu", part2, part3);
    }
    else {
      sprintf(buffer, "%lu", part3);
    }
  }
#else
  sprintf(buffer, "%lu", t);
#endif
  
  return buffer;
}


/* timep_print(Time *t)
 *    gdb can't pass uint64s correctly, but it can pass 
 * *pointers* correctly.  So this is a front end to time_print()
 * for debugging.
 */
char *timep_print(TICS *t) {  return(time_print(*t)); }