//
//  alarm.c:  Test of 'clock' alarm-setting thread
//
//    $Id: alarm.c,v 1.1 2001/03/26 03:17:45 khj Exp $
//

#include <rtl.h>
#include <rtl_sched.h>

#include <linux/comedi.h>
#include <linux/comedilib.h>

//
// *** Prototypes ***
//
int  init_module(void);
void cleanup_module(void);

//
// *** GLOBALS ***
//
#define PERIOD 1000000    // 1kHz

pthread_t clockt;
pthread_t clktestt;

int ALARM;


//
// *** THREADS ***
//
void *clock(void *t) {
  //  *****
  rtl_printf("kj: >clock\n");
  pthread_suspend_np(pthread_self());

  pthread_make_periodic_np(pthread_self(), gethrtime(), PERIOD);

  rtl_printf("kj: clock1\n");
  while (1) {
    pthread_wait_np();
    ALARM = 1;
    rtl_printf("kj: clock2\n");
    pthread_suspend_np(pthread_self());
  }  
}

void *clktest(void *t) {
  //  *******
  int ctr;

  rtl_printf("kj: >clktest\n");
  pthread_wakeup_np(clockt);

  rtl_printf("kj: clktest1\n");

  ALARM = 0;
  for(ctr=0; ctr<100000000; ctr++)
    if (ALARM)
      break;

  rtl_printf("kj: ctr %d  ALARM %d\n", ctr, ALARM);
  
  pthread_suspend_np(pthread_self());
}  



//
// *** MODULE INIT/TERM ***
//
int init_module () {
  int err;
  pthread_attr_t attr;
  struct sched_param sched_param;

  rtl_printf("\nkj: Installing module.\n");

  // -- clock
  pthread_attr_init (&attr);
  sched_param.sched_priority = 4;
  pthread_attr_setschedparam (&attr, &sched_param);

  if ((err = pthread_create (&clockt, &attr, clock, NULL)))
     rtl_printf("kj: Error in 'clock' creation!\n");


  // -- clktest
  pthread_attr_init (&attr);
  sched_param.sched_priority = 2;
  pthread_attr_setschedparam (&attr, &sched_param);

  if((err = pthread_create (&clktestt, &attr, clktest, NULL)))
     rtl_printf("kj: Error in 'clktest' creation!\n");

  return 0;
}

void cleanup_module() {
  // Remove thread
  pthread_delete_np(clktestt);
  pthread_delete_np(clockt);

  rtl_printf("kj: Module removed (ALARM=%d).\n", ALARM);
}
