OsdSynch.c (99492) | OsdSynch.c (105278) |
---|---|
1/*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2000 BSDi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * | 1/*- 2 * Copyright (c) 2000 Michael Smith 3 * Copyright (c) 2000 BSDi 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * |
27 * $FreeBSD: head/sys/dev/acpica/Osd/OsdSynch.c 99492 2002-07-06 13:59:59Z iwasaki $ | 27 * $FreeBSD: head/sys/dev/acpica/Osd/OsdSynch.c 105278 2002-10-16 17:23:34Z jhb $ |
28 */ 29 30/* 31 * 6.1 : Mutual Exclusion and Synchronisation 32 */ 33 34#include "acpi.h" 35 36#include "opt_acpi.h" 37#include <sys/kernel.h> | 28 */ 29 30/* 31 * 6.1 : Mutual Exclusion and Synchronisation 32 */ 33 34#include "acpi.h" 35 36#include "opt_acpi.h" 37#include <sys/kernel.h> |
38#include <sys/lock.h> | |
39#include <sys/malloc.h> | 38#include <sys/malloc.h> |
40#include <sys/mutex.h> | |
41#include <sys/sysctl.h> | 39#include <sys/sysctl.h> |
40#if __FreeBSD_version >= 500000 41#include <sys/lock.h> 42#include <sys/mutex.h> 43#endif |
|
42 43#define _COMPONENT ACPI_OS_SERVICES 44ACPI_MODULE_NAME("SYNCH") 45 46static MALLOC_DEFINE(M_ACPISEM, "acpisem", "ACPI semaphore"); 47 | 44 45#define _COMPONENT ACPI_OS_SERVICES 46ACPI_MODULE_NAME("SYNCH") 47 48static MALLOC_DEFINE(M_ACPISEM, "acpisem", "ACPI semaphore"); 49 |
50#if __FreeBSD_version < 500000 51# define AS_LOCK(as) s = splhigh() 52# define AS_UNLOCK(as) splx(s) 53# define AS_LOCK_DECL int s 54# define msleep(a, b, c, d, e) tsleep(a, c, d, e) 55#else 56# define AS_LOCK(as) mtx_lock(&(as)->as_mtx) 57# define AS_UNLOCK(as) mtx_unlock(&(as)->as_mtx) 58# define AS_LOCK_DECL 59#endif 60 |
|
48/* 49 * Simple counting semaphore implemented using a mutex. (Subsequently used 50 * in the OSI code to implement a mutex. Go figure.) 51 */ 52struct acpi_semaphore { | 61/* 62 * Simple counting semaphore implemented using a mutex. (Subsequently used 63 * in the OSI code to implement a mutex. Go figure.) 64 */ 65struct acpi_semaphore { |
66#if __FreeBSD_version >= 500000 |
|
53 struct mtx as_mtx; | 67 struct mtx as_mtx; |
68#endif |
|
54 UINT32 as_units; 55 UINT32 as_maxunits; 56 UINT32 as_pendings; 57 UINT32 as_resetting; 58 UINT32 as_timeouts; 59}; 60 61#ifndef ACPI_NO_SEMAPHORES --- 18 unchanged lines hidden (view full) --- 80 return(AE_BAD_PARAMETER); 81 if (InitialUnits > MaxUnits) 82 return_ACPI_STATUS(AE_BAD_PARAMETER); 83 84 if ((as = malloc(sizeof(*as), M_ACPISEM, M_NOWAIT)) == NULL) 85 return_ACPI_STATUS(AE_NO_MEMORY); 86 87 bzero(as, sizeof(*as)); | 69 UINT32 as_units; 70 UINT32 as_maxunits; 71 UINT32 as_pendings; 72 UINT32 as_resetting; 73 UINT32 as_timeouts; 74}; 75 76#ifndef ACPI_NO_SEMAPHORES --- 18 unchanged lines hidden (view full) --- 95 return(AE_BAD_PARAMETER); 96 if (InitialUnits > MaxUnits) 97 return_ACPI_STATUS(AE_BAD_PARAMETER); 98 99 if ((as = malloc(sizeof(*as), M_ACPISEM, M_NOWAIT)) == NULL) 100 return_ACPI_STATUS(AE_NO_MEMORY); 101 102 bzero(as, sizeof(*as)); |
103#if __FreeBSD_version >= 500000 |
|
88 mtx_init(&as->as_mtx, "ACPI semaphore", NULL, MTX_DEF); | 104 mtx_init(&as->as_mtx, "ACPI semaphore", NULL, MTX_DEF); |
105#endif |
|
89 as->as_units = InitialUnits; 90 as->as_maxunits = MaxUnits; 91 as->as_pendings = as->as_resetting = as->as_timeouts = 0; 92 93 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 94 "created semaphore %p max %d, initial %d\n", 95 as, InitialUnits, MaxUnits)); 96 --- 9 unchanged lines hidden (view full) --- 106AcpiOsDeleteSemaphore (ACPI_HANDLE Handle) 107{ 108#ifndef ACPI_NO_SEMAPHORES 109 struct acpi_semaphore *as = (struct acpi_semaphore *)Handle; 110 111 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 112 113 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "destroyed semaphore %p\n", as)); | 106 as->as_units = InitialUnits; 107 as->as_maxunits = MaxUnits; 108 as->as_pendings = as->as_resetting = as->as_timeouts = 0; 109 110 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 111 "created semaphore %p max %d, initial %d\n", 112 as, InitialUnits, MaxUnits)); 113 --- 9 unchanged lines hidden (view full) --- 123AcpiOsDeleteSemaphore (ACPI_HANDLE Handle) 124{ 125#ifndef ACPI_NO_SEMAPHORES 126 struct acpi_semaphore *as = (struct acpi_semaphore *)Handle; 127 128 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 129 130 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, "destroyed semaphore %p\n", as)); |
131#if __FreeBSD_version >= 500000 |
|
114 mtx_destroy(&as->as_mtx); | 132 mtx_destroy(&as->as_mtx); |
133#endif |
|
115 free(Handle, M_ACPISEM); 116 return_ACPI_STATUS(AE_OK); 117#else 118 return(AE_OK); 119#endif 120} 121 122/* --- 4 unchanged lines hidden (view full) --- 127ACPI_STATUS 128AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT32 Timeout) 129{ 130#ifndef ACPI_NO_SEMAPHORES 131 struct acpi_semaphore *as = (struct acpi_semaphore *)Handle; 132 ACPI_STATUS result; 133 int rv, tmo; 134 struct timeval timeouttv, currenttv, timelefttv; | 134 free(Handle, M_ACPISEM); 135 return_ACPI_STATUS(AE_OK); 136#else 137 return(AE_OK); 138#endif 139} 140 141/* --- 4 unchanged lines hidden (view full) --- 146ACPI_STATUS 147AcpiOsWaitSemaphore(ACPI_HANDLE Handle, UINT32 Units, UINT32 Timeout) 148{ 149#ifndef ACPI_NO_SEMAPHORES 150 struct acpi_semaphore *as = (struct acpi_semaphore *)Handle; 151 ACPI_STATUS result; 152 int rv, tmo; 153 struct timeval timeouttv, currenttv, timelefttv; |
154 AS_LOCK_DECL; |
|
135 136 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 137 138 if (as == NULL) 139 return_ACPI_STATUS(AE_BAD_PARAMETER); 140 141 if (cold) 142 return_ACPI_STATUS(AE_OK); 143 144#if 0 145 if (as->as_units < Units && as->as_timeouts > 10) { 146 printf("%s: semaphore %p too many timeouts, resetting\n", __func__, as); | 155 156 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 157 158 if (as == NULL) 159 return_ACPI_STATUS(AE_BAD_PARAMETER); 160 161 if (cold) 162 return_ACPI_STATUS(AE_OK); 163 164#if 0 165 if (as->as_units < Units && as->as_timeouts > 10) { 166 printf("%s: semaphore %p too many timeouts, resetting\n", __func__, as); |
147 mtx_lock(&as->as_mtx); | 167 AS_LOCK(as); |
148 as->as_units = as->as_maxunits; 149 if (as->as_pendings) 150 as->as_resetting = 1; 151 as->as_timeouts = 0; 152 wakeup(as); | 168 as->as_units = as->as_maxunits; 169 if (as->as_pendings) 170 as->as_resetting = 1; 171 as->as_timeouts = 0; 172 wakeup(as); |
153 mtx_unlock(&as->as_mtx); | 173 AS_UNLOCK(as); |
154 return_ACPI_STATUS(AE_TIME); 155 } 156 157 if (as->as_resetting) { 158 return_ACPI_STATUS(AE_TIME); 159 } 160#endif 161 --- 10 unchanged lines hidden (view full) --- 172 timeouttv.tv_sec = Timeout / 1000; 173 timeouttv.tv_usec = (Timeout % 1000) * 1000; 174 } 175 176 /* calculate timeout value in timeval */ 177 getmicrotime(¤ttv); 178 timevaladd(&timeouttv, ¤ttv); 179 | 174 return_ACPI_STATUS(AE_TIME); 175 } 176 177 if (as->as_resetting) { 178 return_ACPI_STATUS(AE_TIME); 179 } 180#endif 181 --- 10 unchanged lines hidden (view full) --- 192 timeouttv.tv_sec = Timeout / 1000; 193 timeouttv.tv_usec = (Timeout % 1000) * 1000; 194 } 195 196 /* calculate timeout value in timeval */ 197 getmicrotime(¤ttv); 198 timevaladd(&timeouttv, ¤ttv); 199 |
180 mtx_lock(&as->as_mtx); | 200 AS_LOCK(as); |
181 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 182 "get %d units from semaphore %p (has %d), timeout %d\n", 183 Units, as, as->as_units, Timeout)); 184 for (;;) { 185 if (as->as_maxunits == ACPI_NO_UNIT_LIMIT) { 186 result = AE_OK; 187 break; 188 } --- 10 unchanged lines hidden (view full) --- 199 } 200 201 /* if timeout values of zero is specified, return immediately */ 202 if (Timeout == 0) { 203 result = AE_TIME; 204 break; 205 } 206 | 201 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 202 "get %d units from semaphore %p (has %d), timeout %d\n", 203 Units, as, as->as_units, Timeout)); 204 for (;;) { 205 if (as->as_maxunits == ACPI_NO_UNIT_LIMIT) { 206 result = AE_OK; 207 break; 208 } --- 10 unchanged lines hidden (view full) --- 219 } 220 221 /* if timeout values of zero is specified, return immediately */ 222 if (Timeout == 0) { 223 result = AE_TIME; 224 break; 225 } 226 |
227#if __FreeBSD_version >= 500000 |
|
207 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 208 "semaphore blocked, calling msleep(%p, %p, %d, \"acsem\", %d)\n", 209 as, &as->as_mtx, PCATCH, tmo)); | 228 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 229 "semaphore blocked, calling msleep(%p, %p, %d, \"acsem\", %d)\n", 230 as, &as->as_mtx, PCATCH, tmo)); |
231#endif |
|
210 211 as->as_pendings++; 212 213 if (acpi_semaphore_debug) { 214 printf("%s: Sleep %d, pending %d, semaphore %p, thread %d\n", 215 __func__, Timeout, as->as_pendings, as, AcpiOsGetThreadId()); 216 } 217 --- 51 unchanged lines hidden (view full) --- 269 } 270 271 if (result == AE_TIME) { 272 as->as_timeouts++; 273 } else { 274 as->as_timeouts = 0; 275 } 276 | 232 233 as->as_pendings++; 234 235 if (acpi_semaphore_debug) { 236 printf("%s: Sleep %d, pending %d, semaphore %p, thread %d\n", 237 __func__, Timeout, as->as_pendings, as, AcpiOsGetThreadId()); 238 } 239 --- 51 unchanged lines hidden (view full) --- 291 } 292 293 if (result == AE_TIME) { 294 as->as_timeouts++; 295 } else { 296 as->as_timeouts = 0; 297 } 298 |
277 mtx_unlock(&as->as_mtx); | 299 AS_UNLOCK(as); |
278 279 return_ACPI_STATUS(result); 280#else 281 return(AE_OK); 282#endif 283} 284 285ACPI_STATUS 286AcpiOsSignalSemaphore(ACPI_HANDLE Handle, UINT32 Units) 287{ 288#ifndef ACPI_NO_SEMAPHORES 289 struct acpi_semaphore *as = (struct acpi_semaphore *)Handle; | 300 301 return_ACPI_STATUS(result); 302#else 303 return(AE_OK); 304#endif 305} 306 307ACPI_STATUS 308AcpiOsSignalSemaphore(ACPI_HANDLE Handle, UINT32 Units) 309{ 310#ifndef ACPI_NO_SEMAPHORES 311 struct acpi_semaphore *as = (struct acpi_semaphore *)Handle; |
312 AS_LOCK_DECL; |
|
290 291 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 292 293 if (as == NULL) 294 return_ACPI_STATUS(AE_BAD_PARAMETER); 295 | 313 314 ACPI_FUNCTION_TRACE((char *)(uintptr_t)__func__); 315 316 if (as == NULL) 317 return_ACPI_STATUS(AE_BAD_PARAMETER); 318 |
296 mtx_lock(&as->as_mtx); | 319 AS_LOCK(as); |
297 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 298 "return %d units to semaphore %p (has %d)\n", 299 Units, as, as->as_units)); 300 if (as->as_maxunits != ACPI_NO_UNIT_LIMIT) { 301 as->as_units += Units; 302 if (as->as_units > as->as_maxunits) 303 as->as_units = as->as_maxunits; 304 } 305 306 if (acpi_semaphore_debug && (as->as_timeouts > 0 || as->as_pendings > 0)) { 307 printf("%s: Release %d, units %d, pending %d, semaphore %p, thread %d\n", 308 __func__, Units, as->as_units, as->as_pendings, as, AcpiOsGetThreadId()); 309 } 310 311 wakeup(as); | 320 ACPI_DEBUG_PRINT((ACPI_DB_MUTEX, 321 "return %d units to semaphore %p (has %d)\n", 322 Units, as, as->as_units)); 323 if (as->as_maxunits != ACPI_NO_UNIT_LIMIT) { 324 as->as_units += Units; 325 if (as->as_units > as->as_maxunits) 326 as->as_units = as->as_maxunits; 327 } 328 329 if (acpi_semaphore_debug && (as->as_timeouts > 0 || as->as_pendings > 0)) { 330 printf("%s: Release %d, units %d, pending %d, semaphore %p, thread %d\n", 331 __func__, Units, as->as_units, as->as_pendings, as, AcpiOsGetThreadId()); 332 } 333 334 wakeup(as); |
312 mtx_unlock(&as->as_mtx); | 335 AS_UNLOCK(as); |
313 return_ACPI_STATUS(AE_OK); 314#else 315 return(AE_OK); 316#endif 317} | 336 return_ACPI_STATUS(AE_OK); 337#else 338 return(AE_OK); 339#endif 340} |