|
|
1.1 ! root 1: #ifndef __KERNEL_X86LOCK_H__ ! 2: #define __KERNEL_X86LOCK_H__ ! 3: ! 4: /* ! 5: * Here we encapsulate all the system-specific basics for dealing with multi- ! 6: * and uni-processor locking in an i386 environment. Note that the functions ! 7: * defined here for the user have names that are too long for common ISO C ! 8: * external linkage limitations; this should not be an obstacle, since the ! 9: * functions defined here will normally have internal linkage. ! 10: * ! 11: * Note that none of the functions here are defined in the DDI/DKI. This ! 12: * header is purely for internal purposes and for this reason does not follow ! 13: * the usual DDI/DKI header binary-compatibility structure with external- ! 14: * linkage versions always available. ! 15: */ ! 16: ! 17: /* ! 18: *-IMPORTS: ! 19: * <common/ccompat.h> ! 20: * __INLINE__ ! 21: * __VOLATILE__ ! 22: * __NON_ISO () ! 23: * <common/xdebug.h> ! 24: * __LOCAL__ ! 25: * <common/__types.h> ! 26: * __uchar_t ! 27: * __ushort_t ! 28: * __uint_t ! 29: * __ulong_t ! 30: * <kernel/__pl.h> ! 31: * __pl_t ! 32: */ ! 33: ! 34: #include <common/ccompat.h> ! 35: #include <common/xdebug.h> ! 36: #include <common/__types.h> ! 37: #include <kernel/__pl.h> ! 38: ! 39: ! 40: /* ! 41: * On the 386, there are no "compare and swap" instructions as in the 68020 ! 42: * CPU. Unfortunately, this deficiency makes some of the more advanced ! 43: * synchronisation algorithms unavailable (and introduces locking requirements ! 44: * where no locking is needed in the 68020). ! 45: * ! 46: * The facilities that do exist are an atomic fetch-and-set via XCHG, and ! 47: * atomic arithmetic via the LOCK instruction prefix. Neither facility is ! 48: * directly available in C, so this header file encapsulates the system- ! 49: * specific methods for gaining access to these atomic operations. ! 50: * ! 51: * We define a wide range of atomic data types, so that in cases where a ! 52: * machine might not be able to support a high-level atomic operation on a ! 53: * data type it will be possible to build the high-level operation out of ! 54: * primitive locking facilities like test-and-set. ! 55: * ! 56: * We use the single-element-array declarations for two reasons: 1) we may ! 57: * as well have implicit reference-passing semantics, and 2) it seems like ! 58: * the easiest way (until C++, at least) of preventing the accidental misuse ! 59: * of data items of these types. ! 60: * ! 61: * Each atomic type is guaranteed to have the same range as the <limits.h> ! 62: * header specifies, but may be considerably larger (and have different ! 63: * alignment requirements) than objects of the base non-atomic type. ! 64: * ! 65: * Dealing with atomic pointers: with C++, there is currently no guarantee ! 66: * equivalent to the ISO C requirement that any pointer type can be converted ! 67: * to and from a value of type "void *" successfully without loss of ! 68: * information. For now, we operate without this guarantee rather than ! 69: * introducing possibly unnecessary complexity via a "generic" structure- ! 70: * pointer type. In point of fact, we don't support the only known case where ! 71: * this doesn't work anyway (Borland C++ medium model, SS != DS) since we ! 72: * assume SS = DS in those small-data models for simplicity anyway. ! 73: * ! 74: * To make things easier for the Borland C++, all the functions defined here ! 75: * are permitted to evaluate their "lock" argument multiple times, which is ! 76: * why the names have been changed to all upper-case. ! 77: */ ! 78: ! 79: /* ! 80: * The split between the user-visible (implicit reference) and internal ! 81: * (volatile, decayed pointer) types was effectively forced by differences ! 82: * in the way the available translators dealt with type-qualifiers and casts ! 83: * to values of array type. ! 84: * ! 85: * As it happens, this split appears to have produced the most aesthetically ! 86: * pleasing code forms, much to my surprise, as well as pointing up a lurking ! 87: * problem (a misplaced "volatile") in the treatment of atomic_ptr_t. ! 88: */ ! 89: ! 90: typedef signed char atomic_char_t [1]; ! 91: typedef short atomic_short_t [1]; ! 92: typedef int atomic_int_t [1]; ! 93: typedef long atomic_long_t [1]; ! 94: ! 95: typedef __uchar_t atomic_uchar_t [1]; ! 96: typedef __ushort_t atomic_ushort_t [1]; ! 97: typedef __uint_t atomic_uint_t [1]; ! 98: typedef __ulong_t atomic_ulong_t [1]; ! 99: ! 100: typedef __VOID__ * atomic_ptr_t [1]; ! 101: ! 102: typedef __VOLATILE__ signed char * __atomic_char_t; ! 103: typedef __VOLATILE__ __uchar_t * __atomic_uchar_t; ! 104: typedef __VOLATILE__ short * __atomic_short_t; ! 105: typedef __VOLATILE__ __ushort_t * __atomic_ushort_t; ! 106: typedef __VOLATILE__ int * __atomic_int_t; ! 107: typedef __VOLATILE__ __uint_t * __atomic_uint_t; ! 108: typedef __VOLATILE__ long * __atomic_long_t; ! 109: typedef __VOLATILE__ __ulong_t * __atomic_ulong_t; ! 110: typedef __VOID__ * __VOLATILE__ * __atomic_ptr_t; ! 111: ! 112: ! 113: /* ! 114: * Here we define C-linkage prototypes for the functions that we want to ! 115: * define (possibly as macros) here, so that it's easy to suppress any macro ! 116: * definitions given below and get full type-checking even for compilers that ! 117: * need macros to get the inline versions. ! 118: * ! 119: * Note that while ATOMIC_TEST_AND_SET_UCHAR has () functionality that is ! 120: * completely availble through ATOMIC_FETCH_AND_STORE_UCHAR (), we define it ! 121: * as a separate function so as not to overly constrain implementations on ! 122: * machines such as the 60820, which has the powerful "compare and swap" ! 123: * operation and the basic "test and set operation", but no basic exchange ! 124: * (whereas the 88100 implements only exchange, and only on bytes and 32-bit ! 125: * long words). ! 126: * ! 127: * Being verbose here is a small price to pay for the later flexibility. ! 128: */ ! 129: ! 130: ! 131: #if ! (__GNUC__ && (defined (i386) || _I386)) ! 132: ! 133: __EXTERN_C_BEGIN__ ! 134: ! 135: char ATOMIC_FETCH_AND_STORE_CHAR __PROTO ((__atomic_char_t _lock, ! 136: char _newvalue)); ! 137: __uchar_t ATOMIC_FETCH_AND_STORE_UCHAR __PROTO ((__atomic_uchar_t _lock, ! 138: __uchar_t _newvalue)); ! 139: short ATOMIC_FETCH_AND_STORE_SHORT __PROTO ((__atomic_short_t _lock, ! 140: short _newvalue)); ! 141: __ushort_t ATOMIC_FETCH_AND_STORE_USHORT __PROTO ((__atomic_ushort_t _lock, ! 142: __ushort_t _newvalue)); ! 143: int ATOMIC_FETCH_AND_STORE_INT __PROTO ((__atomic_int_t _lock, ! 144: int _newvalue)); ! 145: __uint_t ATOMIC_FETCH_AND_STORE_UINT __PROTO ((__atomic_uint_t _lock, ! 146: __uint_t _newvalue)); ! 147: long ATOMIC_FETCH_AND_STORE_LONG __PROTO ((__atomic_long_t _lock, ! 148: long _newvalue)); ! 149: __ulong_t ATOMIC_FETCH_AND_STORE_ULONG __PROTO ((__atomic_ulong_t _lock, ! 150: __ulong_t _newvalue)); ! 151: ! 152: __VOID__ * ATOMIC_FETCH_AND_STORE_PTR __PROTO ((__atomic_ptr_t _lock, ! 153: __VOID__ * _newvalue)); ! 154: ! 155: char ATOMIC_FETCH_CHAR __PROTO ((__atomic_char_t _lock)); ! 156: __uchar_t ATOMIC_FETCH_UCHAR __PROTO ((__atomic_uchar_t _lock)); ! 157: short ATOMIC_FETCH_SHORT __PROTO ((__atomic_short_t _lock)); ! 158: __ushort_t ATOMIC_FETCH_USHORT __PROTO ((__atomic_ushort_t _lock)); ! 159: int ATOMIC_FETCH_INT __PROTO ((__atomic_int_t _lock)); ! 160: __uint_t ATOMIC_FETCH_UINT __PROTO ((__atomic_uint_t _lock)); ! 161: long ATOMIC_FETCH_LONG __PROTO ((__atomic_long_t _lock)); ! 162: __ulong_t ATOMIC_FETCH_ULONG __PROTO ((__atomic_ulong_t _lock)); ! 163: __VOID__ * ATOMIC_FETCH_PTR __PROTO ((__atomic_ptr_t _lock)); ! 164: ! 165: int ATOMIC_TEST_AND_SET_UCHAR __PROTO ((__atomic_uchar_t _lock)); ! 166: ! 167: void ATOMIC_STORE_PTR __PROTO ((__atomic_ptr_t _lock, ! 168: __VOID__ * _newvalue)); ! 169: ! 170: void ATOMIC_CLEAR_UCHAR __PROTO ((__atomic_uchar_t _lock)); ! 171: void ATOMIC_CLEAR_USHORT __PROTO ((__atomic_ushort_t _lock)); ! 172: void ATOMIC_CLEAR_PTR __PROTO ((__atomic_ptr_t _lock)); ! 173: ! 174: __EXTERN_C_END__ ! 175: ! 176: ! 177: #else /* __GNUC__ && (defined (i386) || _I386) */ ! 178: ! 179: ! 180: __LOCAL__ __INLINE__ ! 181: char ATOMIC_FETCH_AND_STORE_CHAR (__atomic_char_t _lock, ! 182: char _newvalue) { ! 183: __NON_ISO (asm) volatile ("xchgb %0, %2" : "=r" (_newvalue) : ! 184: "0" (_newvalue), "m" (_lock [0])); ! 185: return _newvalue; ! 186: } ! 187: ! 188: __LOCAL__ __INLINE__ ! 189: __uchar_t ATOMIC_FETCH_AND_STORE_UCHAR (__atomic_uchar_t _lock, ! 190: __uchar_t _newvalue) { ! 191: __NON_ISO (asm) volatile ("xchgb %0, %2" : "=r" (_newvalue) : ! 192: "0" (_newvalue), "m" (_lock [0])); ! 193: return _newvalue; ! 194: } ! 195: ! 196: __LOCAL__ __INLINE__ ! 197: short ATOMIC_FETCH_AND_STORE_SHORT (__atomic_short_t _lock, ! 198: short _newvalue) { ! 199: __NON_ISO (asm) volatile ("xchgw %0, %2" : "=r" (_newvalue) : ! 200: "0" (_newvalue), "m" (_lock [0])); ! 201: return _newvalue; ! 202: } ! 203: ! 204: __LOCAL__ __INLINE__ ! 205: __ushort_t ATOMIC_FETCH_AND_STORE_USHORT (__atomic_ushort_t _lock, ! 206: __ushort_t _newvalue) { ! 207: __NON_ISO (asm) volatile ("xchgw %0, %2" : "=r" (_newvalue) : ! 208: "0" (_newvalue), "m" (_lock [0])); ! 209: return _newvalue; ! 210: } ! 211: ! 212: __LOCAL__ __INLINE__ ! 213: int ATOMIC_FETCH_AND_STORE_INT (__atomic_int_t _lock, ! 214: int _newvalue) { ! 215: __NON_ISO (asm) volatile ("xchgl %0, %2" : "=r" (_newvalue) : ! 216: "0" (_newvalue), "m" (_lock [0])); ! 217: return _newvalue; ! 218: } ! 219: ! 220: __LOCAL__ __INLINE__ ! 221: __uint_t ATOMIC_FETCH_AND_STORE_UINT (__atomic_uint_t _lock, ! 222: __uint_t _newvalue) { ! 223: __NON_ISO (asm) volatile ("xchgl %0, %2" : "=r" (_newvalue) : ! 224: "0" (_newvalue), "m" (_lock [0])); ! 225: return _newvalue; ! 226: } ! 227: ! 228: __LOCAL__ __INLINE__ ! 229: long ATOMIC_FETCH_AND_STORE_LONG (__atomic_long_t _lock, ! 230: long _newvalue) { ! 231: __NON_ISO (asm) volatile ("xchgl %0, %2" : "=r" (_newvalue) : ! 232: "0" (_newvalue), "m" (_lock [0])); ! 233: return _newvalue; ! 234: } ! 235: ! 236: __LOCAL__ __INLINE__ ! 237: __ulong_t ATOMIC_FETCH_AND_STORE_ULONG (__atomic_ulong_t _lock, ! 238: __ulong_t _newvalue) { ! 239: __NON_ISO (asm) volatile ("xchgl %0, %2" : "=r" (_newvalue) : ! 240: "0" (_newvalue), "m" (_lock [0])); ! 241: return _newvalue; ! 242: } ! 243: ! 244: __LOCAL__ __INLINE__ ! 245: __VOID__ * ATOMIC_FETCH_AND_STORE_PTR (__atomic_ptr_t _lock, ! 246: __VOID__ * _newvalue) { ! 247: __NON_ISO (asm) volatile ("xchgl %0, %2" : "=r" (_newvalue) : ! 248: "0" (_newvalue), "m" (_lock [0])); ! 249: return _newvalue; ! 250: } ! 251: ! 252: __LOCAL__ __INLINE__ char ATOMIC_FETCH_CHAR (__atomic_char_t _lock) { ! 253: return _lock [0]; ! 254: } ! 255: ! 256: __LOCAL__ __INLINE__ __uchar_t ATOMIC_FETCH_UCHAR (__atomic_uchar_t _lock) { ! 257: return _lock [0]; ! 258: } ! 259: ! 260: __LOCAL__ __INLINE__ short ATOMIC_FETCH_SHORT (__atomic_short_t _lock) { ! 261: return _lock [0]; ! 262: } ! 263: ! 264: __LOCAL__ __INLINE__ __ushort_t ATOMIC_FETCH_USHORT (__atomic_ushort_t _lock) { ! 265: return _lock [0]; ! 266: } ! 267: ! 268: __LOCAL__ __INLINE__ int ATOMIC_FETCH_INT (__atomic_int_t _lock) { ! 269: return _lock [0]; ! 270: } ! 271: ! 272: __LOCAL__ __INLINE__ __uint_t ATOMIC_FETCH_UINT (__atomic_uint_t _lock) { ! 273: return _lock [0]; ! 274: } ! 275: ! 276: __LOCAL__ __INLINE__ long ATOMIC_FETCH_LONG (__atomic_long_t _lock) { ! 277: return _lock [0]; ! 278: } ! 279: ! 280: __LOCAL__ __INLINE__ __ulong_t ATOMIC_FETCH_ULONG (__atomic_ulong_t _lock) { ! 281: return _lock [0]; ! 282: } ! 283: ! 284: __LOCAL__ __INLINE__ __VOID__ * ATOMIC_FETCH_PTR (__atomic_ptr_t _lock) { ! 285: return (__VOID__ *) _lock [0]; ! 286: } ! 287: ! 288: __LOCAL__ __INLINE__ int ATOMIC_TEST_AND_SET_UCHAR (__atomic_uchar_t _lock) { ! 289: return ATOMIC_FETCH_AND_STORE_UCHAR (_lock, (__uchar_t) -1); ! 290: } ! 291: ! 292: __LOCAL__ __INLINE__ void ATOMIC_CLEAR_UCHAR (__atomic_uchar_t _lock) { ! 293: _lock [0] = 0; ! 294: } ! 295: ! 296: __LOCAL__ __INLINE__ void ATOMIC_CLEAR_USHORT (__atomic_ushort_t _lock) { ! 297: _lock [0] = 0; ! 298: } ! 299: ! 300: __LOCAL__ __INLINE__ void ATOMIC_CLEAR_PTR (__atomic_ptr_t _lock) { ! 301: _lock [0] = 0; ! 302: } ! 303: ! 304: __LOCAL__ __INLINE__ ! 305: void ATOMIC_STORE_UCHAR (__atomic_uchar_t _lock, __uchar_t _newvalue) { ! 306: _lock [0] = _newvalue; ! 307: } ! 308: ! 309: __LOCAL__ __INLINE__ ! 310: void ATOMIC_STORE_PTR (__atomic_ptr_t _lock, __VOID__ * _newvalue) { ! 311: _lock [0] = _newvalue; ! 312: } ! 313: ! 314: #endif ! 315: ! 316: ! 317: #if __BORLANDC__ ! 318: ! 319: ! 320: /*lint -e570 *//* Anything with pseudoregisters causes spurious warnings */ ! 321: /*lint -e732 *//* Anything with pseudoregisters causes spurious warnings */ ! 322: /*lint -e915 *//* Anything with pseudoregisters causes spurious warnings */ ! 323: ! 324: void __emit__ (unsigned char __byte, ...); ! 325: ! 326: /* ! 327: * Borland C++ has many restrictions on assembly and in-line functions. To ! 328: * get around some of these, we use the 32-bit-register pseudovariables that ! 329: * are available when targetting the 386. Note how we convert 32-bit values ! 330: * into 16-bit seg:offset pairs and back via the stack; this avoids several ! 331: * of the nastier bugs in the 32-bit support. ! 332: */ ! 333: ! 334: #define __USE_ES__ 0x26 ! 335: #define __XCHG_AL_ESBX__ __USE_ES__, 0x86, 0x07 ! 336: #define __XCHG_AX_ESBX__ __USE_ES__, 0x87, 0x07 ! 337: #define __XCHG_EAX_ESBX__ __USE_ES__, 0x66, 0x87, 0x07 ! 338: #define __MOV_AX_ESBX__ __USE_ES__, 0x8B, 0x07 ! 339: #define __MOV_EAX_ESBX__ __USE_ES__, 0x66, 0x8B, 0x07 ! 340: ! 341: #if defined (__LARGE__) || defined (__HUGE__) || defined (__COMPACT__) ! 342: #define __lockaddr(l) (_ES = (unsigned) (void __seg *) \ ! 343: (void __far *) (l),\ ! 344: _BX = (unsigned) (l)) ! 345: #else ! 346: #define __lockaddr(l) (_ES = _DS, _BX = (unsigned) (l)) ! 347: #endif ! 348: ! 349: ! 350: #define ATOMIC_FETCH_AND_STORE_CHAR(l,v) (__lockaddr (l), _AL = (v),\ ! 351: __emit__ (__XCHG_AL_ESBX__),\ ! 352: (char) _AL) ! 353: #define ATOMIC_FETCH_AND_STORE_UCHAR(l,v) (__lockaddr (l), _AL = (v),\ ! 354: __emit__ (__XCHG_AL_ESBX__),\ ! 355: (__uchar_t) _AL) ! 356: #define ATOMIC_FETCH_AND_STORE_SHORT(l,v) (__lockaddr (l), _AX = (v),\ ! 357: __emit__ (__XCHG_AX_ESBX__),\ ! 358: (short) _AX) ! 359: #define ATOMIC_FETCH_AND_STORE_USHORT(l,v) (__lockaddr (l), _AX = (v),\ ! 360: __emit__ (__XCHG_AX_ESBX__),\ ! 361: (__ushort_t) _AX) ! 362: #define ATOMIC_FETCH_AND_STORE_INT(l,v) (__lockaddr (l), _AX = (v),\ ! 363: __emit__ (__XCHG_AX_ESBX__),\ ! 364: (int) _AX) ! 365: #define ATOMIC_FETCH_AND_STORE_UINT(l,v) (__lockaddr (l), _AX = (v),\ ! 366: __emit__ (__XCHG_AX_ESBX__),\ ! 367: (__uint_t) _AX) ! 368: #define ATOMIC_FETCH_AND_STORE_LONG(l,v) (__lockaddr (l), _EAX = (v),\ ! 369: __emit__ (__XCHG_EAX_ESBX__),\ ! 370: (long) _EAX) ! 371: #define ATOMIC_FETCH_AND_STORE_ULONG(l,v) (__lockaddr (l), _EAX = (v),\ ! 372: __emit__ (__XCHG_EAX_ESBX__),\ ! 373: (__ulong_t) _EAX) ! 374: ! 375: #define ATOMIC_FETCH_CHAR(l) (((__atomic_char_t) (l)) [0]) ! 376: #define ATOMIC_FETCH_UCHAR(l) (((__atomic_uchar_t) (l)) [0]) ! 377: #define ATOMIC_FETCH_SHORT(l) (((__atomic_short_t) (l)) [0]) ! 378: #define ATOMIC_FETCH_USHORT(l) (((__atomic_ushort_t) (l)) [0]) ! 379: #define ATOMIC_FETCH_INT(l) (((__atomic_int_t) (l)) [0]) ! 380: #define ATOMIC_FETCH_UINT(l) (((__atomic_uint_t) (l)) [0]) ! 381: #define ATOMIC_FETCH_LONG(l) ((long) (_EAX = ((__atomic_long_t) (l)) [0])) ! 382: #define ATOMIC_FETCH_ULONG(l) ((__ulong_t) (_EAX = ((__atomic_ulong_t) (l)) [0])) ! 383: ! 384: #define ATOMIC_TEST_AND_SET_UCHAR(l) ATOMIC_FETCH_AND_STORE_UCHAR (l, -1) ! 385: ! 386: #define ATOMIC_CLEAR_UCHAR(l) ((void) (((__atomic_uchar_t) (l)) [0] = 0)) ! 387: #define ATOMIC_CLEAR_USHORT(l) ((void) (((__atomic_ushort_t) (l)) [0] = 0)) ! 388: ! 389: #define ATOMIC_STORE_UCHAR(l,v) ((void) (((__atomic_uchar_t) (l)) [0] = (v))) ! 390: ! 391: #if defined (__LARGE__) || defined (__HUGE__) || defined (__COMPACT__) ! 392: ! 393: /* ! 394: * The ATOMIC_FETCH_AND_STORE_PTR () operation cannot be performed in-line in ! 395: * BC++ 3.1 in large data models due to code-generation bugs that appear to ! 396: * be caused by a mix of problems casting 32-bit registers to pointers and ! 397: * other problems dealing with far-pointer-valued returns from in-line ! 398: * assembly. ! 399: */ ! 400: ! 401: #define ATOMIC_STORE_PTR(l,v) (__lockaddr (l), _EAX = (long) (v),\ ! 402: __emit__ (__XCHG_EAX_ESBX__)) ! 403: ! 404: #define ATOMIC_FETCH_PTR(l) ((void *) (_EAX = ((__atomic_ulong_t) (l)) [0])) ! 405: ! 406: #define ATOMIC_CLEAR_PTR(l) ATOMIC_STORE_PTR (l, 0) ! 407: ! 408: #else /* use simpler small-data version */ ! 409: ! 410: #define ATOMIC_FETCH_AND_STORE_PTR(l,v) (__lockaddr (l), _AX = (unsigned) (v),\ ! 411: __emit__ (__XCHG_AX_ESBX__), \ ! 412: (void *) _AX) ! 413: ! 414: #define ATOMIC_STORE_PTR(l,v) (__lockaddr (l), _AX = (unsigned) (v),\ ! 415: __emit__ (__XCHG_AX_ESBX__)) ! 416: ! 417: #define ATOMIC_FETCH_PTR(l) (((__atomic_ptr_t) (l)) [0]) ! 418: ! 419: #define ATOMIC_CLEAR_PTR(l) ATOMIC_STORE_PTR (l, 0) ! 420: ! 421: #endif /* small data model */ ! 422: ! 423: ! 424: #elif __COHERENT__ ! 425: ! 426: ! 427: #define ATOMIC_FETCH_CHAR(l) (((__atomic_char_t) (l)) [0]) ! 428: #define ATOMIC_FETCH_UCHAR(l) (((__atomic_uchar_t) (l)) [0]) ! 429: #define ATOMIC_FETCH_SHORT(l) (((__atomic_short_t) (l)) [0]) ! 430: #define ATOMIC_FETCH_USHORT(l) (((__atomic_ushort_t) (l)) [0]) ! 431: #define ATOMIC_FETCH_INT(l) (((__atomic_int_t) (l)) [0]) ! 432: #define ATOMIC_FETCH_UINT(l) (((__atomic_uint_t) (l)) [0]) ! 433: #define ATOMIC_FETCH_LONG(l) (((__atomic_long_t) (l)) [0]) ! 434: #define ATOMIC_FETCH_ULONG(l) (((__atomic_ulong_t) (l)) [0]) ! 435: #define ATOMIC_FETCH_PTR(l) (((__atomic_ptr_t) (l)) [0]) ! 436: ! 437: #define ATOMIC_TEST_AND_SET_UCHAR(l) ATOMIC_FETCH_AND_STORE_UCHAR (l, -1) ! 438: ! 439: #define ATOMIC_CLEAR_UCHAR(l) ((void) (((__atomic_uchar_t) (l)) [0] = 0)) ! 440: #define ATOMIC_CLEAR_USHORT(l) ((void) (((__atomic_ushort_t) (l)) [0] = 0)) ! 441: #define ATOMIC_CLEAR_PTR(l) ((void) (((__atomic_ptr_t) (l)) [0] = 0)) ! 442: ! 443: #define ATOMIC_STORE_UCHAR(l,v) ((void) (((__atomic_uchar_t) (l)) [0] = (v))) ! 444: #define ATOMIC_STORE_PTR(l,v) ((void) (((__atomic_ptr_t) (l)) [0] = (v))) ! 445: ! 446: #endif /* __COHERENT__ */ ! 447: ! 448: ! 449: #ifdef _CHECK_LOCK_TYPES ! 450: ! 451: #undef ATOMIC_FETCH_AND_STORE_CHAR ! 452: #undef ATOMIC_FETCH_AND_STORE_UCHAR ! 453: #undef ATOMIC_FETCH_AND_STORE_SHORT ! 454: #undef ATOMIC_FETCH_AND_STORE_USHORT ! 455: #undef ATOMIC_FETCH_AND_STORE_INT ! 456: #undef ATOMIC_FETCH_AND_STORE_UINT ! 457: #undef ATOMIC_FETCH_AND_STORE_LONG ! 458: #undef ATOMIC_FETCH_AND_STORE_ULONG ! 459: #undef ATOMIC_FETCH_AND_STORE_PTR ! 460: #undef ATOMIC_FETCH_CHAR ! 461: #undef ATOMIC_FETCH_UCHAR ! 462: #undef ATOMIC_FETCH_SHORT ! 463: #undef ATOMIC_FETCH_USHORT ! 464: #undef ATOMIC_FETCH_INT ! 465: #undef ATOMIC_FETCH_UINT ! 466: #undef ATOMIC_FETCH_LONG ! 467: #undef ATOMIC_FETCH_ULONG ! 468: #undef ATOMIC_FETCH_PTR ! 469: ! 470: #undef ATOMIC_CLEAR_UCHAR ! 471: #undef ATOMIC_CLEAR_USHORT ! 472: #undef ATOMIC_CLEAR_PTR ! 473: ! 474: #undef ATOMIC_STORE_UCHAR ! 475: #undef ATOMIC_STORE_PTR ! 476: ! 477: #endif /* defined (_CHECK_LOCK_TYPES) */ ! 478: ! 479: ! 480: __EXTERN_C_BEGIN__ ! 481: ! 482: __pl_t TEST_AND_SET_LOCK __PROTO ((__atomic_uchar_t _locked, ! 483: __pl_t _pl, ! 484: __CONST__ char * _name)); ! 485: ! 486: __EXTERN_C_END__ ! 487: ! 488: ! 489: #endif /* ! defined (__KERNEL_X86LOCK_H__) */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.