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

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

#include <time.h>
#include <pthread.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");

  while (1) {
    pthread_suspend_np(pthread_self());

    rtl_printf("kj: Before %ld\n", gethrtime());
    nanosleep(hrt2ts(PERIOD), NULL);
    rtl_printf("kj: After  %ld\n", gethrtime());

    ALARM = 1;
    rtl_printf("kj: clock1\n");
  }  
}

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

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

  ALARM = 0;
  pthread_wakeup_np(clockt);

  rtl_printf("kj: clktest1\n");


  while(!ALARM) {}

  rtl_printf("kj: ALARM non-zero %ld\n", gethrtime());

  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);
}
