Pregunta

Aunque este tema se ha discutido muchas veces en este foro y todos los demás foros, todavía tengo dudas. Por favor, ayuda.

¿Cómo funciona el trabajo en do{} while(0) macro en el kernel de Linux? Por ejemplo,

#define preempt_disable()    do { } while (0)

¿Cómo desactivar preempt?

#define might_resched()    do { } while (0)

¿Cómo reprogramar?

Del mismo modo macros que he visto para las cerraduras de exclusión mutua y otro también. ¿Cómo ayuda esto? Entiendo por seguir problema, pero no para los ejemplos anteriores.

#define foo(x)    do { do something } while(0)

Editar

¿Qué pasa con el siguiente código para rt_mutex_lock?

/**
 * rt_mutex_lock - lock a rt_mutex
 *
 * @lock: the rt_mutex to be locked
 */
void __sched rt_mutex_lock(struct rt_mutex *lock)
{
        might_sleep();
        rt_mutex_fastlock(lock, TASK_UNINTERRUPTIBLE, 0, rt_mutex_slowlock);
}
EXPORT_SYMBOL_GPL(rt_mutex_lock);


/*
 * debug aware fast / slowpath lock,trylock,unlock
 *
 * The atomic acquire/release ops are compiled away, when either the
 * architecture does not support cmpxchg or when debugging is enabled.
 */

static inline int rt_mutex_fastlock(struct rt_mutex *lock, 
    int state, int detect_deadlock, int (*slowfn)(struct rt_mutex *lock, 
    int state, struct hrtimer_sleeper *timeout, int detect_deadlock))
{
        if (!detect_deadlock && likely(rt_mutex_cmpxchg(lock, NULL, current))) {
                rt_mutex_deadlock_account_lock(lock, current);
                return 0;
        } else{
                return slowfn(lock, state, NULL, detect_deadlock);
        }
}

Estoy confundido porque rt_mutex_deadlock_account_lock se definen en dos lugares en el núcleo:

En kernel/rtmutex-debug.c:

void rt_mutex_deadlock_account_lock(struct rt_mutex *lock, 
    struct task_struct *task)
{
    //....
}

En kernel/rtmutex.h:

#define rt_mutex_deadlock_account_lock(m, t) do { } while (0)

En el nuevo kernel 2.6.35.4 en el rt_mutex_lock(&adap->bus_lock); controlador I2C ha sustituido a la mutex_lock(). ¿Cómo funciona este bloqueo, entonces?

¿Fue útil?

Solución

@Kragen ha respondido a lo que el hacer ... mientras constructo es para -. Que básicamente hace una macro mucho más seguro para el uso

Sin embargo, no creo que responde a la pregunta "¿cómo funciona esto?":

#define preempt_disable()    do { } while (0)

La macro se define a no hacer nada . ¿Por qué quieres que hacer nada?

  • En algunos casos se desea utilizar una macro como un marcador de posición para hacer algo. Por ejemplo, es posible escribir código en un sistema donde "Preferencia" no es un problema, pero se conoce el código podría ser portado a un sistema donde "Preferencia" necesita un poco de manejo especial. Así que utiliza una macro en todas partes el segundo sistema lo necesita (de modo que el manejo es fácil de activar más adelante), pero para el primer sistema a continuación, definir esa macro como una macro en blanco.

  • En algunos casos es posible que desee hacer cosas como una tarea que se compone de diferentes partes, (por ejemplo START_TABLE (); TABLE_ENTRY (1); TABLE_ENTRY (2); END_TABLE ();). Esto hace que una buena aplicación limpia y clara de su mesa. Pero entonces descubre que en realidad no necesita la macro END_TABLE (). Permiten mantener el orden código de cliente, sale de la macro definida, y simplemente se define para no hacer nada. De esta manera, todas las tablas tienen un END_TABLE y el código es más fácil de leer.

  • Un caso similar puede ocurrir con dos estados (activar / desactivar) donde un estado necesita la macro para hacer algo, pero el otro estado sólo pasa por defecto, por lo que la aplicación de uno es "vacío" - que todavía utilizar la macro porque hace que el código de cliente más fácil de entender, ya que afirma explícitamente los lugares donde las cosas están activados o desactivados.

Otros consejos

este enlace para una mejor explicación de lo que podía dar.

IIRC el uso del do-while en las macros es para que se vean más como una invocación de la función normal; hay algunos problemas de sintaxis sutiles alrededor sin soporte lateral si las declaraciones y cosas por el estilo. Sin el do-while el aspecto fuerzas macro como una invocación de la función normal, pero podría funcionar de forma diferente.

Me imagino que en este caso se utilizan las macros para ciertas llamadas a funciones compilan en la nada; que parece que podría ser lo que se obtiene si no se ha establecido CONFIG_PREEMPT, por lo que ciertas partes del núcleo que sólo son necesarios para preempt simplemente desaparecen sin ella. Así que los bucles hacen preempt no desactivar o cualquier reprogramación; no habrá otra definición (probablemente una función real) en el código fuente del núcleo en otro lugar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top