1.\" Copyright (c) 2001,2002 John H. Baldwin <jhb@FreeBSD.org> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.\" $FreeBSD$ 26.\" 27.Dd March 22, 2001 28.Dt CRITICAL_ENTER 9 29.Os 30.Sh NAME 31.Nm cpu_critical_enter , 32.Nm cpu_critical_exit , 33.Nm critical_enter , 34.Nm critical_exit 35.Nd enter and exit a critical region 36.Sh SYNOPSIS 37.In sys/types.h 38.In sys/systm.h 39.Ft critical_t 40.Fn cpu_critical_enter "void" 41.Ft void 42.Fn cpu_critical_exit "critical_t savecrit" 43.Ft void 44.Fn critical_enter "void" 45.Ft void 46.Fn critical_exit "void" 47.Sh DESCRIPTION 48These functions are used to prevent preemption in a critcal region of code. 49All that is guaranteed is that the thread currently executing on a CPU will 50not be preempted. 51Specifically, a thread in a critical region will not migrate to another 52CPU while it is in a critical region. 53The current CPU may still trigger faults and exceptions during a critical 54section; however, these faults are usually fatal. 55.Pp 56The 57.Fn cpu_critical_enter 58and 59.Fn cpu_critical_exit 60functions provide the machine dependent disabling of preemption, normally 61by disabling interrupts on the local CPU. 62The 63.Fn cpu_critical_enter 64function returns an opaque value of type 65.Vt critical_t . 66This value must be passed to the 67.Fn cpu_critical_exit 68function when leaving the critical region. 69.Pp 70The 71.Fn critical_enter 72and 73.Fn critical_exit 74functions provide a machine independent wrapper around the machine dependent 75API. 76This wrapper currently saves state regarding nested critical sections as 77well as the 78.Vt critical_t 79value inside of a critical region in per-thread variables. 80Nearly all code should use these versions of the API. 81.Pp 82Note that these functions are not required to provide any inter-CPU 83synchronization, data protection, or memory ordering guarantees and thus 84should 85.Em not 86be used to protect shared data structures. 87.Pp 88These functions should be used with care as an infinite loop within a 89critical region will deadlock the CPU. 90Also, the machine dependent and machine independent functions should not 91be interlocked, and neither pair of functions should be interlocked with 92operations on mutexes, sx locks, semaphores, or other synchronization 93primitives. 94.Sh RETURN VALUES 95The 96.Fn cpu_critical_enter 97function returns an opaque value that must be passed to a corresponding call to 98.Fn cpu_critical_exit . 99.Sh EXAMPLES 100This example demonstrates the use of 101.Fn critical_enter 102and 103.Fn critical_exit 104to guarantee atomic access to the DMA controller. 105.Bd -literal -offset indent 106int 107isa_dmastatus(int chan) 108{ 109 u_long cnt = 0; 110 int ffport, waport; 111 u_long low1, high1, low2, high2; 112 113 ... 114 critical_enter(); 115 outb(ffport, 0); 116 low1 = inb(waport); 117 high1 = inb(waport); 118 outb(ffport, 0); 119 low2 = inb(waport); 120 high2 = inb(waport); 121 critical_exit(); 122 ... 123} 124.Ed 125.Sh HISTORY 126These functions were introduced in 127.Fx 5.0 . 128