|
CRITICAL_ENTER(9)
Contents
|
cpu_critical_enter, cpu_critical_exit, critical_enter, critical_exit --
enter and exit a critical region
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <machine/critical.h>
void
cpu_critical_enter(void);
void
cpu_critical_exit(void);
void
critical_enter(void);
void
critical_exit(void);
These functions are used to prevent preemption in a critical region of
code. All that is guaranteed is that the thread currently executing on a
CPU will not be preempted. Specifically, a thread in a critical region
will not migrate to another CPU while it is in a critical region. The
current CPU may still trigger faults and exceptions during a critical
section; however, these faults are usually fatal.
The cpu_critical_enter() and cpu_critical_exit() functions provide the
machine dependent disabling of preemption, normally by disabling interrupts
on the local CPU.
The critical_enter() and critical_exit() functions provide a machine
independent wrapper around the machine dependent API. This wrapper currently
saves state regarding nested critical sections. Nearly all code
should use these versions of the API.
Note that these functions are not required to provide any inter-CPU synchronization,
data protection, or memory ordering guarantees and thus
should not be used to protect shared data structures.
These functions should be used with care as an infinite loop within a
critical region will deadlock the CPU. Also, they should not be interlocked
with operations on mutexes, sx locks, semaphores, or other synchronization
primitives.
This example demonstrates the use of critical_enter() and critical_exit()
to guarantee atomic access to the DMA controller.
int
isa_dmastatus(int chan)
{
u_long cnt = 0;
int ffport, waport;
u_long low1, high1, low2, high2;
...
critical_enter();
outb(ffport, 0);
low1 = inb(waport);
high1 = inb(waport);
outb(ffport, 0);
low2 = inb(waport);
high2 = inb(waport);
critical_exit();
...
}
These functions were introduced in FreeBSD 5.0.
FreeBSD 5.2.1 March 22, 2001 FreeBSD 5.2.1 [ Back ] |