/* * this version uses pthread_setschedparam as a workaround of the * glibc bug, prints using stdio */ #include #include #include #include /* for sched_param.c */ #include /* --------------------------------------------- */ /* source from http://sources.redhat.com/ml/glibc-bugs/2004-05/msg00003.html */ #define LPRIO 1 #define MPRIO 2 #define HPRIO 3 void show_sched(void) { struct sched_param sp; int policy; const char *pstr; if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) { perror("pthread_getschedparam failed"); return; } switch(policy) { case SCHED_OTHER: pstr = "SCHED_OTHER"; break; case SCHED_FIFO: pstr = "SCHED_FIFO"; break; case SCHED_RR: pstr = "SCHED_RR"; break; default: pstr = "unknown"; } printf("thread id = 0x%lx, policy = %s, priority = %d\n", pthread_self(), pstr, sp.sched_priority); return; } void set_sched(int policy, int priority) { struct sched_param schedp; memset(&schedp, 0, sizeof(schedp)); schedp.sched_priority = priority; if (pthread_setschedparam(pthread_self(), policy, &schedp) != 0) perror("pthread_setschedparam failed"); } /* --------------------------------------------- */ void *low(void *arg) { set_sched(SCHED_FIFO, LPRIO); printf("LOW priority thread!!!\n"); return NULL; } struct medium_par_t { int policy; char *c; } mp1, mp2; void *medium(void *arg) { int i,j; struct medium_par_t *p = (struct medium_par_t *)arg; set_sched(p->policy, MPRIO); for (i=0; i<300; i++) { for (j=0; j<1000000; j++) ; printf(p->c); } return NULL; } void my_create(int policy) { pthread_t th1, th2, th3; pthread_attr_t medium_attr, low_attr; struct sched_param medium_policy, low_policy; pthread_attr_init(&medium_attr); pthread_attr_setschedpolicy(&medium_attr, policy); medium_policy.sched_priority = 2; pthread_attr_setschedparam(&medium_attr, &medium_policy); pthread_attr_init(&low_attr); pthread_attr_setschedpolicy(&low_attr, SCHED_FIFO); low_policy.sched_priority = 1; pthread_attr_setschedparam(&low_attr, &low_policy); mp1.policy = mp2.policy = policy; mp1.c = "."; mp2.c = "#"; pthread_create(&th1, &medium_attr, medium, (void *)&mp1); pthread_create(&th2, &medium_attr, medium, (void *)&mp2); pthread_create(&th3, &low_attr, low, NULL); pthread_attr_destroy(&medium_attr); pthread_attr_destroy(&low_attr); pthread_join(th1, NULL); pthread_join(th2, NULL); pthread_join(th3, NULL); } void *high(void *arg) { show_sched(); set_sched(SCHED_RR, HPRIO); show_sched(); /* first experiment: - two medium priority thread scheduled with RR - one low priority thread scheduled with FIFO */ my_create(SCHED_RR); /* second experiment: - two medium priority thread scheduled with FIFO - one low priority thread scheduled with FIFO */ my_create(SCHED_FIFO); return NULL; } int main() { pthread_t mythread; pthread_attr_t myattr; struct sched_param myparam; int err; int parameter; void *returnvalue; /* initializes the thread attribute */ pthread_attr_init(&myattr); pthread_attr_setschedpolicy(&myattr, SCHED_FIFO); myparam.sched_priority = 3; pthread_attr_setschedparam(&myattr, &myparam); err = pthread_create(&mythread, &myattr, high, (void *)¶meter); if (err) { perror("ERROR"); exit(1); } pthread_attr_destroy(&myattr); /* wait the end of the thread we just created */ pthread_join(mythread, &returnvalue); return 0; }