Logo Search packages:      
Sourcecode: fair version File versions  Download package

chrono.c

/******************************************************************************

      chrono.c -- timer and timestamp functionality
      Copyright (C) 2004  Wessel Dankers <wsl@uvt.nl>

      This program is free software; you can redistribute it and/or modify
      it under the terms of the GNU General Public License as published by
      the Free Software Foundation; either version 2 of the License, or
      (at your option) any later version.

      This program is distributed in the hope that it will be useful,
      but WITHOUT ANY WARRANTY; without even the implied warranty of
      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      GNU General Public License for more details.

      You should have received a copy of the GNU General Public License
      along with this program; if not, write to the Free Software
      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

      $Id: chrono.c 23144 2007-12-21 15:36:48Z wsl $
      $URL: https://infix.uvt.nl/its-id/trunk/sources/fair-0.5.1/src/chrono.c $

******************************************************************************/

#include <sys/time.h>
#include <time.h>
#include <stdlib.h>

#include "fair.h"
#include "error.h"
#include "chrono.h"
#include "avlr.h"

static int ptrcmp(byte *a, byte *b) {
      assert(a && b);
      return a - b;
}

static int chrono_cmp(const chrono_t *a, const chrono_t *b) {
      stamp_t x, y;
      assert(a && b);
      x = a->expiry;
      y = b->expiry;
      return x > y ? 1 : x < y ? -1 : 0;
}

stamp_t now = 0LL;
static avl_tree_t active = {NULL, NULL, NULL, (avl_compare_t)chrono_cmp, NULL};
static avl_tree_t inactive = {NULL, NULL, NULL, (avl_compare_t)ptrcmp, NULL};
static const chrono_t chrono_0 = {{0}};

unsigned int chrono_count(void) {
      return avl_count(&active) + avl_count(&inactive);
}

stamp_t stamp_get(const struct timeval *tv) {
#if STAMP_TICKS != 1000000
#error FIXME
#endif
      unless(tv) return 0;
      return (stamp_t)tv->tv_sec * STAMP_TICKS + (stamp_t)tv->tv_usec;
}

void stamp_tv(struct timeval *tv, stamp_t when) {
#if STAMP_TICKS != 1000000
#error FIXME
#endif
      unless(tv) return;
      tv->tv_sec = when / STAMP_TICKS;
      tv->tv_usec = when % STAMP_TICKS;
}

void stamp_now(struct timeval *tv) {
      return stamp_tv(tv, now);
}

void stamp_sync(void) {
      struct timeval tv;
      
      if(gettimeofday(&tv, NULL) == -1)
            syslog_exit(LOG_CRIT, "gettimeofday(): %m");

      now = stamp_get(&tv);
}

chrono_t *chrono_new(chrono_hook_t func, void *data) {
      chrono_t *r = xalloc(sizeof *r);
      *r = chrono_0;
      r->func = func;
      r->data = data;
      avl_init_node(&r->node, r);
      avl_insert_node(r->tree = &inactive, &r->node);
      return r;
}

void chrono_at(chrono_t *cr, stamp_t moment) {
      unless(cr) return;
      cr->expiry = moment;
      if(cr->tree)
            avl_unlink_node(cr->tree, &cr->node);
      avl_insert_right(cr->tree = &active, &cr->node);
}

void chrono_after(chrono_t *cr, stamp_t moment) {
      chrono_at(cr, now + moment);
}

void chrono_disable(chrono_t *cr) {
      unless(cr) return;
      if(cr->tree != &inactive) {
            if(cr->tree)
                  avl_unlink_node(cr->tree, &cr->node);
            avl_insert_node(cr->tree = &inactive, &cr->node);
      }
}

void chrono_delete(chrono_t *cr) {
      unless(cr) return;
      if(cr->tree)
            avl_unlink_node(cr->tree, &cr->node);
      free(cr);
}

stamp_t chrono_events() {
      chrono_t *cr;
      while(active.head) {
            cr = active.head->item;
            assert(cr);
            if(cr->expiry > now)
                  return cr->expiry - now;
            assert(cr->tree == &active);
            avl_unlink_node(&active, &cr->node);
            avl_insert_node(cr->tree = &inactive, &cr->node);
            if(cr->func)
                  cr->func(cr);
      }
      return 0;
}

Generated by  Doxygen 1.6.0   Back to index