Subversion Repositories shark

Rev

Rev 218 | Blame | Compare with Previous | Last modification | View Log | RSS feed

/*
 * Copyright (c) 1996 The University of Utah and
 * the Computer Systems Laboratory at the University of Utah (CSL).
 * All rights reserved.
 *
 * Permission to use, copy, modify and distribute this software is hereby
 * granted provided that (1) source code retains these copyright, permission,
 * and disclaimer notices, and (2) redistributions including binaries
 * reproduce the notices in supporting documentation, and (3) all advertising
 * materials mentioning features or use of this software display the following
 * acknowledgement: ``This product includes software developed by the
 * Computer Systems Laboratory at the University of Utah.''
 *
 * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
 * IS" CONDITION.  THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
 * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 *
 * CSL requests users of this software to return to csl-dist@cs.utah.edu any
 * improvements that they make and grant CSL redistribution rights.
 */

/*
 * Linux timer support.
 */



#include<kernel/kern.h>
#include<time.h>
#include<linux/timer.h>

//#define TIMER_DEBUG

//#define IANPATCH
#ifndef IANPATCH

static inline void
jiffies_to_timespec(unsigned long j, struct timespec *value)
{
 
  value->tv_nsec = (j % HZ) * (1000000000L / HZ);
  value->tv_sec = j / HZ;

}

int add_timer(struct timer_list *timer)
{

  struct timespec timeout;

  jiffies_to_timespec(timer->expires, &timeout);
  timer->event_timer = kern_event_post(&timeout, (void (*)(void *))timer->function, (void *)timer->data);

  #ifdef TIMER_DEBUG
    cprintf("Set to %ld:%ld\n",timeout.tv_sec,timeout.tv_nsec);
  #endif

  return 0;

}


void del_timer(struct timer_list *timer)
{

  kern_event_delete(timer->event_timer);

}

void mod_timer(struct timer_list *timer, unsigned long expires)
{
 
  kern_event_delete(timer->event_timer);
  timer->expires = expires;
  add_timer(timer);

}

void init_timer(struct timer_list * timer)
{
}

#else

#include <pthread.h>

/*Needs to have this sort of thing in the initfile
 * PTHREAD_register_module(1, 0, 1);
 *
 *   TIMER_register_module();
 *   PI_register_module();
 *   PC_register_module();
 */


pthread_attr_t task_attr; /* attributtes for the task doing the callback*/

static inline void
jiffies_to_timespec(unsigned long j, struct timespec *value)
{
        value->tv_nsec = (j % HZ) * (1000000000L / HZ);
        value->tv_sec = j / HZ;
}

int add_timer(struct timer_list *timer)
{
  int err;
  struct sigevent ev;
  struct sched_param task_param;
  struct itimerspec timeout;

  ev.sigev_notify            = SIGEV_THREAD;
  ev.sigev_value.sival_int   = timer->data;
  ev.sigev_notify_function   = timer->function;
  ev.sigev_notify_attributes = &task_attr;

  pthread_attr_init(&task_attr);
  pthread_attr_setdetachstate(&task_attr, PTHREAD_CREATE_DETACHED);
  pthread_attr_setschedpolicy(&task_attr, SCHED_RR);
  task_param.sched_priority = 10;
  pthread_attr_setschedparam(&task_attr, &task_param);

  err =timer_create(CLOCK_REALTIME, &ev, &(timer->sharktimer));
  if (err !=0 ) { cprintf("timer: unable to create timer\n"); }
 
  timeout.it_interval.tv_sec=0;
  timeout.it_interval.tv_nsec=0;
  jiffies_to_timespec(timer->expires, &(timeout.it_value));

  err = timer_settime(timer->sharktimer, 0, &timeout, NULL);
  if (err !=0 ) { cprintf("timer: unable to timer_settime\n"); }
 
  return err;
}


void del_timer(struct timer_list *timer)
{
        timer_delete(timer->sharktimer);
}

void mod_timer(struct timer_list *timer, unsigned long expires)
{
        timer_delete(timer->sharktimer);
        timer->expires=expires;
        add_timer(timer);
}

void init_timer(struct timer_list * timer)
{
}

#endif