How can I monitor all threads in the process to know each time witch process invoke to `write` syscall during 3 seconds.

For that, I using `ptrace` and attach to all threads in spesific process , define a timeout for threads that not using syscall.

here is the C example for code
Code:
    #include <stdio.h>
    #include <unistd.h>
    #include <errno.h>
    #include <stdlib.h>
    #include <dirent.h>
    #include <sys/wait.h>
    #include <sys/ptrace.h>
    #include <sys/syscall.h>
    #include <signal.h>
    #include <sys/reg.h>
    #include <sys/types.h>
    #include <string.h>
    
    volatile int timeout_g =0;
    volatile int stop_loop_g = 0;
    
    struct Node
    {
    
        void  *data;
    
        struct Node *next;
    };
    
    
    void push(struct Node** head_ref, void *new_data, size_t data_size)
    {
        struct Node* new_node = (struct Node*)malloc(sizeof(struct Node));
    
        new_node->data  = malloc(data_size);
        new_node->next = (*head_ref);
    
        int i;
        for (i=0; i<data_size; i++)
            *(char *)(new_node->data + i) = *(char *)(new_data + i);
    
        (*head_ref)    = new_node;
    }
    
    struct Node* get_tid_list(int pid)
    {
        struct Node* tids_list = NULL;
        static const char task_path[] = "/proc/%d/task";
        char procdir[sizeof(task_path)+sizeof(int) *3];
        DIR * dir;
        int tid;
        if(sprintf(procdir, task_path, pid)>0 && ( dir = opendir(procdir))!= NULL)
        {
            struct dirent *de;
            while((de = readdir(dir))!=NULL)
            {
                if(de->d_fileno ==0)
                    continue;
                char dummy ;
                if (sscanf(de->d_name, "%d%c" , &tid, &dummy)!=1)
                {
                    continue;
                }
    
                push (&tids_list, &tid, sizeof(int));
            }
        }
        return tids_list;
    }

    int wait_signal_or_timeout (int tid)
    {
        struct timespec timeout;
        timeout.tv_sec = 2;
        timeout.tv_nsec =0;
        sigset_t set;
        sigemptyset(&set);
        sigaddset(&set, SIGCHLD);
        sigaddset(&set, SIGINT);
        sigprocmask(SIG_BLOCK, & set , NULL);
        int ret = sigtimedwait(&set , NULL, &timeout);
    
        if(ret == SIGCHLD)
        {
    
            goto exit;
        }
        if(ret == SIGINT)
        {
            stop_loop_g = 1;
    
            goto exit;
        }
        if(errno == EAGAIN)
        {
            timeout_g = 1 ;
    
            goto exit;
        }
        //printf("error , tid = %d \n",tid);
        printf("error , ret= %d  , errno = %s\n",ret, strerror(errno));
    
    
        exit:
            sigemptyset(&set);
            sigprocmask(SIG_SETMASK, &set, NULL);
            if(timeout_g  || stop_loop_g)
                return -1;
            else
                return 0;
    }
    void main(int argv, char *argc[])
    {
    
        int pid = atoi(argc[1]);
    
        int status ;
        struct Node* tids_list = get_tid_list(pid);
    
        while(tids_list != NULL && !stop_loop_g)
        {
    
            int tid = *(int*)tids_list->data;
            //printf("tid = %d \n",tid);
            if(ptrace(PTRACE_ATTACH, tid, NULL,NULL) == -1 )
            {
                printf("error attach tid = %d \n", tid );
                tids_list = tids_list->next;
                continue;
            }
            if(waitpid(tid, &status, __WALL)==-1)
            {
                printf("error waitpid tid = %d \n", tid );
                tids_list = tids_list->next;
                continue;
            }
            timeout_g = 0;
            time_t finish_time = time(NULL) +3;//check during 3 sec.
            int flag =0;
            int  use_syscall=0;
            while ((long)time(NULL) -(long)finish_time <0 && !timeout_g)
            {
                if(ptrace(PTRACE_SYSCALL, tid, NULL, NULL) == -1)
                {
                    printf("error. tid = %d .\n",tid);
                    break;
                }
                if(wait_signal_or_timeout(tid) ==-1)
                    break;
    
                if(flag ==0)//enter syscall
                {
                    flag = 1;
                    int command = ptrace(PTRACE_PEEKUSER,tid, 8 * ORIG_RAX,NULL);
                    if(command == SYS_write)
                    {
                        use_syscall =1;
                        printf("tid = %d , call to WRITE syscall = %d \n",tid, command);
    
                    }
                }
                else //exit from syscall
                {
                    flag = 0;
                }
            }
            if(use_syscall)
            {
                printf("tid = %d , use write syscall \n",tid);
            }
            else
            {
                printf("tid = %d , didn't use write syscall \n",tid);
            }
    
            if(ptrace(PTRACE_DETACH, tid, NULL , NULL) <0)
            {
                //can't detach from tid , maybe because tid not stop
    
                syscall(SYS_kill, tid , SIGSTOP); //send sigstop so we can detach from tid
                if(waitpid(tid , &status, __WALL) == -1)
                {
                    printf("error while send SIGSTOP \n");
                }
                if(ptrace(PTRACE_DETACH , tid, NULL , NULL) <0)
                {
                    printf("ERROR detach again ! \n");
                }
                syscall(SYS_kill, tid , SIGCONT);
            }
            tids_list = tids_list->next;
        }
    }
Here is test program

//compile with gcc -othreads threads.c -lpthread
Code:
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <unistd.h>  
    #include <pthread.h> 
      
    
    void * write_each_sec(void *vargp) 
    { 
        printf("start write_each_sec \n");
        while(1)
        {    
            sleep(1); 
            printf("a\n"    );
        }
        
        return NULL; 
    } 
      
    
    
    void * only_sleep(void *vargp) 
    { 
        printf("start only_sleep \n");
        while(1)
        {    
            sleep(1);
        }
        
        return NULL; 
    } 
     
    int main() 
    { 
        pthread_t thread_id[30]; 
        int i ;
        for(i= 0; i<30;i++)
        {
            if(i%2==0)
                pthread_create(thread_id[i], NULL, write_each_sec, NULL); 
            else
                pthread_create(&thread_id[i], NULL, only_sleep, NULL); 
        }
        for(i= 0; i<30;i++)
        {
            pthread_join(thread_id[i], NULL);
        }
       

    }
Test program create half threads that using write syscall and half threads that not using write syscall.

My code works well but it has two issues:

For now the code check those threads serially but not concurrency,How can I change this code to attach and monitor all threads concurrency ?