packages feed

timberc-1.0.1: rtsPOSIX/timer.c

// The Timber compiler <timber-lang.org>
// 
// Copyright 2008 Johan Nordlander <nordland@csee.ltu.se>
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 
// 3. Neither the names of the copyright holder and any identified
//    contributors, nor the names of their affiliations, may be used to 
//    endorse or promote products derived from this software without 
//    specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.


#include "timber.h"

struct S_Timer {
    WORD *GCINFO;
    AbsTime start;
};

typedef struct S_Timer *S_Timer;

struct T_Timer;
typedef struct T_Timer *T_Timer;

struct T_Timer {
  WORD *GCINFO;
  UNITTYPE (*reset) (T_Timer, Int);
  Time (*sample) (T_Timer, Int);
  Ref self;
};


static WORD __GC__T_Timer[] = {WORDS(sizeof(struct T_Timer)), GC_STD, WORDS(offsetof(struct T_Timer,self)), 0};
   
static WORD __GC__S_Timer[] = {WORDS(sizeof(struct S_Timer)), GC_STD, 0};

static WORD __GC__Time[]    = {WORDS(sizeof(struct Time)), GC_STD, 0};


Time sec(Int c) {
  Time res;
  NEW(Time,res,WORDS(sizeof(struct Time)));
  res->GCINFO = __GC__Time;
  res->sec = c;
  res->usec = 0;
  return res;
}

Time millisec(Int c) {
  Time res;
  NEW(Time,res,WORDS(sizeof(struct Time)));
  res->GCINFO = __GC__Time;
  res->sec = c / 1000;
  res->usec = 1000 * (c % 1000);
  return res;
}

Time microsec(Int c) {
  Time res;
  NEW(Time,res,WORDS(sizeof(struct Time)));
  res->GCINFO = __GC__Time;
  res->sec = c / 1000000;
  res->usec = c % 1000000;
  return res;
}

Int secOf(Time t) {
  switch ((Int)t) {
  case INHERIT: panic("secOf Inherit");
  case TIME_INFINITY: panic("secOf infinity");
  default: return t->sec;
  }
}

Int microsecOf(Time t) {
  switch ((Int)t) {
  case INHERIT: panic("microsecOf Inherit");
  case TIME_INFINITY: panic("microsecOf infinity");
  default: return t->usec;
  }
}



Time primTimePlus(Time t1, Time t2) {
  Time res;
  switch ((Int)t1) {
  case INHERIT: return t2;
  case TIME_INFINITY: return Infinity;
  default: 
    switch ((Int)t2) {
    case INHERIT: return t1;
    case TIME_INFINITY: return Infinity;
    default:
      NEW(Time,res,WORDS(sizeof(struct Time)));
      res->GCINFO = __GC__Time;
      res->usec = t1->usec + t2->usec;
      res->sec = t1->sec + t2->sec;
      if (res->usec >= 1000000) {
	res->usec -= 1000000;
	res->sec += 1;
      }
      return res;
    }
  }
}

Time primTimeMin(Time t1, Time t2) {
  switch ((Int)t1) {
  case INHERIT: 
  case TIME_INFINITY:return t2;
  default:
    switch ((Int)t2) {
    case INHERIT: 
    case TIME_INFINITY: return t1;
    default: 
      if (t1->sec < t2->sec || (t1->sec == t2->sec && t1->usec < t2->usec))
	return t1;
      else
	return t2;
    }
  }
}


Time primTimeMinus(Time t1, Time t2) {
  Time res;
  switch ((Int)t1) {
  case INHERIT: panic("primTimeMinus Inherit");
  case TIME_INFINITY: 
    switch((Int) t2) {
    case INHERIT: panic("primTimeMinus Inherit");
    case TIME_INFINITY: panic("infinity - infinity");
    default: return Infinity;
    }      
  default:
    switch ((Int)t2) {
    case INHERIT: panic("primTimeMinus Inherit");
    case TIME_INFINITY:
      NEW(Time,res,WORDS(sizeof(struct Time)));
      res->GCINFO = __GC__Time;
      res->sec = 0;
      res->usec = 0;
      return res;
    default:
      NEW(Time,res,WORDS(sizeof(struct Time)));
      res->GCINFO = __GC__Time;
      res->usec = t1->usec - t2->usec;
      if (res->usec < 0) {
	res->usec += 1000000;
	t1->sec -= 1;
      }
      res->sec = t1->sec - t2->sec;
      if (res->sec < 0) res->sec = 0;
      return res;
    }
  }
}

Bool primTimeEQ(Time t1, Time t2) {
  switch ((Int)t1) {
  case INHERIT: panic("primTimeEQ Inherit");
  case TIME_INFINITY: switch((Int)t2) {
    case INHERIT: panic("primTimeEQ Inherit");
    case TIME_INFINITY: return 1;
    default:
      return 0;
    }
  default:
    switch ((Int)t2) {
    case INHERIT: panic("primTimeEQ Inherit");
    case TIME_INFINITY: return 0;
    default:
      return (t1->sec == t2->sec && t1->usec == t2->usec);
    }
  }
}

Bool primTimeNE(Time t1, Time t2) {
  switch ((Int)t1) {
  case INHERIT: panic("primTimeNE Inherit");
  case TIME_INFINITY: switch((Int)t2) {
    case INHERIT: panic("primTimeNE Inherit");
    case TIME_INFINITY: return 0;
    default:
      return 1;
    }
  default:
    switch ((Int)t2) {
    case INHERIT: panic("primTimeNE Inherit");
    case TIME_INFINITY: return 1;
    default:
      return (t1->sec != t2->sec || t1->usec != t2->usec);
    }
  }
}

Bool primTimeLT(Time t1, Time t2) {
  switch ((Int)t1) {
  case INHERIT: panic("primTimeLT Inherit");
  case TIME_INFINITY: switch((Int)t2) {
    case INHERIT: panic("primTimeLT Inherit");
    default:
      return 0;
    }
  default:
    switch ((Int)t2) {
    case INHERIT: panic("primTimeLT Inherit");
    case TIME_INFINITY: return 1;
    default:
      return (t1->sec < t2->sec || (t1->sec==t2->sec && t1->usec<t2->usec));
    }
  }
}
Bool primTimeLE(Time t1, Time t2) {
  switch ((Int)t1) {
  case INHERIT: panic("primTime InheritLE");
  case TIME_INFINITY: switch((Int)t2) {
    case INHERIT: panic("primTime InheritLE");
    default:
      return 0;
    }
  default:
    switch ((Int)t2) {
    case INHERIT: panic("primTime InheritLE");
    case TIME_INFINITY: return 1;
    default:
      return (t1->sec < t2->sec || (t1->sec==t2->sec && t1->usec<=t2->usec));
    }
  }
}

Bool primTimeGT(Time t1, Time t2) {
  return primTimeLT(t2,t1);
}

Bool primTimeGE(Time t1, Time t2) {
  return primTimeLE(t2,t1);
}

static UNITTYPE reset_fun(Ref self, Int x) {
  self = (Ref)LOCK((PID)self);
  ((S_Timer)STATEOF(self))->start = CURRENT()->msg->baseline;
  UNLOCK((PID)self);
  return (UNITTYPE)0;
}

static Time sample_fun(Ref self, Int x) {
  self = (Ref)LOCK((PID)self);
  AbsTime now;
  now = CURRENT()->msg->baseline;
  SUB(now,((S_Timer)STATEOF(self))->start);
  UNLOCK((PID)self);
  Time res;
  NEW(Time,res,WORDS(sizeof(struct Time)));
  res->GCINFO = __GC__Time;
  res->sec = now.tv_sec;
  res->usec = now.tv_usec;
  return res;
}

static UNITTYPE reset_sel(T_Timer this,Int x) {
  return reset_fun(this->self,x);
}

static Time sample_sel(T_Timer this, Int x) {
  return sample_fun(this->self,x);
}

TIMERTYPE primTIMERTERM(Int x) {
  Ref self;
  NEW(Ref,self,WORDS(sizeof(struct Ref))+WORDS(sizeof(struct S_Timer)));
  INITREF(self);
  ((S_Timer)STATEOF(self))->GCINFO = __GC__S_Timer;
  ((S_Timer)STATEOF(self))->start = CURRENT()->msg->baseline;
  T_Timer res;
  NEW(T_Timer,res,WORDS(sizeof(struct T_Timer)));
  res->GCINFO = __GC__T_Timer;
  res->reset = reset_sel;
  res->sample = sample_sel;
  res->self = self;
  return (TIMERTYPE)res;
}