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, 9 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

# User Rev Content
1 cebix 1.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 gbeauche 1.5 // Define for external components
63     #define SHEEPSHAVER 1
64    
65 gbeauche 1.4 // Mac and host address space are the same
66     #define REAL_ADDRESSING 1
67    
68 gbeauche 1.5 #define POWERPC_ROM 1
69    
70     #if EMULATED_PPC
71 gbeauche 1.7 // Handle interrupts asynchronously?
72     #define ASYNC_IRQ 0
73 gbeauche 1.5 // 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 cebix 1.1 #else
78 gbeauche 1.5 # define ROM_IS_WRITE_PROTECTED 1
79     #endif
80 gbeauche 1.9 // Configure PowerPC emulator
81 gbeauche 1.13 #define PPC_CHECK_INTERRUPTS (ASYNC_IRQ ? 0 : 1)
82 gbeauche 1.14 #define PPC_DECODE_CACHE 1
83 gbeauche 1.10 #define PPC_FLIGHT_RECORDER 1
84 gbeauche 1.17 #define PPC_PROFILE_COMPILE_TIME 0
85     #define PPC_PROFILE_GENERIC_CALLS 0
86 gbeauche 1.16 #define KPX_MAX_CPUS 1
87 gbeauche 1.5 #else
88     // Mac ROM is write protected
89     #define ROM_IS_WRITE_PROTECTED 1
90     #define USE_SCRATCHMEM_SUBTERFUGE 0
91 cebix 1.1 #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 gbeauche 1.3 #define VAL64(a) (a ## l)
118     #define UVAL64(a) (a ## ul)
119 cebix 1.1 #elif SIZEOF_LONG_LONG == 8
120     typedef unsigned long long uint64;
121     typedef long long int64;
122 gbeauche 1.3 #define VAL64(a) (a ## LL)
123     #define UVAL64(a) (a ## uLL)
124 cebix 1.1 #else
125     #error "No 8 byte type, you lose."
126     #endif
127 gbeauche 1.3 #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 gbeauche 1.5 #endif
136    
137 gbeauche 1.15 /**
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 gbeauche 1.5 #ifdef HAVE_BYTESWAP_H
155     #include <byteswap.h>
156     #endif
157    
158 gbeauche 1.15 #ifdef opt_bswap_16
159     #undef bswap_16
160     #define bswap_16 opt_bswap_16
161     #endif
162 gbeauche 1.5 #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 gbeauche 1.15 #ifdef opt_bswap_32
172     #undef bswap_32
173     #define bswap_32 opt_bswap_32
174     #endif
175 gbeauche 1.5 #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 gbeauche 1.15 #ifdef opt_bswap_64
188     #undef bswap_64
189     #define bswap_64 opt_bswap_64
190     #endif
191 gbeauche 1.5 #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 gbeauche 1.3 #endif
216 cebix 1.1
217 gbeauche 1.6 // 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 gbeauche 1.8 static const spinlock_t SPIN_LOCK_UNLOCKED = 0;
323 gbeauche 1.6
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 cebix 1.1 // 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 gbeauche 1.18 // Timing functions
348     extern uint64 GetTicks_usec(void);
349     extern void Delay_usec(uint32 usec);
350    
351 cebix 1.2 // Setup pthread attributes
352     extern void Set_pthread_attr(pthread_attr_t *attr, int priority);
353    
354 cebix 1.1 // Various definitions
355     typedef struct rgb_color {
356     uint8 red;
357     uint8 green;
358     uint8 blue;
359     uint8 alpha;
360     } rgb_color;
361    
362 gbeauche 1.19 // 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 cebix 1.1 // 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 gbeauche 1.3 #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 cebix 1.1
406     #endif