#include <time.h>
#include <sys/siginfo.h>
#include <sys/netmgr.h>
#include <sys/neutrino.h>
#include <sys/time.h>
#include <pthread.h>
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
//ID pulsow
#define PULSE_ID2 10
#define PULSE_ID3 11
//czas startu programu
struct timeval start;
//struktura wiadomosci
typedef struct{
struct _pulse pulse;
} msg;
//do zapewnienia sekcji krytycznej
pthread_mutex_t mut;
//identyfikatory timerow
timer_t timer1, timer2, timer3, timer4;
//identyfikator kanalu
int chid;
//identyfikatory polaczen dla T2 i T3
int coid2, coid3;
//funkcja wypisujaca komunikat oznaczony timestampem
void timestamp(char* msg)
{
pthread_mutex_lock(&mut); //terminal jest chroniony mutexem
//pobranie aktualnego czasu
gettimeofday
(&time, NULL
);
int miliseconds
= ((time.
tv_sec-start.
tv_sec)*1000000 + time.
tv_usec-start.
tv_usec)/1000; //czas od startu
int seconds = miliseconds/1000; //sekundy
miliseconds = miliseconds%1000; //milisekundy
printf("%d:%03ld\t - %s\n", seconds
, miliseconds
, msg
);
pthread_mutex_unlock(&mut);
}
//watek T1
void thread1(void* args)
{
timestamp("Timer T1.");
}
//handler sygnalu SIGINT - zamyka program
void signalHandler(int sigid)
{
//usuwanie timerow
timer_delete(timer1);
timer_delete(timer2);
timer_delete(timer3);
timer_delete(timer4);
//zamykanie polaczen i kanalu
ConnectDetach(coid2);
ConnectDetach(coid3);
ChannelDestroy(chid);
timestamp("Timer T4. Koniec programu.");
}
int main()
{
//eventy dla timerow
struct sigevent event1, event2, event3, event4;
//parametry timerow
struct itimerspec itimerspec1, itimerspec2, itimerspec3, itimerspec4;
int rcvid;
msg message;
//ustawienie handlera sygnalu
signal(SIGINT, signalHandler);
chid = ChannelCreate(0);
//stworzenie eventu tworzacego watek
SIGEV_THREAD_INIT (&event1, (void*)thread1, NULL, NULL);
//czas pierwszego uruchomienia i powtarzania 0.5s
itimerspec1.it_value.tv_sec = 0;
itimerspec1.it_value.tv_nsec = 500000000;
itimerspec1.it_interval.tv_sec = 0;
itimerspec1.it_interval.tv_nsec = 500000000;
//stworzenie eventu wywolujacego puls 2
coid2 = ConnectAttach(ND_LOCAL_NODE, 0, chid, _NTO_SIDE_CHANNEL, 0);
SIGEV_PULSE_INIT (&event2, coid2, SIGEV_PULSE_PRIO_INHERIT, PULSE_ID2, NULL);
//czas pierwszego uruchomienia i powtarzania 2s
itimerspec2.it_value.tv_sec = 2;
itimerspec2.it_value.tv_nsec = 0;
itimerspec2.it_interval.tv_sec = 2;
itimerspec2.it_interval.tv_nsec = 0;
//stworzenie eventu wywolujacego puls 3
coid3 = ConnectAttach(ND_LOCAL_NODE, 0, chid, _NTO_SIDE_CHANNEL, 0);
SIGEV_PULSE_INIT (&event3, coid3, SIGEV_PULSE_PRIO_INHERIT, PULSE_ID3, NULL);
//czas pierwszego uruchomienia 5s, powtarzania 1s
itimerspec3.it_value.tv_sec = 5;
itimerspec3.it_value.tv_nsec = 0;
itimerspec3.it_interval.tv_sec = 1;
itimerspec3.it_interval.tv_nsec = 0;
//stworzenie eventu wywolujacego SIGINT
SIGEV_SIGNAL_INIT (&event4, SIGINT);
//czas pierwszego i jedynego uruchomienia - 10s
itimerspec4.it_value.tv_sec = 10;
itimerspec4.it_value.tv_nsec = 0;
itimerspec4.it_interval.tv_sec = 0;
itimerspec4.it_interval.tv_nsec = 0;
//stworzenie timerow dla eventow i zapamietanie ich id
timer_create(CLOCK_REALTIME, &event1, &timer1);
timer_create(CLOCK_REALTIME, &event2, &timer2);
timer_create(CLOCK_REALTIME, &event3, &timer3);
timer_create(CLOCK_REALTIME, &event4, &timer4);
//ustawienie czasow timerow
timer_settime(timer1, 0, &itimerspec1, NULL);
timer_settime(timer2, 0, &itimerspec2, NULL);
timer_settime(timer3, 0, &itimerspec3, NULL);
timer_settime(timer4, 0, &itimerspec4, NULL);
//zapisanie poczatkowego czasu programu
gettimeofday(&start, NULL);
timestamp("Start");
//odbieranie wiadomosci
while(1)
{
rcvid = MsgReceive(chid, &message, sizeof(message), NULL);
if(rcvid == 0)
{
if(message.pulse.code == PULSE_ID2)
{
timestamp("Timer T2.");
}
else if(message.pulse.code == PULSE_ID3)
{
timestamp("Timer T3.");
}
}
}
return 0;
}