ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/sysdeps.h
Revision: 1.19
Committed: 2003-12-31T18:16:55Z (20 years, 5 months ago) by gbeauche
Content type: text/plain
Branch: MAIN
Changes since 1.18: +19 -0 lines
Log Message:
Add fast X11 display locking routines based on spinlocks, or on pthreads
in the worst case. Optimize out GetScrap() case when we already own the
selection. i.e. make it smoother. Use our own XDisplay{Un,}Lock() routines.

File Contents

# Content
1 /*
2 * sysdeps.h - System dependent definitions for Linux
3 *
4 * SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21 #ifndef SYSDEPS_H
22 #define SYSDEPS_H
23
24 #ifndef __STDC__
25 #error "Your compiler is not ANSI. Get a real one."
26 #endif
27
28 #include "config.h"
29 #include "user_strings_unix.h"
30
31 #ifndef STDC_HEADERS
32 #error "You don't have ANSI C header files."
33 #endif
34
35 #ifdef HAVE_UNISTD_H
36 # include <sys/types.h>
37 # include <unistd.h>
38 #endif
39
40 #include <netinet/in.h>
41 #include <assert.h>
42 #include <stdio.h>
43 #include <stdlib.h>
44 #include <string.h>
45 #include <signal.h>
46
47 #ifdef HAVE_FCNTL_H
48 # include <fcntl.h>
49 #endif
50
51 #ifdef TIME_WITH_SYS_TIME
52 # include <sys/time.h>
53 # include <time.h>
54 #else
55 # ifdef HAVE_SYS_TIME_H
56 # include <sys/time.h>
57 # else
58 # include <time.h>
59 # endif
60 #endif
61
62 // Define for external components
63 #define SHEEPSHAVER 1
64
65 // Mac and host address space are the same
66 #define REAL_ADDRESSING 1
67
68 #define POWERPC_ROM 1
69
70 #if EMULATED_PPC
71 // Handle interrupts asynchronously?
72 #define ASYNC_IRQ 0
73 // Mac ROM is write protected when banked memory is used
74 #if REAL_ADDRESSING || DIRECT_ADDRESSING
75 # define ROM_IS_WRITE_PROTECTED 0
76 # define USE_SCRATCHMEM_SUBTERFUGE 1
77 #else
78 # define ROM_IS_WRITE_PROTECTED 1
79 #endif
80 // Configure PowerPC emulator
81 #define PPC_CHECK_INTERRUPTS (ASYNC_IRQ ? 0 : 1)
82 #define PPC_DECODE_CACHE 1
83 #define PPC_FLIGHT_RECORDER 1
84 #define PPC_PROFILE_COMPILE_TIME 0
85 #define PPC_PROFILE_GENERIC_CALLS 0
86 #define KPX_MAX_CPUS 1
87 #else
88 // Mac ROM is write protected
89 #define ROM_IS_WRITE_PROTECTED 1
90 #define USE_SCRATCHMEM_SUBTERFUGE 0
91 #endif
92
93 // Data types
94 typedef unsigned char uint8;
95 typedef signed char int8;
96 #if SIZEOF_SHORT == 2
97 typedef unsigned short uint16;
98 typedef short int16;
99 #elif SIZEOF_INT == 2
100 typedef unsigned int uint16;
101 typedef int int16;
102 #else
103 #error "No 2 byte type, you lose."
104 #endif
105 #if SIZEOF_INT == 4
106 typedef unsigned int uint32;
107 typedef int int32;
108 #elif SIZEOF_LONG == 4
109 typedef unsigned long uint32;
110 typedef long int32;
111 #else
112 #error "No 4 byte type, you lose."
113 #endif
114 #if SIZEOF_LONG == 8
115 typedef unsigned long uint64;
116 typedef long int64;
117 #define VAL64(a) (a ## l)
118 #define UVAL64(a) (a ## ul)
119 #elif SIZEOF_LONG_LONG == 8
120 typedef unsigned long long uint64;
121 typedef long long int64;
122 #define VAL64(a) (a ## LL)
123 #define UVAL64(a) (a ## uLL)
124 #else
125 #error "No 8 byte type, you lose."
126 #endif
127 #if SIZEOF_VOID_P == 4
128 typedef uint32 uintptr;
129 typedef int32 intptr;
130 #elif SIZEOF_VOID_P == 8
131 typedef uint64 uintptr;
132 typedef int64 intptr;
133 #else
134 #error "Unsupported size of pointer"
135 #endif
136
137 /**
138 * Helper functions to byteswap data
139 **/
140
141 #if defined(__GNUC__)
142 #if defined(__x86_64__)
143 // Linux/AMD64 currently has no asm optimized bswap_32() in <byteswap.h>
144 #define opt_bswap_32 do_opt_bswap_32
145 static inline uint32 do_opt_bswap_32(uint32 x)
146 {
147 uint32 v;
148 __asm__ __volatile__ ("bswap %0" : "=r" (v) : "0" (x));
149 return v;
150 }
151 #endif
152 #endif
153
154 #ifdef HAVE_BYTESWAP_H
155 #include <byteswap.h>
156 #endif
157
158 #ifdef opt_bswap_16
159 #undef bswap_16
160 #define bswap_16 opt_bswap_16
161 #endif
162 #ifndef bswap_16
163 #define bswap_16 generic_bswap_16
164 #endif
165
166 static inline uint16 generic_bswap_16(uint16 x)
167 {
168 return ((x & 0xff) << 8) | ((x >> 8) & 0xff);
169 }
170
171 #ifdef opt_bswap_32
172 #undef bswap_32
173 #define bswap_32 opt_bswap_32
174 #endif
175 #ifndef bswap_32
176 #define bswap_32 generic_bswap_32
177 #endif
178
179 static inline uint32 generic_bswap_32(uint32 x)
180 {
181 return (((x & 0xff000000) >> 24) |
182 ((x & 0x00ff0000) >> 8) |
183 ((x & 0x0000ff00) << 8) |
184 ((x & 0x000000ff) << 24) );
185 }
186
187 #ifdef opt_bswap_64
188 #undef bswap_64
189 #define bswap_64 opt_bswap_64
190 #endif
191 #ifndef bswap_64
192 #define bswap_64 generic_bswap_64
193 #endif
194
195 static inline uint64 generic_bswap_64(uint64 x)
196 {
197 return (((x & UVAL64(0xff00000000000000)) >> 56) |
198 ((x & UVAL64(0x00ff000000000000)) >> 40) |
199 ((x & UVAL64(0x0000ff0000000000)) >> 24) |
200 ((x & UVAL64(0x000000ff00000000)) >> 8) |
201 ((x & UVAL64(0x00000000ff000000)) << 8) |
202 ((x & UVAL64(0x0000000000ff0000)) << 24) |
203 ((x & UVAL64(0x000000000000ff00)) << 40) |
204 ((x & UVAL64(0x00000000000000ff)) << 56) );
205 }
206
207 #ifdef WORDS_BIGENDIAN
208 static inline uint16 tswap16(uint16 x) { return x; }
209 static inline uint32 tswap32(uint32 x) { return x; }
210 static inline uint64 tswap64(uint64 x) { return x; }
211 #else
212 static inline uint16 tswap16(uint16 x) { return bswap_16(x); }
213 static inline uint32 tswap32(uint32 x) { return bswap_32(x); }
214 static inline uint64 tswap64(uint64 x) { return bswap_64(x); }
215 #endif
216
217 // spin locks
218 #ifdef __GNUC__
219
220 #ifdef __powerpc__
221 #define HAVE_TEST_AND_SET 1
222 static inline int testandset(int *p)
223 {
224 int ret;
225 __asm__ __volatile__("0: lwarx %0,0,%1 ;"
226 " xor. %0,%3,%0;"
227 " bne 1f;"
228 " stwcx. %2,0,%1;"
229 " bne- 0b;"
230 "1: "
231 : "=&r" (ret)
232 : "r" (p), "r" (1), "r" (0)
233 : "cr0", "memory");
234 return ret;
235 }
236 #endif
237
238 #ifdef __i386__
239 #define HAVE_TEST_AND_SET 1
240 static inline int testandset(int *p)
241 {
242 char ret;
243 long int readval;
244
245 __asm__ __volatile__("lock; cmpxchgl %3, %1; sete %0"
246 : "=q" (ret), "=m" (*p), "=a" (readval)
247 : "r" (1), "m" (*p), "a" (0)
248 : "memory");
249 return ret;
250 }
251 #endif
252
253 #ifdef __s390__
254 #define HAVE_TEST_AND_SET 1
255 static inline int testandset(int *p)
256 {
257 int ret;
258
259 __asm__ __volatile__("0: cs %0,%1,0(%2)\n"
260 " jl 0b"
261 : "=&d" (ret)
262 : "r" (1), "a" (p), "0" (*p)
263 : "cc", "memory" );
264 return ret;
265 }
266 #endif
267
268 #ifdef __alpha__
269 #define HAVE_TEST_AND_SET 1
270 static inline int testandset(int *p)
271 {
272 int ret;
273 unsigned long one;
274
275 __asm__ __volatile__("0: mov 1,%2\n"
276 " ldl_l %0,%1\n"
277 " stl_c %2,%1\n"
278 " beq %2,1f\n"
279 ".subsection 2\n"
280 "1: br 0b\n"
281 ".previous"
282 : "=r" (ret), "=m" (*p), "=r" (one)
283 : "m" (*p));
284 return ret;
285 }
286 #endif
287
288 #ifdef __sparc__
289 #define HAVE_TEST_AND_SET 1
290 static inline int testandset(int *p)
291 {
292 int ret;
293
294 __asm__ __volatile__("ldstub [%1], %0"
295 : "=r" (ret)
296 : "r" (p)
297 : "memory");
298
299 return (ret ? 1 : 0);
300 }
301 #endif
302
303 #ifdef __arm__
304 #define HAVE_TEST_AND_SET 1
305 static inline int testandset(int *p)
306 {
307 register unsigned int ret;
308 __asm__ __volatile__("swp %0, %1, [%2]"
309 : "=r"(ret)
310 : "0"(1), "r"(p));
311
312 return ret;
313 }
314 #endif
315
316 #endif /* __GNUC__ */
317
318 #if HAVE_TEST_AND_SET
319 #define HAVE_SPINLOCKS 1
320 typedef int spinlock_t;
321
322 static const spinlock_t SPIN_LOCK_UNLOCKED = 0;
323
324 static inline void spin_lock(spinlock_t *lock)
325 {
326 while (testandset(lock));
327 }
328
329 static inline void spin_unlock(spinlock_t *lock)
330 {
331 *lock = 0;
332 }
333
334 static inline int spin_trylock(spinlock_t *lock)
335 {
336 return !testandset(lock);
337 }
338 #endif
339
340 // Time data type for Time Manager emulation
341 #ifdef HAVE_CLOCK_GETTIME
342 typedef struct timespec tm_time_t;
343 #else
344 typedef struct timeval tm_time_t;
345 #endif
346
347 // Timing functions
348 extern uint64 GetTicks_usec(void);
349 extern void Delay_usec(uint32 usec);
350
351 // Setup pthread attributes
352 extern void Set_pthread_attr(pthread_attr_t *attr, int priority);
353
354 // Various definitions
355 typedef struct rgb_color {
356 uint8 red;
357 uint8 green;
358 uint8 blue;
359 uint8 alpha;
360 } rgb_color;
361
362 // X11 display fast locks
363 #ifdef HAVE_SPINLOCKS
364 #define X11_LOCK_TYPE spinlock_t
365 #define X11_LOCK_INIT SPIN_LOCK_UNLOCKED
366 #define XDisplayLock() spin_lock(&x_display_lock)
367 #define XDisplayUnlock() spin_unlock(&x_display_lock)
368 #elif defined(HAVE_PTHREADS)
369 #define X11_LOCK_TYPE pthread_mutex_t
370 #define X11_LOCK_INIT PTHREAD_MUTEX_INITIALIZER
371 #define XDisplayLock() pthread_mutex_lock(&x_display_lock);
372 #define XDisplayUnlock() pthread_mutex_unlock(&x_display_lock);
373 #else
374 #define XDisplayLock()
375 #define XDisplayUnlock()
376 #endif
377 #ifdef X11_LOCK_TYPE
378 extern X11_LOCK_TYPE x_display_lock;
379 #endif
380
381 // Macro for calling MacOS routines
382 #define CallMacOS(type, tvect) call_macos((uint32)tvect)
383 #define CallMacOS1(type, tvect, arg1) call_macos1((uint32)tvect, (uint32)arg1)
384 #define CallMacOS2(type, tvect, arg1, arg2) call_macos2((uint32)tvect, (uint32)arg1, (uint32)arg2)
385 #define CallMacOS3(type, tvect, arg1, arg2, arg3) call_macos3((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3)
386 #define CallMacOS4(type, tvect, arg1, arg2, arg3, arg4) call_macos4((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3, (uint32)arg4)
387 #define CallMacOS5(type, tvect, arg1, arg2, arg3, arg4, arg5) call_macos5((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3, (uint32)arg4, (uint32)arg5)
388 #define CallMacOS6(type, tvect, arg1, arg2, arg3, arg4, arg5, arg6) call_macos6((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3, (uint32)arg4, (uint32)arg5, (uint32)arg6)
389 #define CallMacOS7(type, tvect, arg1, arg2, arg3, arg4, arg5, arg6, arg7) call_macos7((uint32)tvect, (uint32)arg1, (uint32)arg2, (uint32)arg3, (uint32)arg4, (uint32)arg5, (uint32)arg6, (uint32)arg7)
390
391 #ifdef __cplusplus
392 extern "C" {
393 #endif
394 extern uint32 call_macos(uint32 tvect);
395 extern uint32 call_macos1(uint32 tvect, uint32 arg1);
396 extern uint32 call_macos2(uint32 tvect, uint32 arg1, uint32 arg2);
397 extern uint32 call_macos3(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3);
398 extern uint32 call_macos4(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4);
399 extern uint32 call_macos5(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5);
400 extern uint32 call_macos6(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5, uint32 arg6);
401 extern uint32 call_macos7(uint32 tvect, uint32 arg1, uint32 arg2, uint32 arg3, uint32 arg4, uint32 arg5, uint32 arg6, uint32 arg7);
402 #ifdef __cplusplus
403 }
404 #endif
405
406 #endif