| 
 | 
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 ] |