test_thdprio.cpp

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <sys/prctl.h>


//#define TEST_SAME_PRIO
//#define TEST_DIFF_PRIO
#define TEST_OTHER_PRIO

//#define TEST_SCHD_OTHER
//#define TEST_SCHD_RR
//#define TEST_SCHD_FIFO
//#define TEST_SCHD_MIXED_OTHER_RR
//#define TEST_SCHD_MIXED_OTHER_FIFO
//#define TEST_SCHD_MIXED_OTHER_RR_FIFO
//#define TEST_SCHD_MIXED_OTHER_RR_FIFO2
#define TEST_SCHD_MIXED_FIFO_EMPTY_RR
//#define TEST_SCHD_MIXED_RR_FIFO


#define CREATE_WAIT 100
#define THREAD_LOOP 5000000
#define DEF_PRIO 30


pthread_t ppid0, ppid1, ppid2, ppid3, ppid4;
pthread_attr_t attr0, attr1, attr2, attr3, attr4;
unsigned long cnt0, cnt1, cnt2, cnt3, cnt4;
int prio0, prio1, prio2, prio3, prio4;
int policy0, policy1, policy2, policy3, policy4;



void init_prio(void) 
{
#if defined(TEST_SAME_PRIO)
    prio0 =  prio1 = prio2 = prio3 = prio4 = 11;

#elif defined(TEST_DIFF_PRIO)
    prio0 = DEF_PRIO - 20;
    prio1 = DEF_PRIO - 10;
    prio2 = DEF_PRIO;
    prio3 = DEF_PRIO + 10;
    prio4 = DEF_PRIO + 20;

#endif
}


void init_policy(void) 
{
#if defined(TEST_SCHD_OTHER)
    policy0 = policy1 = policy2 = policy3 = policy4 = SCHED_OTHER;

#elif defined(TEST_SCHD_RR)
    policy0 = policy1 = policy2 = policy3 = policy4 = SCHED_RR;

#elif defined(TEST_SCHD_FIFO)
    policy0 = policy1 = policy2 = policy3 = policy4 = SCHED_FIFO;

#elif defined(TEST_SCHD_MIXED_OTHER_RR)
    policy0 = policy1 = policy2 = policy3 = SCHED_OTHER;
    policy4 = SCHED_RR;

#elif defined(TEST_SCHD_MIXED_OTHER_FIFO)
    policy0 = policy1 = SCHED_FIFO;
    policy2 = policy3 = policy4 = SCHED_OTHER;

#elif defined(TEST_SCHD_MIXED_OTHER_RR_FIFO)
    policy0 = policy1 = policy2 = SCHED_OTHER;
    policy3 = SCHED_FIFO;
    policy4 = SCHED_RR;

    prio0 = prio1 = prio2 = DEF_PRIO;
    prio3 = DEF_PRIO + 10;
    prio4 = DEF_PRIO + 20;

#elif defined(TEST_SCHD_MIXED_OTHER_RR_FIFO2)
        policy0 = policy1 = SCHED_OTHER;
        policy2 = SCHED_RR;
        policy3 = SCHED_RR;
        policy4 = SCHED_FIFO;

        prio0 = prio1 = DEF_PRIO;
        prio2 = DEF_PRIO;
        prio3 = DEF_PRIO + 10;
        prio4 = DEF_PRIO + 20;

#elif defined(TEST_SCHD_MIXED_FIFO_EMPTY_RR)
    policy0 = policy1 = SCHED_OTHER;
    policy2 = SCHED_FIFO;
    policy3 = SCHED_RR;
    policy4 = SCHED_FIFO;

    prio0 = prio1 = DEF_PRIO + 10;
    prio2 = DEF_PRIO;
    prio3 = DEF_PRIO + 10;
    prio4 = DEF_PRIO + 20;

#elif defined(TEST_SCHD_MIXED_RR_FIFO)
    policy0 = policy1 = policy2 = SCHED_RR;
    policy3 =  policy4 = SCHED_FIFO;

    prio0 = DEF_PRIO - 20;
    prio1 = DEF_PRIO + 10;
    prio2 = DEF_PRIO;
    prio3 = DEF_PRIO - 10;
    prio4 = DEF_PRIO + 20;

#endif
}

void set_thread_name(const char* n)
{
    prctl(PR_SET_NAME,n,0,0,0);
}

void get_thread_name(char* n)
{
    prctl(PR_GET_NAME,n,0,0,0);
}

void show_thread_priority_range(int policy)
{        
    int max_priority = sched_get_priority_max(policy);  
    int min_priority = sched_get_priority_min(policy);      

    switch ( policy )
        {
        case SCHED_FIFO:
                printf("policy = SCHED_FIFO, ");
                break;

        case SCHED_RR:
                printf("policy = SCHED_RR, ");
                break;

        case SCHED_OTHER:
                printf("policy = SCHED_OTHER, ");
                break;

        default:
                printf("policy = UNKNOWN, ");
                break;
        }

    printf("max_priority = %d, ", max_priority);
    printf("min_priority = %dn", min_priority);
}



void getinfo(const char * i)
{
    int policy;
    pthread_attr_t attr;
    struct sched_param param;
    char n[32];
    char schd[12];
    char buf[64];

    get_thread_name(n);

    pthread_attr_init(&attr);    
    pthread_attr_getschedpolicy(&attr, &policy);
    pthread_getschedparam(pthread_self(),&policy,&param);

    if(policy == SCHED_OTHER)
        sprintf(schd, "SCHED_OTHER");
    else if(policy == SCHED_RR)
        sprintf(schd, "SCHED_RR");
    else if(policy == SCHED_FIFO)
        sprintf(schd, "SCHED_FIFO");
    else
        sprintf(schd, "UNKOWN");


    memset(buf, 0, sizeof(buf));
    sprintf(buf, "%s: %s(prio = %d), [%s], Thread loop: %lu, %lu, %lu, %lu, %lun", n, schd, param.sched_priority, i, cnt0, cnt1, cnt2, cnt3, cnt4);
    printf("%s", buf);
}


void set_thread_attr(int idx, pthread_attr_t* attr, int policy, int priority)
{
    char schd[12];
    struct sched_param param; 
    param.sched_priority = priority; 

    pthread_attr_init(attr);
    pthread_attr_setscope(attr, PTHREAD_SCOPE_PROCESS);
    pthread_attr_setschedpolicy(attr, policy);
    pthread_attr_setschedparam(attr,&param);
    pthread_attr_setinheritsched(attr,PTHREAD_EXPLICIT_SCHED);    


    if(policy == SCHED_OTHER)
        sprintf(schd, "SCHED_OTHER");
    else if(policy == SCHED_RR)
        sprintf(schd, "SCHED_RR");
    else if(policy == SCHED_FIFO)
        sprintf(schd, "SCHED_FIFO");
    else
        sprintf(schd, "UNKOWN");

    printf("set thread[%d]: policy: %s, priority = %dn", idx, schd, priority);
}

void wait(int r)
{
    printf("wait %d loopsn", r);
    while(--r >= 0);    
}

void threadloop(int idx, unsigned long x, unsigned long y, unsigned long& count)
{
    unsigned long i = 0, j = 0;

    count = 0;
    for(i=1;i<x;i++)
        for(j=1;j<y;j++)
            if(j%2500 == 0) {
                count++;
                            printf("%d ", idx);
                     }
}

void threadloop_with_sleep(int idx, unsigned long x, unsigned long y, unsigned long& count)
{
    unsigned long i = 0, j = 0;

    count = 0;
    for(i=1;i<x;i++)
        for(j=1;j<y;j++)
            if(j%2500 == 0) {
                count++;                    
                            printf("%d ", idx);
                            if(count == 8000) {
                                printf("thread%d, count = %d, before sleepn", idx, count);
                                usleep(1000);
                                printf("thread%d, count = %d, exit sleepn", idx, count);
                            }
                     }
}


void* Thread0(void* p)
{
    set_thread_name(__func__);

    sleep(1);
    getinfo("start");

    threadloop(0, 10, THREAD_LOOP, cnt0);

    getinfo("exit");
}

void* Thread1(void* p)
{
    set_thread_name(__func__);

    sleep(1);
    getinfo("start");

    threadloop(1, 10, THREAD_LOOP, cnt1);

    getinfo("exit");
}

void* Thread2(void* p)
{
    set_thread_name(__func__);

    sleep(1);
    getinfo("start");

    threadloop(2, 10, THREAD_LOOP, cnt2);

    getinfo("exit");
}

void* Thread3(void* p)
{
    set_thread_name(__func__);

    sleep(1);
    getinfo("start");

       #ifdef TEST_SCHD_MIXED_FIFO_EMPTY_RR
           threadloop_with_sleep(3, 10, THREAD_LOOP, cnt3);
       #else
        threadloop(3, 10, THREAD_LOOP, cnt3);
       #endif

    getinfo("exit");
}

void* Thread4(void* p)
{
    set_thread_name(__func__);

    sleep(1);
    getinfo("start");

    threadloop(4, 10, THREAD_LOOP, cnt4);

    getinfo("exit");
}

int main()
{
    int i;
    i = getuid();
    if(i==0)
        printf("The current user is rootn");
    else
        printf("The current user is not rootn");

    printf("current priority range: n");
    show_thread_priority_range(SCHED_OTHER);
    show_thread_priority_range(SCHED_FIFO);
    show_thread_priority_range(SCHED_RR);
    sleep(3);

    printf("init thread property:n");
    init_prio();
    init_policy();
    set_thread_attr(0, &attr0, policy0, prio0);
    set_thread_attr(1, &attr1, policy1, prio1);
    set_thread_attr(2, &attr2, policy2, prio2);
    set_thread_attr(3, &attr3, policy3, prio3);
    set_thread_attr(4, &attr4, policy4, prio4);

    pthread_create(&ppid0,&attr0,Thread0,NULL);        
    wait(CREATE_WAIT); 
    pthread_create(&ppid1,&attr1,Thread1,NULL);        
    wait(CREATE_WAIT);
    pthread_create(&ppid2,&attr2,Thread2,NULL);        
    wait(CREATE_WAIT);
    pthread_create(&ppid3,&attr3,Thread3,NULL);        
    wait(CREATE_WAIT*5);
    pthread_create(&ppid4,&attr4,Thread4,NULL);        

    pthread_join(ppid0,NULL);
    pthread_join(ppid1,NULL);
    pthread_join(ppid2,NULL);
    pthread_join(ppid3,NULL);
    pthread_join(ppid4,NULL);

    pthread_attr_destroy(&attr0);
    pthread_attr_destroy(&attr1);
    pthread_attr_destroy(&attr2);
    pthread_attr_destroy(&attr3);
    pthread_attr_destroy(&attr4);

    printf(" >>>>>>>>>>>>>test over<<<<<<<<<<<<<<n");
    return 0;
}