cvs commit: src/sys/kern sched_4bsd.c

Julian Elischer julian at elischer.org
Mon Jul 28 23:14:28 UTC 2008


John Baldwin wrote:
> On Monday 28 July 2008 04:39:21 pm John Baldwin wrote:
>> jhb         2008-07-28 20:39:21 UTC
>>
>>   FreeBSD src repository
>>
>>   Modified files:
>>     sys/kern             sched_4bsd.c 
>>   Log:
>>   SVN rev 180937 on 2008-07-28 20:39:21Z by jhb
>>   
>>   When choosing a CPU for a thread in a cpuset, prefer the last CPU that the
>>   thread ran on if there are no other CPUs in the set with a shorter per-CPU
>>   runqueue.

would this help teh case where we set up a cpu set with all CPUs?

in other words shouldn't we just drop the single cpu runqueue
and have this always turned on?

> 
> I used the test program below.  Prior to this change, the two child processes 
> bounced between the two CPUs constantly.  With this patch on an 
> otherwise-idle box, they only switched CPUs once after starting.  With ULE 
> they switch CPUs occasionally (once every few seconds) but not nearly as bad 
> as 4BSD before this patch (multiple switches per second).  Granted, this is a 
> very contrived test. :)
> 
> Note that I ran this on a 4-CPU box and used CPUs 2 and 3.  You can change 
> which CPUs are used by changing the 'cpus[]' array.  This is also quite x86 
> specific. :)
> 
> #include <sys/param.h>
> #include <sys/cpuset.h>
> #include <err.h>
> #include <stdio.h>
> #include <unistd.h>
> #include <machine/cpufunc.h>
> 
> int apic_ids[2];
> int cpus[2] = { 2, 3 };
> 
> int
> apic_id(void)
> {
>         u_int regs[4];
> 
>         do_cpuid(1, regs);
>         return (regs[1] >> 24);
> }
> 
> void
> check_id(pid_t pid, int *id)
> {
>         int new;
> 
>         new = apic_id();
>         if (*id == new)
>                 return;
>         printf("%d: moved from APIC ID %d to APIC ID %d\n", pid, *id, new);
>         *id = new;
> }
> 
> void
> child(void)
> {
>         int last_id;
>         pid_t pid;
>         int i;
> 
>         pid = getpid();
>         last_id = apic_id();
>         printf("%d: starting on APIC ID %d\n", pid, last_id);
>         for (;;) {
>                 for (i = 0; i < 10000000; i++)
>                         check_id(pid, &last_id);
>                 usleep(5);
>                 check_id(pid, &last_id);
>         }
> }
> 
> int
> main(int ac, char **av)
> {
>         cpuset_t set;
>         int i;
> 
>         for (i = 0; i < 2; i++) {
>                 CPU_ZERO(&set);
>                 CPU_SET(cpus[i], &set);
> 
>                 if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
>                     sizeof(set), &set))
>                         err(1, "cpuset_affinity(%d)", cpus[i]);
>                 apic_ids[i] = apic_id();
>                 printf("CPU%d has APIC ID %d\n", cpus[i], apic_ids[i]);
>         }
> 
>         CPU_ZERO(&set);
>         for (i = 0; i < 2; i++)
>                 CPU_SET(cpus[i], &set);
>         if (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_PID, -1,
>             sizeof(set), &set))
>                 err(1, "cpuset_affinity");
> 
>         for (i = 0; i < 2; i++) {
>                 switch (fork()) {
>                 case -1:
>                         err(1, "fork");
>                 case 0:
>                         break;
>                 default:
>                         child();
>                 }
>         }
> 
>         for (i = 0; i < 2; i++)
>                 wait(NULL);
> 
>         return (0);
> }
> 



More information about the cvs-all mailing list