/** * The original version of the program comes from Linux man page * man pthread_attr_init * * This is a revised, simplified version to show the basics of * thread attributes */ #include #include #include #include #include #define DEFAULT_STACK_SIZE 0x200000 /* 2 MB */ #define handle_error_en(en, msg) \ { errno = en; perror(msg); exit(EXIT_FAILURE); } void get_show_sched(pthread_attr_t *attr, char * prefix) { int s, i; struct sched_param sp; printf("Demonstrate get and set of scheduling parameters.\n"); printf("=== retrieval scheduling default policy ===\n"); s = pthread_attr_getschedpolicy(attr, &i); if (s != 0) handle_error_en(s, "pthread_attr_getschedpolicy and priority"); printf("%sScheduling policy = %s\n", prefix, (i == SCHED_OTHER) ? "SCHED_OTHER" : (i == SCHED_FIFO) ? "SCHED_FIFO" : (i == SCHED_RR) ? "SCHED_RR" : "???"); s = pthread_attr_getschedparam(attr, &sp); if (s != 0) handle_error_en(s, "pthread_attr_getschedpolicy"); printf("%sScheduling priority = %d\n", prefix, sp.sched_priority); printf("=== change scheduling parameters ===\n"); printf("a. set scheduling policy to be RR (round-robin) ...\n"); printf("b. lower scheduling priority by 1 (less preferrable)...\n"); i = SCHED_RR; s = pthread_attr_setschedpolicy(attr, i); if (s != 0) handle_error_en(s, "pthread_attr_setschedpolicy"); s = pthread_attr_getschedpolicy(attr, &i); if (s != 0) handle_error_en(s, "pthread_attr_getschedpolicy"); sp.sched_priority ++; s = pthread_attr_setschedparam(attr, &sp); if (s != 0) handle_error_en(s, "pthread_attr_setschedpolicy"); s = pthread_attr_getschedparam(attr, &sp); if (s != 0) handle_error_en(s, "pthread_attr_getschedpolicy"); printf("%sScheduling policy = %s\n", prefix, (i == SCHED_OTHER) ? "SCHED_OTHER" : (i == SCHED_FIFO) ? "SCHED_FIFO" : (i == SCHED_RR) ? "SCHED_RR" : "???"); printf("%sScheduling priority = %d\n", prefix, sp.sched_priority); } void get_show_stack(pthread_attr_t *attr, char *prefix) { int s; size_t v; void *stkaddr; printf("Demonstrate get and set of stack parameters.\n"); printf("=== retrieval stack parameters ===\n"); s = pthread_attr_getstack(attr, &stkaddr, &v); if (s != 0) handle_error_en(s, "pthread_attr_getschedpolicy"); printf("%sStack address = %p\n", prefix, stkaddr); printf("%sStack size = 0x%x bytes\n", prefix, v); printf("=== reset stack size (double it) ===\n"); v *= 2; // double the size s = pthread_attr_setstack(attr, stkaddr, v); s = pthread_attr_getstack(attr, &stkaddr, &v); if (s != 0) handle_error_en(s, "pthread_attr_getschedpolicy"); printf("%sStack address = %p\n", prefix, stkaddr); printf("%sStack size = 0x%x bytes\n", prefix, v); } void display_pthread_attr(pthread_attr_t *attr, char *prefix) { /* get, set, and show sheduling policy and parameters */ get_show_sched(attr, prefix); /* get, set, and show stack parameters */ get_show_stack(attr, prefix); } static void * thread_start(void *arg) { int s; pthread_attr_t gattr; /* pthread_getattr_np() is a non-standard GNU extension that retrieves the attributes of the thread specified in its first argument */ s = pthread_getattr_np(pthread_self(), &gattr); if (s != 0) handle_error_en(s, "pthread_getattr_np"); printf("Thread attributes for thread %u:\n", pthread_self()); display_pthread_attr(&gattr, "\t"); exit(EXIT_SUCCESS); /* Terminate all threads */ } int main(int argc, char *argv[]) { pthread_t thr; pthread_attr_t attr; pthread_attr_t *attrp; /* NULL or &attr */ int s; void *sp; attrp = NULL; s = pthread_create(&thr, attrp, &thread_start, NULL); if (s != 0) handle_error_en(s, "pthread_create"); pause(); /* Terminates when other thread calls exit() */ }