/* TEST rig for sched routines. The pthread stuff is still here * because I want (some day :]) To implement the pthread per thread schedule functions */ #include #include #include #include #if 0 #ifndef PTHREAD_CANCEL_ASYNCHRONOUS #error undefined PTHREAD_CANCEL_ASYNCHRONOUS #endif #ifndef PTHREAD_CANCEL_ENABLE #error undefined PTHREAD_CANCEL_ENABLE #endif #ifndef PTHREAD_CANCEL_DEFERRED #error undefined PTHREAD_CANCEL_DEFERRED #endif #ifndef PTHREAD_CANCEL_DISABLE #error undefined PTHREAD_CANCEL_DISABLE #endif #ifndef PTHREAD_CANCELED #error undefined PTHREAD_CANCELED #endif #endif #if HARD_CODE #ifndef PTHREAD_COND_INITIALIZER #error undefined PTHREAD_COND_INITIALIZER #endif #endif #if 0 #ifndef PTHREAD_CREATE_DETACHED #error undefined PTHREAD_CREATE_DETACHED #endif #ifndef PTHREAD_CREATE_JOINABLE #error undefined PTHREAD_CREATE_JOINABLE #endif #ifndef PTHREAD_EXPLICIT_SCHED #error undefined PTHREAD_EXPLICIT_SCHED #endif #ifndef PTHREAD_INHERIT_SCHED #error undefined PTHREAD_INHERIT_SCHED #endif #ifndef PTHREAD_MUTEX_DEFAULT #error undefined PTHREAD_MUTEX_DEFAULT #endif #ifndef PTHREAD_MUTEX_ERRORCHECK #error undefined PTHREAD_MUTEX_ERRORCHECK #endif #ifndef PTHREAD_MUTEX_NORMAL #error undefined PTHREAD_MUTEX_NORMAL #endif #ifndef PTHREAD_MUTEX_INITIALIZER #error undefined PTHREAD_MUTEX_INITIALIZER #endif #ifndef PTHREAD_MUTEX_RECURSIVE #error undefined PTHREAD_MUTEX_RECURSIVE #endif #ifndef PTHREAD_ONCE_INIT #error undefined PTHREAD_ONCE_INIT #endif #ifndef PTHREAD_PRIO_INHERIT #error undefined PTHREAD_PRIO_INHERIT #endif #ifndef PTHREAD_PRIO_NONE #error undefined PTHREAD_PRIO_NONE #endif #ifndef PTHREAD_PRIO_PROTECT #error undefined PTHREAD_PRIO_PROTECT #endif #endif #ifndef PTHREAD_PROCESS_SHARED #error undefined PTHREAD_PROCESS_SHARED #endif #ifndef PTHREAD_PROCESS_PRIVATE #error undefined PTHREAD_PROCESS_PRIVATE #endif #if 0 #ifndef PTHREAD_RWLOCK_INITIALIZER #error undefined PTHREAD_RWLOCK_INITIALIZER #endif #ifndef PTHREAD_SCOPE_PROCESS #error undefined PTHREAD_SCOPE_PROCESS #endif #ifndef PTHREAD_SCOPE_SYSTEM #error undefined PTHREAD_SCOPE_SYSTEM #endif #endif typedef struct datastruct { pthread_cond_t cond; pthread_mutex_t mutex; int testvalue; } datastruct_t; static int trv=1; void *threadfunc(void *argument) { datastruct_t *mydata=argument; /* get the mutex */ if (pthread_mutex_lock(&mydata->mutex)) return &trv; /* loop on the value */ while (mydata->testvalue>0) { /* set the variable value */ if (mydata->testvalue>0) mydata->testvalue--; /* tell any waiting threads */ if (pthread_cond_signal(&mydata->cond)) return &trv; /* release the mutex so the waiting (and now signaled thread) can get the lock */ if (pthread_mutex_unlock(&mydata->mutex)) return &trv; /* let other threads do some stuff */ sched_yield(); /* get the mutex again so we can update the value */ if (pthread_mutex_lock(&mydata->mutex)) return &trv; } /* we have the mutex here */ if (pthread_mutex_unlock(&mydata->mutex)) return &trv; trv=0; return &trv; } main(void) { datastruct_t data; pthread_condattr_t condattr; pthread_t thread; int rv,pshared, policy, min_pri, max_pri; struct timespec time_quantum; struct sched_param schedparam; rv = pthread_condattr_init(&condattr); printf("condattr init %d\n",rv); rv = pthread_condattr_getpshared(&condattr, &pshared); printf("condattr getpshared %d, pshared %d\n",rv,pshared); rv = pthread_condattr_setpshared(&condattr, PTHREAD_PROCESS_SHARED); printf("condattr setpshared %d\n"); rv = pthread_condattr_getpshared(&condattr, &pshared); printf("condattr getpshared %d, pshared %d\n",rv,pshared); rv = pthread_cond_init(&data.cond, &condattr); printf("cond init %d\n",rv); rv = pthread_mutex_init(&data.mutex, NULL); printf("mutex init %d\n",rv); data.testvalue=150; rv = pthread_create(&thread, NULL, threadfunc, &data); printf("create thread %d\n",rv); /* get the mutex */ printf("locking mutex\n"); rv = pthread_mutex_lock(&data.mutex); printf("lock mutex %d\n",rv); /* we now have 1 running thread and 1 paused thread... so lets test scheduler stuff now */ #ifndef SCHED_FIFO #error no FIFO #endif #ifndef SCHED_RR #error no RoundRobin #endif #ifndef SCHED_OTHER #error no Other #endif #if notes int sched_get_priority_max(int policy); /* max priority for policy */ int sched_get_priority_min(int policy); /* min priority for policy */ int sched_getparam(pid_t pid, struct sched_param *param); /* get sched params for process*/ int sched_getscheduler(pid_t pid); /* get the scheduler for pid */ int sched_rr_get_interval(pid_t pid, struct timespec *interval); /* get the time quantum for pid */ int sched_setparam(pid_t, const struct sched_param *); /* set the scheduling parameters */ int sched_setscheduler(pid_t, int, const struct sched_param *); /* set the scheduler */ int sched_yield(void); /* yield the cpu */ #endif /* clear the error code */ errno =0; policy = sched_getscheduler(0); if (policy == -1 && errno) switch (errno) { case ENOSYS:printf("get scheduler not implemented (%d)\n",policy);break; case EPERM:printf("get scheduler no access (%d)\n",policy);break; case ESRCH:printf("get scheduler no process (%d)\n",policy);break; default:printf("get scheduler returned an unexpected errno\n",errno);break; } else switch(policy) { case SCHED_FIFO:printf("get scheduler returned FIFO (%d)\n",policy);break; case SCHED_RR:printf("get scheduler returned RR (%d)\n",policy);break; case SCHED_OTHER:printf("get scheduler returned OTHER (%d)\n",policy);break; default:printf("get scheduler returned an unexpected value (%d)\n",policy);break; } /* clear the error code */ errno =0; rv = sched_getparam(0, &schedparam); if (rv==-1) printf ("get param returned error %d\n",errno); else printf ("get param returned priority %d\n",schedparam.sched_priority); min_pri=sched_get_priority_min(policy); max_pri=sched_get_priority_max(policy); switch(min_pri) { case EINVAL:printf("min priority returned EINVAL (%d) - invalid policy\n",min_pri);min_pri=0;break; case ENOSYS:printf("min priority returned ENOSYS (%d) - not implemented\n", min_pri);min_pri=0;break; default:printf("min priority returned %d\n", min_pri);break; } switch(max_pri) { case EINVAL:printf("max priority returned EINVAL (%d) - invalid policy\n",max_pri);max_pri=0;break; case ENOSYS:printf("max priority returned ENOSYS (%d) - not implemented\n", max_pri);max_pri=0;break; default:printf("max priority returned %d\n", max_pri);break; } errno =0; rv = sched_rr_get_interval(0, &time_quantum); if (rv==-1 && errno) printf("rr_get_interval returned error %d\n",errno); else printf("rr_get_interval %d\n",rv); /* set priority to highest */ schedparam.sched_priority=max_pri; rv = sched_setparam(0, &schedparam); if (rv==-1) printf("sched set param returned error %d\n",errno); else { printf("set priority to highest(%d), please check now and press RETURN\n",max_pri); getc(stdin); } /* set priority to lowest */ schedparam.sched_priority=min_pri; rv = sched_setparam(0, &schedparam); if (rv==-1) printf("sched set param returned error %d\n",errno); else { printf("set priority to lowest(%d), please check now and press RETURN\n",min_pri); getc(stdin); } /* try changing scheduling priority */ while (data.testvalue > 0) { // printf("waiting on the condition\n"); rv = pthread_cond_wait(&data.cond, &data.mutex); // printf("cond wait %d\n",rv); printf("testvalue %d--",data.testvalue--); } rv = pthread_mutex_unlock(&data.mutex); printf("\nmutex unlock %d\n",rv); //rv = 0; //while (!rv) { ///* this is bad programming! busy loop until the thread cannot be found */ //rv = pthread_cancel(&thread); //} //printf("thread has exited\n"); rv = pthread_mutex_destroy(&data.mutex); printf("mutex destroy %d\n",rv); rv = pthread_cond_destroy(&data.cond); printf("cond destroy %d\n",rv); #if HARD_CODE rv = pthread_cond_destroy(&cond2); printf("cond2(default init) destroy %d\n",rv); #endif rv = pthread_condattr_destroy(&condattr); printf("condattr destroy %d\n",rv); return 0; }