//============================================================================
// Name        : SignalTest.cpp
// Author      : FAZLOV
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>

#include <sys/procmgr.h>
#include <sys/neutrino.h>
#include <sync.h>

#include <stdio.h>
#include <unistd.h>


#include "time.h"
#include <pthread.h>
#include <stdlib.h>
#include <signal.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <sys/neutrino.h>
#include <malloc.h>
//#include <ipProto.h>
//#include <net/utils/ifconfig.h>
#include <unix.h>

#define DEBUG 1

pthread_barrier_t  barrier;


using namespace std;
/*
 *
 * int pthread_create( pthread_t* thread,
                    const pthread_attr_t* attr,
                    void* (*start_routine)(void* ),
                    void* arg );
 *
 */

#define SIGNALTIMER100    SIGRTMIN+1 //SIGRTMAX + 7

#define SIGNALTIMER50   SIGRTMIN+2 //SIGRTMAX + 8

timer_t timer100;

timer_t timer50;

pthread_t thread100;

pthread_t thread50;

int ErrorCountSinx;

void *Thread100(void *)
{
	int sigw;
	int err=0;
    struct sigaction act;
    sigset_t  set;
    struct sigevent event;
int    VCount100=0;

ErrorCountSinx=0;

	event.sigev_notify = SIGEV_SIGNAL;
    event.sigev_signo = SIGNALTIMER100;

    sigemptyset(&set);

    if(sigaddset(&set, SIGNALTIMER100))
    {
        err = 1;
        goto errmsg;
    }

   if((err = pthread_sigmask(SIG_BLOCK, &set, NULL)))
        goto errmsg;



   if(timer_create(CLOCK_REALTIME, &event, &timer100) != 0)
    {
        printf("\nThread 100 Error timer creating \n");
        exit(-1);
    }



   loop:


      if(sigwait(&set, &sigw))
        //if ((SignalWaitinfo(&set,0))==-1)
        {
          ErrorCountSinx++;
          goto loop;
      }
    //  printf("\nAfter In Loop 100\n");

      VCount100++;

 goto loop;

      errmsg: printf("\n Thread ERROR  start #%d", err);
      return NULL;

 }


void *Thread50(void *)
{
	int sigw;
	int err=0;
    struct sigaction act;
    sigset_t  set;
    struct sigevent event;
  int    VCount50=0;


	event.sigev_notify = SIGEV_SIGNAL;
    event.sigev_signo = SIGNALTIMER50;

    sigemptyset(&set);

    if(sigaddset(&set, SIGNALTIMER50))
    {
        err = 1;
        goto errmsg;
    }

   if((err = pthread_sigmask(SIG_BLOCK, &set, NULL)))
        goto errmsg;



   if(timer_create(CLOCK_REALTIME, &event, &timer50) != 0)
    {
        printf("\nThread 100 Error timer creating \n");
        exit(-1);
    }



   loop:


      if(sigwait(&set, &sigw))
      // if ((SignalWaitinfo(&set,0))==-1)
        {
          goto loop;
      }
  //    printf("\nAfter In Loop 50\n");

      VCount50++;

 goto loop;

      errmsg: printf("\n Thread 50 ERROR  start #%d", err);
      return NULL;

 }




void AddThread(pthread_t* thread,int Prio,void* (*start_routine)(void* ))
{
    int err;
    pthread_attr_t attr;


    struct sched_param schedparam;
    int Polisy;
    err = 0;
    pthread_attr_init(&attr);
    if((err = pthread_getschedparam(pthread_self(), &Polisy, &schedparam)))
    {
        goto errmsg;
    }
    if((err = pthread_attr_setdetachstate(&attr,
            PTHREAD_CREATE_DETACHED)))
    {
        goto errmsg;
    }
    if((err = pthread_attr_setinheritsched(&attr,
            PTHREAD_EXPLICIT_SCHED)))
    {
        goto errmsg;
    }
    if((err = pthread_attr_setschedpolicy(&attr, SCHED_FIFO)))
    {
        goto errmsg;
    }
    schedparam.sched_priority = Prio;
    if((err = pthread_attr_setschedparam(&attr, &schedparam)))
    {
        goto errmsg;
    }
    if ((err = pthread_create(thread, &attr, (*start_routine),(void *) 0)))
    {
        goto errmsg;
    }
#ifdef DEBUG

	printf("AddThread FINISH  OK !!!");
#endif
    return;
    errmsg: printf("AddThread ERROR  INIT #%d", err);
    return;

}





#define PERIOD100  10000000
#define PERIOD50  20000000

void StartTimers(void)
	{
    struct itimerspec timeval;
  int err=0;

  int flag = 0;
	    timeval.it_interval.tv_sec = 0; /* no periodic timer - only once */
	    timeval.it_interval.tv_nsec = PERIOD100;
	    timeval.it_value.tv_sec = 0; /* */
	    timeval.it_value.tv_nsec =PERIOD100;
	    if((err = timer_settime(timer100, flag, &timeval, NULL)) != 0)
	    {
	        printf(
	                "\n<StartTimers> timer100 Error timer_settime завершение прогр Код ошибки = %d\n",
	                err);
	        exit(-1);
	    }


	    timeval.it_interval.tv_sec = 0; /* no periodic timer - only once */
	    timeval.it_interval.tv_nsec = PERIOD50;
	    timeval.it_value.tv_sec = 0; /* */
	    timeval.it_value.tv_nsec =PERIOD50;
	    if((err = timer_settime(timer50, flag, &timeval, NULL)) != 0)
	    {
	        printf(
	                "\n<StartTimers> timer100 Error timer_settime завершение прогр Код ошибки = %d\n",
	                err);
	        exit(-1);
	    }



#ifdef DEBUG
		printf("\n  End Timers start \n");
#endif

}

int K=0;


int main() {

int Res=0;

 struct sigaction act;
Res=pthread_barrier_init(
                    &barrier,
                    0,
                    3 );

sigset_t set;
int sigw;
int Count=0;
struct sigaction action;

sigemptyset(&set);

sigaddset(&set,SIGNALTIMER100);

sigaddset(&set,SIGNALTIMER50);

act.__sa_un._sa_handler= SIG_DFL;

act.sa_flags =SA_SIGINFO;

sigaction(SIGNALTIMER100, &act, NULL);

sigaction(SIGNALTIMER50, &act, NULL);

sigprocmask(SIG_BLOCK, &set, NULL);//


AddThread(&thread100,40,Thread100);

AddThread(&thread50,39,Thread50);




StartTimers();
pthread_barrier_wait(&barrier );
return EXIT_SUCCESS;
}
