POSIX timer with sigev_notify = SIGEV_THREAD_ID method
<p>In a multithreaded scenario, I am trying to implement a POSIX timer in which on timer expiration the next thread of the same process should be awakened (at a time only one thread is running and all others are in block state).
In the timer, I am using <em>sigev_notify = SIGEV_THREAD_ID</em> as neither I want any handler to service the signal nor I want to create a new thread after the timer expiration .</p>

<pre><code>//Import
#define _GNU_SOURCE
#define _POSIX_C_SOURCE 199309
#include &lt;sched.h&gt;
#include &lt;unistd.h&gt;
#include &lt;sys/wait.h&gt;
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;pthread.h&gt;
#include &lt;unistd.h&gt;
#include &lt;signal.h&gt;
#include &lt;errno.h&gt;
#include &lt;semaphore.h&gt;
#include &lt;sys/stat.h&gt;
#include &lt;fcntl.h&gt;
#include &lt;syscall.h&gt;
#define NUM_THREADS 10

#define CLOCKID CLOCK_REALTIME

int ret;
//pthread_cond_t      condA[NUM_THREADS+1]  = PTHREAD_COND_INITIALIZER;
pthread_cond_t      condA  = PTHREAD_COND_INITIALIZER;
pthread_mutex_t     mutex  = PTHREAD_MUTEX_INITIALIZER;

sem_t sem[NUM_THREADS];
sem_t mute;

timer_t timer1;
pthread_t tid[NUM_THREADS];
int state = 0;
int thread_count = 1;
int arr_tid[NUM_THREADS];
struct itimerspec new_value, old_value;

struct sigaction action;
struct sigevent sevent;
sigset_t set;
int signum = SIGALRM;

void *threadA(void *data_)
{
    cpu_set_t my_set;        
    CPU_ZERO(&amp;my_set);       
    CPU_SET(2, &amp;my_set);     
    sched_setaffinity(0, sizeof(cpu_set_t), &amp;my_set);

    //struct itimerspec new_value, old_value;

    int i = 0, value;
    int sid;
    FILE *fp;
    fp=fopen("ipc.out","a");    

    long int loopNum;
    int turn = (intptr_t)data_;
    struct timespec tval_result, tval_result2;

    if(thread_count &lt; NUM_THREADS)
    {
        thread_count++;
        sid = syscall(SYS_gettid);
        arr_tid[turn] = sid;
        fprintf(fp,"thread_%d %d\n", turn, sid); 
        //printf("Blocked %d -&gt;%d\n", turn, thread_count );
        pthread_mutex_lock(&amp;mutex);
        pthread_cond_wait(&amp;condA, &amp;mutex);
        pthread_mutex_unlock(&amp;mutex);
    }
    else
    {
        arr_tid[turn] = syscall(SYS_gettid);
    }

    for (value = 0; value &lt; NUM_THREADS; ++value)
    {   
        printf("%d\n",arr_tid[value] );
    } 
    //printf("rpg\n");
    pthread_mutex_lock(&amp;mutex);
    pthread_cond_broadcast(&amp;condA);
    pthread_mutex_unlock(&amp;mutex);
    //printf("unblocked\n");
    fclose(fp); 

    if (turn &gt; 0)
        {
            if (sigwait (&amp;set, &amp;signum) == -1)
                perror ("sigwait");
            //sleep(1);
            //printf("thread %d is sleeping\n", turn);
        }
    while(1)
    {
        ret = sem_wait(&amp;sem[turn]);
        if (ret)
        {
            printf("Error in Sem Post\n");
        }
        //printf("this isn't the end of the world!!!\n");
        sevent.sigev_notify = SIGEV_THREAD_ID;
        sevent._sigev_un._tid = arr_tid[(turn+1)%10];
        sevent.sigev_signo = signum;

        sigemptyset(&amp;set);
        sigaddset(&amp;set, signum);
        sigprocmask(SIG_BLOCK, &amp;set, NULL);

        printf("Thread # -&gt; %d\n", turn);
        clock_gettime(CLOCKID, &amp;tval_result);
        do
        {
            clock_gettime(CLOCKID, &amp;tval_result2);  
        } while( (tval_result2.tv_sec - tval_result.tv_sec)*1000000000+(tval_result2.tv_nsec - tval_result.tv_nsec)&lt;=12000);       
               //printf("Timestamp : %ld %ld\n", tval_result2.tv_sec, tval_result2.tv_nsec);
       // printf("Before creating timer\n");

        new_value.it_interval.tv_sec = 0;
        new_value.it_interval.tv_nsec = 0;
        new_value.it_value.tv_sec = 0;
        new_value.it_value.tv_nsec = 15000;
        printf("next thread to be signalled %d\n", arr_tid[turn+1]);
        if (timer_settime (timer1, 0, &amp;new_value, NULL) == -1)
            perror ("timer_settime");
        printf("yy\n");
        ret = sem_post(&amp;sem[(state+1)%NUM_THREADS]);
        if (ret)
        {
            printf("Error in Sem Post\n");
        }
        state++; 
        //printf("yy\n");
        //sleep(1);
        if (sigwait (&amp;set, &amp;signum) == -1)
            perror ("sigwait");
    }
}

int main(int argc, char *argv[])
{
    int data = 0;
    int err, i;
    int sid = syscall(SYS_gettid);
    //struct itimerspec new_value, old_value;

    FILE *fp;
    fp=fopen("ipc.out","a");    
    fprintf(fp,"Mainthread %d\n",sid);  
    fclose(fp); 
    if (timer_create (CLOCK_REALTIME, &amp;sevent, &amp;timer1) == -1)
        perror ("timer_create");

    sem_init(&amp;sem[0], 0, 1); 
    //sem_init(&amp;sem[1], 0, 0); 
    //sem_init(&amp;sem[2], 0, 0); 
    for ( i = 1; i &lt; NUM_THREADS; ++i)
        {
            sem_init(&amp;sem[i], 0, 0); 
        }
    while(data &lt; NUM_THREADS)
    {
        //create our threads
        err = pthread_create(&amp;tid[data], NULL, threadA, (void *)(intptr_t)data);
        if(err != 0)
            printf("\ncan't create thread :[%s]", strerror(err));
        data++;
    }
    pthread_exit(NULL);
}
</code></pre>

<p><strong>Compilation:</strong> <em>$ gcc filename.c -lrt -lpthread</em></p>

<p>I have used semaphores to synchronize the threads so that threads execute in a particular sequence.</p>

<p>I am not getting the desired output. It should be like after 15 microseconds the timer should expire and next thread should be awakened but it's not happening. 
I have used <strong>sigwait()</strong> to block the threads. Are there any other alternatives to block a thread and awake them using a timer?
What are the signals that can be assigned in <strong>signum</strong>? Can I use pthread_cond_signal() instead of SIGALRM?</p>