Skip to content

Commit

Permalink
Avoid looping forever if core pinning fails
Browse files Browse the repository at this point in the history
This is known to happen, under some circumstances, on Apple M1.

Plus code cleanup.

Closes rdicosmo#103
  • Loading branch information
IagoAbal committed Jul 5, 2021
1 parent f140dbc commit 7b8cbd9
Showing 1 changed file with 30 additions and 33 deletions.
63 changes: 30 additions & 33 deletions src/setcore_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,47 +18,44 @@ CAMLprim value numcores(value unit) {
return Val_int(numcores);
}

CAMLprim value setcore(value which) {
int numcores = sysconf( _SC_NPROCESSORS_ONLN );
int w = Int_val(which) % numcores; // stay in the space of existing cores
int setcorew(int w) {
#if HAVE_DECL_SCHED_SETAFFINITY
cpu_set_t cpus;
#endif
#if HAVE_MACH_THREAD_POLICY_H
cpu_set_t cpus;
CPU_ZERO(&cpus);
CPU_SET (w,&cpus);
//fprintf(stderr,"Trying to pin to cpu %d out of %d reported by the system\n",w,numcores);
return sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpus);
#elif HAVE_MACH_THREAD_POLICY_H
thread_affinity_policy_data_t affinityData;
affinityData.affinity_tag = w;
return thread_policy_set(mach_thread_self(),
THREAD_AFFINITY_POLICY,
&affinityData,
THREAD_AFFINITY_POLICY_COUNT);
#else
return 0; // fake success
#endif
}

CAMLprim value setcore(value which) {
int numcores = sysconf( _SC_NPROCESSORS_ONLN );
int w = Int_val(which) % numcores; // stay in the space of existing cores
int retcode;
int finished=0;
if (numcores <= 1) // only one core in the system, no need to attempt pinning
return Val_unit;
while (finished==0)
do
{
retcode = setcorew(w);
if(retcode != 0)
{
#if HAVE_DECL_SCHED_SETAFFINITY
CPU_ZERO(&cpus);
CPU_SET (w,&cpus);
//fprintf(stderr,"Trying to pin to cpu %d out of %d reported by the system\n",w,numcores);
retcode = sched_setaffinity(getpid(), sizeof(cpu_set_t), &cpus);
if(retcode != 0) {
fprintf(stderr,"Failed pinning to cpu %d, trying %d/2\n",w, w);
w=w/2;
}
else
#endif
#if HAVE_MACH_THREAD_POLICY_H
affinityData.affinity_tag = w;
retcode = thread_policy_set(mach_thread_self(),
THREAD_AFFINITY_POLICY,
&affinityData,
THREAD_AFFINITY_POLICY_COUNT);
if(retcode) {
fprintf(stderr,"MAC OS X: Failed pinning to cpu %d, trying %d/2\n",w, w);
w=w/2;
}
else
#endif
{ //fprintf(stderr,"Succeeded pinning to cpu %d\n",w);
finished=1;
}
fprintf(stderr,"Failed pinning to cpu %d, trying %d/2\n",w, w);
w=w/2;
}
else
{ //fprintf(stderr,"Succeeded pinning to cpu %d\n",w);
finished=1;
}
} while (finished==0 && w>0);
return Val_unit;
}

1 comment on commit 7b8cbd9

@rdicosmo
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for looking into this. It is difficult to follow the diff you proposed, though: there is code that is moved untouched in a separate subroutine, and it is not clear what the proposed change really is.
May you submit a separate PR with only the change in the logic, without the code reshuffling?

Please sign in to comment.