cvs commit: src/sys/kern sched_4bsd.c
Julian Elischer
julian at elischer.org
Mon Jul 28 23:14:29 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-src
mailing list