4

I'm particularly interesting in doing this on Linux, regarding Java programs. There are already a few questions that say you have no control from Java, and some RFEs closed by Sun/Oracle.

If you have access to source code and use a low-level language, you can certainly make the relevant system calls. However, sand-boxed systems - possibly without source code - present more of a challenge. I would have thought that a tool to set this per-process or an kernel parameter are able to control this from outside the parent process. This is really what I'm after.

I understand the reason why this is the default. It looks like some version of Windows may allow some control of this, but most do not. I was expecting Linux to allow control of it, but seems like it's not an option.

Sam Brightman
  • 2,831
  • 4
  • 36
  • 38

2 Answers2

1

Provided you have sufficient privileges, you could simply call setaffinity before execing in the child. In other words, from

if (fork() == 0)
        execve("prog", "prog", ...);

move to use

/* simple example using taskset rather than setaffinity directly */
if (fork() == 0)
        execve("taskset", "taskset", "-c", "0-999999", ...);

[Of course using 999999 is not nice, but that can be substituted by a program which automatically determined the number of cpus and resets the affinity mask as desired.]

user562374
  • 3,817
  • 1
  • 22
  • 19
  • If you have a way to influence what child program is run (e.g. config file — it does not always need program source), you can do it. If it has neither, well, "wrong program to use" then ;-) – user562374 Jan 06 '11 at 03:38
1

What you could also do, is change the affinity of the child from the parent, after the fork(). By the way, I'm assuming you're on linux, some of this stuff, such as retrieving the number of cores with sysconf() will be different on different OS's and unix flavors.... The example here, gets the cpu of the parent process and tries to ensure all child processes are scheduled on a different core, in round robin.

/* get the number of cpu's */
numcpu = sysconf( _SC_NPROCESSORS_ONLN );

/* get our CPU */
CPU_ZERO(&mycpuset);
sched_getaffinity( getpid() , sizeof mycpuset , &mycpuset);

for(i=0 ; i < numcpu ; i++ )
{
    if(CPU_ISSET( i, &mycpuset))
    {
        mycpu = i;
        break;
    }
}

//...

while(1)
{
    //Some other stuff.....

    /* now the fork */    
    if((pid = fork()) == 0)
    {
       //do your child stuff
    }    

   /* Parent... can schedule child. */
   else
   {
   cpu = ++cpu % numcpu;
       if(cpu == mycpu)
           cpu = ++cpu % numcpu;
       CPU_ZERO(&mycpuset);
       CPU_SET(cpu,&mycpuset);
       /*set processor affinity*/
       sched_setaffinity(pid, sizeof mycpuset, &mycpuset );

       //any other father stuff
   }
}
truthbk
  • 31
  • 2
  • As for the other answer, this won't work in sandboxed environments (or - annoying but less problematic - without access to sourrce code). I'm looking for a way to do it from outside the process (kernel setting, taskset etc.). – Sam Brightman Feb 07 '11 at 15:39
  • 1
    @sam-brightman Maybe I didn't understand the question, but I really don't understand why **taskset** doesn't cut it for you. And if you want to do this programmatically, as explained by the notes section of the sched_affinity manpage: a child created via fork(2) inherits its parent's CPU affinity mask. The affinity mask is preserved across an execve(2). So if you want to do it launching a process via execve, that's possible too. Also, if you know the pid, sched_setaffinity will definitely allow you to set core affinity. Being on a sandbox (**chroot**) really shouldn't change anything. – truthbk Feb 22 '11 at 15:41