#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <err.h>
#include <sys/netmgr.h>
#include <sys/neutrino.h>


#define MY_PULSE_CODE		_PULSE_CODE_MINAVAIL


typedef union {
	struct _pulse   pulse;
	/* your other message structures would go here too */
} my_message_t;


static void *Thread( void *arg ) {
	struct itimerspec  itime;
	struct sigevent  event;
	unsigned long  *period = arg;
	my_message_t  msg;
	timer_t  timer_id;
	int  chid, rcvid;

	chid = ChannelCreate( 0 );

	event.sigev_notify = SIGEV_PULSE;
	event.sigev_coid = ConnectAttach( ND_LOCAL_NODE, 0, chid, _NTO_SIDE_CHANNEL, 0 );
	event.sigev_priority = 26;
	event.sigev_code = MY_PULSE_CODE;
	timer_create( CLOCK_REALTIME, &event, &timer_id );

	itime.it_value.tv_sec  = 0;
	itime.it_value.tv_nsec = *period;
	itime.it_interval = itime.it_value;
	timer_settime( timer_id, 0, &itime, NULL );

	for (;;) {
		if ( 0 == ( rcvid = MsgReceive( chid, &msg, sizeof msg, NULL ) ) ) { 
			switch ( msg.pulse.code ) {
			case MY_PULSE_CODE:
				/* Do something */
				break;
			default:
				break;
			}
		}
	}

	return arg;
}

int main( int argc, char *argv[] ) {
	struct _clockperiod  cp;
	unsigned long  period[3] = { 1, 2, 4 };
	unsigned long  base_period = 250000;
	int  i;

	if ( ClockPeriod( CLOCK_REALTIME, NULL, &cp, 0 ) )
		err( EXIT_FAILURE, "ClockPeriod()" );

	printf( "Old: %lu ns\n", cp.nsec );
	cp.nsec = base_period;
	cp.fract = 0;

	if ( ClockPeriod( CLOCK_REALTIME, &cp, NULL, 0 ) || ClockPeriod( CLOCK_REALTIME, NULL, &cp, 0 ) )
		err( EXIT_FAILURE, "ClockPeriod()" );

	base_period = cp.nsec;
	printf( "Actual period: %lu ns\n", base_period );

	for ( i = 0; i < 3; i++ ) {
		period[i] *= base_period;
		pthread_create( NULL, NULL, Thread, &period[i] );
	}

	sleep( 100 );

	return EXIT_SUCCESS;   
}
