/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * * Test that the running thread relinquish the processor until it again becomes * the head of its thread list. * * Steps: * 1. Set the policy to SCHED_FIFO. * 2. Launch as many processes as number CPU minus 1. These processses set * their priority to the max and block all but 1 processor. * 3. Launch a thread which increase a counter in a infinite loop. * 4. Launch a thread which call sched_yield() and check that the counter has * changed since the call. */ #define LINUX #ifdef LINUX #define _GNU_SOURCE #endif #include #include #include #include #include #include #include #include #include "posixtest.h" #ifdef BSD # include # include # include #endif #ifdef HPUX # include # include #endif #define LOOP 1000 /* Shall be >= 1 */ volatile int nb_call = 0; /* Get the number of CPUs */ int get_ncpu() { int ncpu = -1; /* This syscall is not POSIX but it should work on many system */ #ifdef _SC_NPROCESSORS_ONLN ncpu = sysconf(_SC_NPROCESSORS_ONLN); #else # ifdef BSD int mib[2]; size_t len = sizeof(ncpu); mib[0] = CTL_HW; mib[1] = HW_NCPU; sysctl(mib, 2, &ncpu, &len, NULL, 0); # else # ifdef HPUX struct pst_dynamic psd; pstat_getdynamic(&psd, sizeof(psd), 1, 0); ncpu = (int)psd.psd_proc_cnt; # endif /* HPUX */ # endif /* BSD */ #endif /* _SC_NPROCESSORS_ONLN */ return ncpu; } #ifdef LINUX int set_process_affinity(int cpu) { int retval = -1; cpu_set_t cpu_mask; CPU_ZERO(&cpu_mask); if (cpu >= 0 && cpu <= CPU_SETSIZE) { CPU_SET(cpu, &cpu_mask); } else { fprintf (stderr, "Wrong cpu id: %d\n", cpu); return -1; } //#ifndef P2_SCHED_SETAFFINITY retval = sched_setaffinity(0, sizeof(cpu_mask), &cpu_mask); //#else // retval = sched_setaffinity(0, &cpu_mask); //#endif if (retval == -1) perror("Error at sched_setaffinity()"); return retval; } int set_thread_affinity(int cpu) { int retval = -1; cpu_set_t cpu_mask; CPU_ZERO(&cpu_mask); if (cpu >= 0 && cpu <= CPU_SETSIZE) { CPU_SET(cpu, &cpu_mask); } else { fprintf (stderr, "Wrong cpu id: %d\n", cpu); return -1; } //#ifndef P2_PTHREAD_SETAFFINITY retval = pthread_setaffinity_np(pthread_self(), sizeof(cpu_mask), &cpu_mask); //#else // retval = pthread_setaffinity_np(pthread_self(), &cpu_mask); //#endif if (retval != 0) fprintf (stderr, "Error at pthread_setaffinity_np():\n"); return retval; } #endif void * runner(void * arg) { int i=0, nc; long result = 0; #ifdef LINUX set_thread_affinity(*(int *)arg); fprintf(stderr, "%ld bind to cpu: %d\n", (long)pthread_self(), *(int*)arg); #endif for(;i