home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / ixemul-45.0-src.tgz / tar.out / contrib / ixemul / library / kern_time.c < prev    next >
C/C++ Source or Header  |  1996-09-28  |  6KB  |  208 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *
  5.  *  This library is free software; you can redistribute it and/or
  6.  *  modify it under the terms of the GNU Library General Public
  7.  *  License as published by the Free Software Foundation; either
  8.  *  version 2 of the License, or (at your option) any later version.
  9.  *
  10.  *  This library is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  *  Library General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU Library General Public
  16.  *  License along with this library; if not, write to the Free
  17.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  *
  19.  *  kern_time.c,v 1.1.1.1 1994/04/04 04:30:41 amiga Exp
  20.  *
  21.  *  kern_time.c,v
  22.  * Revision 1.1.1.1  1994/04/04  04:30:41  amiga
  23.  * Initial CVS check in.
  24.  *
  25.  *  Revision 1.1  1992/05/14  19:55:40  mwild
  26.  *  Initial revision
  27.  *
  28.  *
  29.  *  Since the code originated from Berkeley, the following copyright
  30.  *  header applies as well. The code has been changed, it's not the
  31.  *  original Berkeley code!
  32.  */
  33.  
  34. /*
  35.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  36.  * All rights reserved.
  37.  *
  38.  * Redistribution is only permitted until one year after the first shipment
  39.  * of 4.4BSD by the Regents.  Otherwise, redistribution and use in source and
  40.  * binary forms are permitted provided that: (1) source distributions retain
  41.  * this entire copyright notice and comment, and (2) distributions including
  42.  * binaries display the following acknowledgement:  This product includes
  43.  * software developed by the University of California, Berkeley and its
  44.  * contributors'' in the documentation or other materials provided with the
  45.  * distribution and in all advertising materials mentioning features or use
  46.  * of this software.  Neither the name of the University nor the names of
  47.  * its contributors may be used to endorse or promote products derived from
  48.  * this software without specific prior written permission.
  49.  * THIS SOFTWARE IS PROVIDED AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  50.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  51.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  52.  *
  53.  *    @(#)kern_time.c    7.13 (Berkeley) 6/28/90
  54.  */
  55.  
  56. #define _KERNEL
  57. #include "ixemul.h"
  58. #include "kprintf.h"
  59.  
  60. #include <sys/time.h>
  61.  
  62. #define err_return(code)        \
  63. {                    \
  64.   errno = code;                \
  65.   KPRINTF (("&errno = %lx, errno = %ld\n", &errno, errno)); \
  66.   return -1;                \
  67. }
  68.  
  69. void timevalfix(struct timeval *t1);
  70. void timevaladd(struct timeval *t1, const struct timeval *t2);
  71. void timevalsub(struct timeval *t1, const struct timeval *t2);
  72.  
  73. int
  74. getitimer(u_int    which, struct itimerval *itv)
  75. {
  76.   if (which > ITIMER_PROF || !itv)
  77.     err_return (EINVAL);
  78.  
  79.   Disable ();
  80.   *itv = u.u_timer[which];
  81.   Enable();
  82.  
  83.   return 0;
  84. }
  85.  
  86. int
  87. setitimer(u_int    which, const struct itimerval *itv, struct itimerval *oitv)
  88. {
  89.     if (which > ITIMER_PROF)
  90.         err_return (EINVAL);
  91.  
  92.     if (oitv && getitimer(which, oitv))
  93.         return -1;
  94.     if (itv == 0)
  95.         return 0;
  96.  
  97.     if (itimerfix((struct timeval *)&itv->it_value) || 
  98.         itimerfix((struct timeval *)&itv->it_interval))
  99.         err_return (EINVAL);
  100.  
  101.     Disable ();
  102.     u.u_timer[which] = *itv;
  103.     Enable ();
  104.  
  105.     return 0;
  106. }
  107.  
  108. /*
  109.  * Check that a proposed value to load into the .it_value or
  110.  * .it_interval part of an interval timer is acceptable, and
  111.  * fix it to have at least minimal value (i.e. if it is less
  112.  * than the resolution of the clock, round it up.)
  113.  */
  114. int itimerfix(struct timeval *tv)
  115. {
  116.     if (tv->tv_sec < 0 || tv->tv_sec > 100000000 ||
  117.         tv->tv_usec < 0 || tv->tv_usec >= 1000000)
  118.         err_return (EINVAL);
  119.     if (tv->tv_sec == 0 && tv->tv_usec != 0 && tv->tv_usec < ITIMER_RESOLUTION)
  120.         tv->tv_usec = ITIMER_RESOLUTION;
  121.     return 0;
  122. }
  123.  
  124. /*
  125.  * Decrement an interval timer by a specified number
  126.  * of microseconds, which must be less than a second,
  127.  * i.e. < 1000000.  If the timer expires, then reload
  128.  * it.  In this case, carry over (usec - old value) to
  129.  * reducint the value reloaded into the timer so that
  130.  * the timer does not drift.  This routine assumes
  131.  * that it is called in a context where the timers
  132.  * on which it is operating cannot change in value.
  133.  */
  134.  
  135. /* on 0 return, send a signal to process */
  136.  
  137. int
  138. itimerdecr (struct itimerval *itp, int usec)    /* CALLED FROM INTERRUPT !! */
  139. {
  140.   if (itp->it_value.tv_usec < usec) 
  141.     {
  142.       if (itp->it_value.tv_sec == 0) 
  143.     {
  144.       /* expired, and already in next interval */
  145.       usec -= itp->it_value.tv_usec;
  146.       goto expire;
  147.     }
  148.  
  149.       itp->it_value.tv_usec += 1000000;
  150.       itp->it_value.tv_sec--;
  151.     }
  152.  
  153.   itp->it_value.tv_usec -= usec;
  154.   usec = 0;
  155.   if (timerisset(&itp->it_value))
  156.     return (1);
  157.  
  158.   /* expired, exactly at end of interval */
  159. expire:
  160.   if (timerisset(&itp->it_interval)) 
  161.     {
  162.       itp->it_value = itp->it_interval;
  163.       itp->it_value.tv_usec -= usec;
  164.       if (itp->it_value.tv_usec < 0) 
  165.         {
  166.       itp->it_value.tv_usec += 1000000;
  167.       itp->it_value.tv_sec--;
  168.     }
  169.     } 
  170.   else
  171.     itp->it_value.tv_usec = 0;        /* sec is already 0 */
  172.  
  173.   return (0);
  174. }
  175.  
  176. /*
  177.  * Add and subtract routines for timevals.
  178.  * N.B.: subtract routine doesn't deal with
  179.  * results which are before the beginning,
  180.  * it just gets very confused in this case.
  181.  * Caveat emptor.
  182.  */
  183. void timevaladd(struct timeval *t1, const struct timeval *t2)
  184. {
  185.     t1->tv_sec += t2->tv_sec;
  186.     t1->tv_usec += t2->tv_usec;
  187.     timevalfix(t1);
  188. }
  189.  
  190. void timevalsub(struct timeval *t1, const struct timeval *t2)
  191. {
  192.     t1->tv_sec -= t2->tv_sec;
  193.     t1->tv_usec -= t2->tv_usec;
  194.     timevalfix(t1);
  195. }
  196.  
  197. void timevalfix(struct timeval *t1)
  198. {
  199.     if (t1->tv_usec < 0) {
  200.         t1->tv_sec--;
  201.         t1->tv_usec += 1000000;
  202.     }
  203.     if (t1->tv_usec >= 1000000) {
  204.         t1->tv_sec++;
  205.         t1->tv_usec -= 1000000;
  206.     }
  207. }
  208.