Cómo evitar que un proceso C dependiente de la sincronización cambie de contexto

Cómo evitar que un proceso C dependiente de la sincronización cambie de contexto

Tenemos un proceso que es responsable de sondear el hardware en intervalos que dependen del tiempo. Nos gustaría dedicar un núcleo de CPU a este proceso. Por ejemplo, queremos que este proceso siga siendo ejecutable en todo momento.

Nuestro primer intento de resolver este problema fue el siguiente:

# Set process to highest priority
nice -n -20 cmd

# Set thread affinity in C for our hardware sampling thread
pthread_setaffinity_np(...)

Ambos pasos anteriores funcionan como se esperaba. Nuestro hilo permanece core3donde lo colocamos y niceestá -20arriba.

Cuando se vuelve a ejecutar ftracecomopor esta discusiónyeste problema, comúnmente vemos lo siguiente:

> cat trace | grep " 3)" | grep " => "
 3)  rhd_loc-2735  =>    <idle>-0   
 3)    <idle>-0    =>  rhd_loc-2735 
 3)  rhd_loc-2735  =>    <idle>-0   
 3)    <idle>-0    =>  rhd_loc-2735 
 3)  rhd_loc-2735  =>    <idle>-0   
 3)    <idle>-0    =>  rhd_loc-2735 

rhd_loc-2735es nuestro proceso.

Además de lo que se muestra arriba, vemos muchos casos en los que kworker-2703los conmutadores y, a veces, otros procesos de menor prioridad se intercambian con el núcleo.

Creemos que el motivo de los cambios de contexto es que nuestro proceso se comunica con SPI(la interfaz periférica en serie), que espera IRQsy también SPIse ejecuta a una velocidad de reloj un orden de magnitud más lenta que el núcleo de la CPU. Por lo tanto, nuestro proceso pasa gran parte de su tiempo esperando SPI/IRQ, por ejemplo, no está en un Runnableestado. Independientemente de la prioridad o afinidad, el núcleo es libre de asignar otros procesos al núcleo.

Esto hace que nuestra frecuencia de muestreo de hardware sea más variable y más baja de lo que podría ser porque nuestro núcleo de CPU no siempre está listo inmediatamente para procesar el siguiente valor SPIy luego enviar una nueva solicitud de muestreo.

Pregunta:

¿Podemos 1) forzar a todos los demás procesos a permanecer fuera del núcleo para que nuestro proceso pueda responder inmediatamente a las solicitudes de interrupción, o 2) mantener nuestro hilo principal ejecutable para que siempre esté disponible para procesar la siguiente solicitud?

información relacionada