source: branches/libc-0.6/src/emx/include/sys/fmutex.h

Last change on this file was 2090, checked in by bird, 20 years ago

o Rewrote the libcXXXX.dll install rule to not play with emxload since

emxload sticks around when first loaded.

o Made unsetenv() cause tzset reload just like putenv() and setenv().
o Changed putenv() behaviour for removal (no '=' in input) to be identical

to unsetenv(). This solves duplicate variable testcase.

o Changed filestreams opened for both reading and writing to switch

more willingly between read and write mode.

o Made sscan() return EOF on EOF.
o Made sscan() skip blanks in input for '%%'.
o Implemented the stdio_unlocked stuff with BSD and GLIBC extension.

TODO: Require a new locktype which support recursive usage! Currently

a hack using 8 free flag bits is used.

o Corrected realpath() behaviour to return the path up to the failure

point on error. _realrealpath() also does this now.
(This also saves us a temp buffer and a copy of the result.)

o Fixed a bug in the handling of ".." in the path resolver.
o Extended that path resolver to check the directoryness of the input

according to flags and any trailing slashes.

o Change the path resolver to be very strict about UNC - UNC have exactly

two slashes at the start of the path.

  • Property cvs2svn:cvs-rev set to 1.7
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 4.0 KB
Line 
1/* sys/fmutex.h (emx+gcc) */
2
3/* Fast mutex semaphores. */
4
5/* This header requires <sys/builtin.h>. */
6
7#ifndef _SYS_FMUTEX_H
8#define _SYS_FMUTEX_H
9
10#include <sys/cdefs.h>
11#include <stdlib.h> /* need abort */
12#include <InnoTekLIBC/FastInfoBlocks.h>
13#include <386/builtin.h>
14
15__BEGIN_DECLS
16
17/* Constants for _fmutex.fs. See _fmutex_available() for ordering. */
18
19#define _FMS_AUTO_INITIALIZE (-1)
20#define _FMS_UNINIT 0
21#define _FMS_AVAILABLE 1
22#define _FMS_OWNED_SIMPLE 2
23#define _FMS_OWNED_HARD 3
24
25/* Constants for _fmutex_create() */
26
27#define _FMC_SHARED 0x01
28#define _FMC_MUST_COMPLETE 0x02
29#define _FMC_DUMMY 0x04 /* internal */
30
31/* Constants for _fmutex_request() */
32
33#define _FMR_IGNINT 0x01
34#define _FMR_NOWAIT 0x02
35
36/* We cannot use __attribute__ ((__packed__)) because G++ does not
37 support this. */
38
39#pragma pack(1)
40typedef struct
41{
42 /** Handle to event semaphore. */
43 unsigned long hev;
44 /** Semaphore status. */
45 volatile signed char fs;
46 /** Semaphore create flags. (_FMC_SHARED) */
47 unsigned char flags;
48 /** padding the struct to 16 bytes. */
49 unsigned char padding[2];
50 /** The (pid << 16) | tid of the owner. */
51 volatile unsigned Owner;
52 /** Descriptive name of the mutex. */
53 const char *pszDesc;
54} _fmutex;
55#pragma pack()
56
57#define _FMUTEX_INITIALIZER _FMUTEX_INITIALIZER_EX(0, __FILE__)
58#define _FMUTEX_INITIALIZER_EX(fFlags, pszDesc) { 0, _FMS_AUTO_INITIALIZE, fFlags, {0x42,0x42}, 0, pszDesc }
59
60
61unsigned __fmutex_request_internal (_fmutex *, unsigned, signed char);
62unsigned __fmutex_request_internal_must_complete (_fmutex *, unsigned);
63unsigned __fmutex_release_internal (_fmutex *);
64unsigned __fmutex_release_internal_must_complete (_fmutex *);
65
66
67static __inline__ unsigned _fmutex_request (_fmutex *sem, unsigned flags)
68{
69 if (!(sem->flags & _FMC_MUST_COMPLETE))
70 {
71 signed char fs = __cxchg (&sem->fs, _FMS_OWNED_SIMPLE);
72 if (fs == _FMS_AVAILABLE)
73 {
74 __atomic_xchg(&sem->Owner, fibGetTidPid());
75 return 0;
76 }
77 else
78 return __fmutex_request_internal (sem, flags, fs);
79 }
80 else
81 return __fmutex_request_internal_must_complete (sem, flags);
82}
83
84
85static __inline__ unsigned _fmutex_release (_fmutex *sem)
86{
87 if (!(sem->flags & _FMC_MUST_COMPLETE))
88 {
89 signed char fs;
90 __atomic_xchg(&sem->Owner, 0);
91 fs = __cxchg(&sem->fs, _FMS_AVAILABLE);
92 if (fs != _FMS_OWNED_HARD)
93 return 0;
94 else
95 return __fmutex_release_internal (sem);
96 }
97 else
98 return __fmutex_release_internal_must_complete (sem);
99}
100
101static __inline__ int _fmutex_available (_fmutex *sem)
102{
103 return sem->fs <= _FMS_AVAILABLE;
104}
105
106
107static __inline__ int _fmutex_is_owner (_fmutex *sem)
108{
109 return sem->fs > _FMS_AVAILABLE && sem->Owner == fibGetTidPid();
110}
111
112/**
113 * Release a semaphore in the child process after the
114 * semaphore was locked for the forking the parent.
115 *
116 * @param pSem Semaphore to unlock.
117 */
118static __inline__ void _fmutex_release_fork(_fmutex *pSem)
119{
120 pSem->fs = _FMS_AVAILABLE;
121 pSem->Owner = 0;
122}
123
124unsigned _fmutex_create (_fmutex *, unsigned);
125unsigned _fmutex_create2 (_fmutex *sem, unsigned, const char *);
126unsigned _fmutex_open (_fmutex *);
127unsigned _fmutex_close (_fmutex *);
128void _fmutex_dummy (_fmutex *);
129
130void _fmutex_checked_close(_fmutex *);
131void _fmutex_checked_create(_fmutex *, unsigned);
132void _fmutex_checked_create2(_fmutex *, unsigned, const char *);
133void _fmutex_checked_open(_fmutex *);
134void _fmutex_abort(_fmutex *, const char *);
135
136static __inline__ void _fmutex_checked_release (_fmutex * sem)
137{
138 if (sem->Owner != fibGetTidPid())
139 _fmutex_abort(sem, "release not owner");
140 if (_fmutex_release (sem) != 0)
141 _fmutex_abort(sem, "release");
142}
143
144static __inline__ void _fmutex_checked_request (_fmutex * sem, unsigned flags)
145{
146 if (_fmutex_request (sem, flags) != 0)
147 _fmutex_abort(sem, "request");
148}
149
150__END_DECLS
151
152#endif /* not _SYS_FMUTEX_H */
153
Note: See TracBrowser for help on using the repository browser.