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