nsprpub/pr/include/md/_linux.h

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

michael@0 1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /*
michael@0 7 * This file is used by not only Linux but also other glibc systems
michael@0 8 * such as GNU/Hurd and GNU/k*BSD.
michael@0 9 */
michael@0 10
michael@0 11 #ifndef nspr_linux_defs_h___
michael@0 12 #define nspr_linux_defs_h___
michael@0 13
michael@0 14 #include "prthread.h"
michael@0 15
michael@0 16 /*
michael@0 17 * Internal configuration macros
michael@0 18 */
michael@0 19
michael@0 20 #define PR_LINKER_ARCH "linux"
michael@0 21 #define _PR_SI_SYSNAME "LINUX"
michael@0 22 #ifdef __powerpc64__
michael@0 23 #define _PR_SI_ARCHITECTURE "ppc64"
michael@0 24 #elif defined(__powerpc__)
michael@0 25 #define _PR_SI_ARCHITECTURE "ppc"
michael@0 26 #elif defined(__alpha)
michael@0 27 #define _PR_SI_ARCHITECTURE "alpha"
michael@0 28 #elif defined(__ia64__)
michael@0 29 #define _PR_SI_ARCHITECTURE "ia64"
michael@0 30 #elif defined(__x86_64__)
michael@0 31 #define _PR_SI_ARCHITECTURE "x86-64"
michael@0 32 #elif defined(__mc68000__)
michael@0 33 #define _PR_SI_ARCHITECTURE "m68k"
michael@0 34 #elif defined(__sparc__) && defined(__arch64__)
michael@0 35 #define _PR_SI_ARCHITECTURE "sparc64"
michael@0 36 #elif defined(__sparc__)
michael@0 37 #define _PR_SI_ARCHITECTURE "sparc"
michael@0 38 #elif defined(__i386__)
michael@0 39 #define _PR_SI_ARCHITECTURE "x86"
michael@0 40 #elif defined(__mips__)
michael@0 41 #define _PR_SI_ARCHITECTURE "mips"
michael@0 42 #elif defined(__arm__)
michael@0 43 #define _PR_SI_ARCHITECTURE "arm"
michael@0 44 #elif defined(__aarch64__)
michael@0 45 #define _PR_SI_ARCHITECTURE "aarch64"
michael@0 46 #elif defined(__hppa__)
michael@0 47 #define _PR_SI_ARCHITECTURE "hppa"
michael@0 48 #elif defined(__s390x__)
michael@0 49 #define _PR_SI_ARCHITECTURE "s390x"
michael@0 50 #elif defined(__s390__)
michael@0 51 #define _PR_SI_ARCHITECTURE "s390"
michael@0 52 #elif defined(__sh__)
michael@0 53 #define _PR_SI_ARCHITECTURE "sh"
michael@0 54 #elif defined(__avr32__)
michael@0 55 #define _PR_SI_ARCHITECTURE "avr32"
michael@0 56 #elif defined(__m32r__)
michael@0 57 #define _PR_SI_ARCHITECTURE "m32r"
michael@0 58 #else
michael@0 59 #error "Unknown CPU architecture"
michael@0 60 #endif
michael@0 61 #define PR_DLL_SUFFIX ".so"
michael@0 62
michael@0 63 #define _PR_VMBASE 0x30000000
michael@0 64 #define _PR_STACK_VMBASE 0x50000000
michael@0 65 #define _MD_DEFAULT_STACK_SIZE 65536L
michael@0 66 #define _MD_MMAP_FLAGS MAP_PRIVATE
michael@0 67
michael@0 68 #if defined(__aarch64__)
michael@0 69 #define _MD_MINIMUM_STACK_SIZE 0x20000
michael@0 70 #endif
michael@0 71
michael@0 72 #undef HAVE_STACK_GROWING_UP
michael@0 73
michael@0 74 /*
michael@0 75 * Elf linux supports dl* functions
michael@0 76 */
michael@0 77 #define HAVE_DLL
michael@0 78 #define USE_DLFCN
michael@0 79 #if defined(ANDROID)
michael@0 80 #define NO_DLOPEN_NULL
michael@0 81 #endif
michael@0 82
michael@0 83 #if defined(__FreeBSD_kernel__) || defined(__GNU__)
michael@0 84 #define _PR_HAVE_SOCKADDR_LEN
michael@0 85 #endif
michael@0 86
michael@0 87 #if defined(__i386__)
michael@0 88 #define _PR_HAVE_ATOMIC_OPS
michael@0 89 #define _MD_INIT_ATOMIC()
michael@0 90 extern PRInt32 _PR_x86_AtomicIncrement(PRInt32 *val);
michael@0 91 #define _MD_ATOMIC_INCREMENT _PR_x86_AtomicIncrement
michael@0 92 extern PRInt32 _PR_x86_AtomicDecrement(PRInt32 *val);
michael@0 93 #define _MD_ATOMIC_DECREMENT _PR_x86_AtomicDecrement
michael@0 94 extern PRInt32 _PR_x86_AtomicAdd(PRInt32 *ptr, PRInt32 val);
michael@0 95 #define _MD_ATOMIC_ADD _PR_x86_AtomicAdd
michael@0 96 extern PRInt32 _PR_x86_AtomicSet(PRInt32 *val, PRInt32 newval);
michael@0 97 #define _MD_ATOMIC_SET _PR_x86_AtomicSet
michael@0 98 #endif
michael@0 99
michael@0 100 #if defined(__ia64__)
michael@0 101 #define _PR_HAVE_ATOMIC_OPS
michael@0 102 #define _MD_INIT_ATOMIC()
michael@0 103 extern PRInt32 _PR_ia64_AtomicIncrement(PRInt32 *val);
michael@0 104 #define _MD_ATOMIC_INCREMENT _PR_ia64_AtomicIncrement
michael@0 105 extern PRInt32 _PR_ia64_AtomicDecrement(PRInt32 *val);
michael@0 106 #define _MD_ATOMIC_DECREMENT _PR_ia64_AtomicDecrement
michael@0 107 extern PRInt32 _PR_ia64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
michael@0 108 #define _MD_ATOMIC_ADD _PR_ia64_AtomicAdd
michael@0 109 extern PRInt32 _PR_ia64_AtomicSet(PRInt32 *val, PRInt32 newval);
michael@0 110 #define _MD_ATOMIC_SET _PR_ia64_AtomicSet
michael@0 111 #endif
michael@0 112
michael@0 113 #if defined(__x86_64__)
michael@0 114 #define _PR_HAVE_ATOMIC_OPS
michael@0 115 #define _MD_INIT_ATOMIC()
michael@0 116 extern PRInt32 _PR_x86_64_AtomicIncrement(PRInt32 *val);
michael@0 117 #define _MD_ATOMIC_INCREMENT _PR_x86_64_AtomicIncrement
michael@0 118 extern PRInt32 _PR_x86_64_AtomicDecrement(PRInt32 *val);
michael@0 119 #define _MD_ATOMIC_DECREMENT _PR_x86_64_AtomicDecrement
michael@0 120 extern PRInt32 _PR_x86_64_AtomicAdd(PRInt32 *ptr, PRInt32 val);
michael@0 121 #define _MD_ATOMIC_ADD _PR_x86_64_AtomicAdd
michael@0 122 extern PRInt32 _PR_x86_64_AtomicSet(PRInt32 *val, PRInt32 newval);
michael@0 123 #define _MD_ATOMIC_SET _PR_x86_64_AtomicSet
michael@0 124 #endif
michael@0 125
michael@0 126 #if defined(__powerpc__) && !defined(__powerpc64__)
michael@0 127 #define _PR_HAVE_ATOMIC_OPS
michael@0 128 #define _MD_INIT_ATOMIC()
michael@0 129 extern PRInt32 _PR_ppc_AtomicIncrement(PRInt32 *val);
michael@0 130 #define _MD_ATOMIC_INCREMENT _PR_ppc_AtomicIncrement
michael@0 131 extern PRInt32 _PR_ppc_AtomicDecrement(PRInt32 *val);
michael@0 132 #define _MD_ATOMIC_DECREMENT _PR_ppc_AtomicDecrement
michael@0 133 extern PRInt32 _PR_ppc_AtomicAdd(PRInt32 *ptr, PRInt32 val);
michael@0 134 #define _MD_ATOMIC_ADD _PR_ppc_AtomicAdd
michael@0 135 extern PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval);
michael@0 136 #define _MD_ATOMIC_SET _PR_ppc_AtomicSet
michael@0 137 #endif
michael@0 138
michael@0 139 #if defined(__powerpc64__)
michael@0 140 #if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
michael@0 141 /* Use GCC built-in functions */
michael@0 142 #define _PR_HAVE_ATOMIC_OPS
michael@0 143 #define _MD_INIT_ATOMIC()
michael@0 144 #define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1)
michael@0 145 #define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1)
michael@0 146 #define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i)
michael@0 147 #define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv)
michael@0 148 #endif
michael@0 149 #endif
michael@0 150
michael@0 151 #if defined(__alpha)
michael@0 152 #define _PR_HAVE_ATOMIC_OPS
michael@0 153 #define _MD_INIT_ATOMIC()
michael@0 154 #define _MD_ATOMIC_ADD(ptr, i) ({ \
michael@0 155 PRInt32 __atomic_tmp, __atomic_ret; \
michael@0 156 __asm__ __volatile__( \
michael@0 157 "1: ldl_l %[ret], %[val] \n" \
michael@0 158 " addl %[ret], %[inc], %[tmp] \n" \
michael@0 159 " addl %[ret], %[inc], %[ret] \n" \
michael@0 160 " stl_c %[tmp], %[val] \n" \
michael@0 161 " beq %[tmp], 2f \n" \
michael@0 162 ".subsection 2 \n" \
michael@0 163 "2: br 1b \n" \
michael@0 164 ".previous" \
michael@0 165 : [ret] "=&r" (__atomic_ret), \
michael@0 166 [tmp] "=&r" (__atomic_tmp), \
michael@0 167 [val] "=m" (*ptr) \
michael@0 168 : [inc] "Ir" (i), "m" (*ptr)); \
michael@0 169 __atomic_ret; \
michael@0 170 })
michael@0 171 #define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1)
michael@0 172 #define _MD_ATOMIC_DECREMENT(ptr) ({ \
michael@0 173 PRInt32 __atomic_tmp, __atomic_ret; \
michael@0 174 __asm__ __volatile__( \
michael@0 175 "1: ldl_l %[ret], %[val] \n" \
michael@0 176 " subl %[ret], 1, %[tmp] \n" \
michael@0 177 " subl %[ret], 1, %[ret] \n" \
michael@0 178 " stl_c %[tmp], %[val] \n" \
michael@0 179 " beq %[tmp], 2f \n" \
michael@0 180 ".subsection 2 \n" \
michael@0 181 "2: br 1b \n" \
michael@0 182 ".previous" \
michael@0 183 : [ret] "=&r" (__atomic_ret), \
michael@0 184 [tmp] "=&r" (__atomic_tmp), \
michael@0 185 [val] "=m" (*ptr) \
michael@0 186 : "m" (*ptr)); \
michael@0 187 __atomic_ret; \
michael@0 188 })
michael@0 189 #define _MD_ATOMIC_SET(ptr, n) ({ \
michael@0 190 PRInt32 __atomic_tmp, __atomic_ret; \
michael@0 191 __asm__ __volatile__( \
michael@0 192 "1: ldl_l %[ret], %[val] \n" \
michael@0 193 " mov %[newval], %[tmp] \n" \
michael@0 194 " stl_c %[tmp], %[val] \n" \
michael@0 195 " beq %[tmp], 2f \n" \
michael@0 196 ".subsection 2 \n" \
michael@0 197 "2: br 1b \n" \
michael@0 198 ".previous" \
michael@0 199 : [ret] "=&r" (__atomic_ret), \
michael@0 200 [tmp] "=&r"(__atomic_tmp), \
michael@0 201 [val] "=m" (*ptr) \
michael@0 202 : [newval] "Ir" (n), "m" (*ptr)); \
michael@0 203 __atomic_ret; \
michael@0 204 })
michael@0 205 #endif
michael@0 206
michael@0 207 #if defined(__arm__) || defined(__aarch64__)
michael@0 208 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
michael@0 209 /* Use GCC built-in functions */
michael@0 210 #define _PR_HAVE_ATOMIC_OPS
michael@0 211 #define _MD_INIT_ATOMIC()
michael@0 212
michael@0 213 #define _MD_ATOMIC_INCREMENT(ptr) __sync_add_and_fetch(ptr, 1)
michael@0 214 #define _MD_ATOMIC_DECREMENT(ptr) __sync_sub_and_fetch(ptr, 1)
michael@0 215 #define _MD_ATOMIC_SET(ptr, nv) __sync_lock_test_and_set(ptr, nv)
michael@0 216 #define _MD_ATOMIC_ADD(ptr, i) __sync_add_and_fetch(ptr, i)
michael@0 217
michael@0 218 #elif defined(_PR_ARM_KUSER)
michael@0 219 #define _PR_HAVE_ATOMIC_OPS
michael@0 220 #define _MD_INIT_ATOMIC()
michael@0 221
michael@0 222 /*
michael@0 223 * The kernel provides this helper function at a fixed address with a fixed
michael@0 224 * ABI signature, directly callable from user space.
michael@0 225 *
michael@0 226 * Definition:
michael@0 227 * Atomically store newval in *ptr if *ptr is equal to oldval.
michael@0 228 * Return zero if *ptr was changed or non-zero if no exchange happened.
michael@0 229 */
michael@0 230 typedef int (__kernel_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
michael@0 231 #define __kernel_cmpxchg (*(__kernel_cmpxchg_t *)0xffff0fc0)
michael@0 232
michael@0 233 #define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1)
michael@0 234 #define _MD_ATOMIC_DECREMENT(ptr) _MD_ATOMIC_ADD(ptr, -1)
michael@0 235
michael@0 236 static inline PRInt32 _MD_ATOMIC_ADD(PRInt32 *ptr, PRInt32 n)
michael@0 237 {
michael@0 238 PRInt32 ov, nv;
michael@0 239 volatile PRInt32 *vp = ptr;
michael@0 240
michael@0 241 do {
michael@0 242 ov = *vp;
michael@0 243 nv = ov + n;
michael@0 244 } while (__kernel_cmpxchg(ov, nv, vp));
michael@0 245
michael@0 246 return nv;
michael@0 247 }
michael@0 248
michael@0 249 static inline PRInt32 _MD_ATOMIC_SET(PRInt32 *ptr, PRInt32 nv)
michael@0 250 {
michael@0 251 PRInt32 ov;
michael@0 252 volatile PRInt32 *vp = ptr;
michael@0 253
michael@0 254 do {
michael@0 255 ov = *vp;
michael@0 256 } while (__kernel_cmpxchg(ov, nv, vp));
michael@0 257
michael@0 258 return ov;
michael@0 259 }
michael@0 260 #endif
michael@0 261 #endif /* __arm__ */
michael@0 262
michael@0 263 #define USE_SETJMP
michael@0 264 #if (defined(__GLIBC__) && __GLIBC__ >= 2) || defined(ANDROID)
michael@0 265 #define _PR_POLL_AVAILABLE
michael@0 266 #endif
michael@0 267 #undef _PR_USE_POLL
michael@0 268 #define _PR_STAT_HAS_ONLY_ST_ATIME
michael@0 269 #if defined(__alpha) || defined(__ia64__)
michael@0 270 #define _PR_HAVE_LARGE_OFF_T
michael@0 271 #elif (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \
michael@0 272 || defined(ANDROID)
michael@0 273 #define _PR_HAVE_OFF64_T
michael@0 274 #else
michael@0 275 #define _PR_NO_LARGE_FILES
michael@0 276 #endif
michael@0 277 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \
michael@0 278 || defined(ANDROID)
michael@0 279 #define _PR_INET6
michael@0 280 #define _PR_HAVE_INET_NTOP
michael@0 281 #define _PR_HAVE_GETHOSTBYNAME2
michael@0 282 #define _PR_HAVE_GETADDRINFO
michael@0 283 #define _PR_INET6_PROBE
michael@0 284 #endif
michael@0 285 #ifndef ANDROID
michael@0 286 #define _PR_HAVE_SYSV_SEMAPHORES
michael@0 287 #define PR_HAVE_SYSV_NAMED_SHARED_MEMORY
michael@0 288 #endif
michael@0 289 /* Android has gethostbyname_r but not gethostbyaddr_r or gethostbyname2_r. */
michael@0 290 #if (__GLIBC__ >= 2) && defined(_PR_PTHREADS)
michael@0 291 #define _PR_HAVE_GETHOST_R
michael@0 292 #define _PR_HAVE_GETHOST_R_INT
michael@0 293 #endif
michael@0 294
michael@0 295 #ifdef _PR_PTHREADS
michael@0 296
michael@0 297 extern void _MD_CleanupBeforeExit(void);
michael@0 298 #define _MD_CLEANUP_BEFORE_EXIT _MD_CleanupBeforeExit
michael@0 299
michael@0 300 #else /* ! _PR_PTHREADS */
michael@0 301
michael@0 302 #include <setjmp.h>
michael@0 303
michael@0 304 #define PR_CONTEXT_TYPE sigjmp_buf
michael@0 305
michael@0 306 #define CONTEXT(_th) ((_th)->md.context)
michael@0 307
michael@0 308 #ifdef __powerpc__
michael@0 309 /*
michael@0 310 * PowerPC based MkLinux
michael@0 311 *
michael@0 312 * On the PowerPC, the new style jmp_buf isn't used until glibc
michael@0 313 * 2.1.
michael@0 314 */
michael@0 315 #if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
michael@0 316 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_GPR1]
michael@0 317 #else
michael@0 318 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__misc[0]
michael@0 319 #endif /* glibc 2.1 or later */
michael@0 320 #define _MD_SET_FP(_t, val)
michael@0 321 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 322 #define _MD_GET_FP_PTR(_t) ((void *) 0)
michael@0 323 /* aix = 64, macos = 70 */
michael@0 324 #define PR_NUM_GCREGS 64
michael@0 325
michael@0 326 #elif defined(__alpha)
michael@0 327 /* Alpha based Linux */
michael@0 328
michael@0 329 #if defined(__GLIBC__) && __GLIBC__ >= 2
michael@0 330 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
michael@0 331 #define _MD_SET_FP(_t, val)
michael@0 332 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 333 #define _MD_GET_FP_PTR(_t) ((void *) 0)
michael@0 334 #define _MD_SP_TYPE long int
michael@0 335 #else
michael@0 336 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
michael@0 337 #define _MD_SET_FP(_t, val)
michael@0 338 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 339 #define _MD_GET_FP_PTR(_t) ((void *) 0)
michael@0 340 #define _MD_SP_TYPE __ptr_t
michael@0 341 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
michael@0 342
michael@0 343 /* XXX not sure if this is correct, or maybe it should be 17? */
michael@0 344 #define PR_NUM_GCREGS 9
michael@0 345
michael@0 346 #elif defined(__ia64__)
michael@0 347
michael@0 348 #define _MD_GET_SP(_t) ((long *)((_t)->md.context[0].__jmpbuf)[0])
michael@0 349 #define _MD_SET_FP(_t, val)
michael@0 350 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 351 #define _MD_GET_FP_PTR(_t) ((void *) 0)
michael@0 352 #define _MD_SP_TYPE long int
michael@0 353
michael@0 354 #define PR_NUM_GCREGS _JBLEN
michael@0 355
michael@0 356 #elif defined(__mc68000__)
michael@0 357 /* m68k based Linux */
michael@0 358
michael@0 359 /*
michael@0 360 * On the m68k, glibc still uses the old style sigjmp_buf, even
michael@0 361 * in glibc 2.0.7.
michael@0 362 */
michael@0 363 #if defined(__GLIBC__) && __GLIBC__ >= 2
michael@0 364 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
michael@0 365 #define _MD_SET_FP(_t, val)
michael@0 366 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 367 #define _MD_GET_FP_PTR(_t) ((void *) 0)
michael@0 368 #define _MD_SP_TYPE int
michael@0 369 #else
michael@0 370 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
michael@0 371 #define _MD_SET_FP(_t, val)
michael@0 372 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 373 #define _MD_GET_FP_PTR(_t) ((void *) 0)
michael@0 374 #define _MD_SP_TYPE __ptr_t
michael@0 375 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
michael@0 376
michael@0 377 /* XXX not sure if this is correct, or maybe it should be 17? */
michael@0 378 #define PR_NUM_GCREGS 9
michael@0 379
michael@0 380 #elif defined(__sparc__)
michael@0 381 /* Sparc */
michael@0 382 #if defined(__GLIBC__) && __GLIBC__ >= 2
michael@0 383 /*
michael@0 384 * You need glibc2-2.0.7-25 or later. The libraries that came with
michael@0 385 * Red Hat 5.1 are not new enough, but they are in 5.2.
michael@0 386 */
michael@0 387 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
michael@0 388 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_FP] = val)
michael@0 389 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 390 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_FP])
michael@0 391 #define _MD_SP_TYPE int
michael@0 392 #else
michael@0 393 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__fp
michael@0 394 #define _MD_SET_FP(_t, val)
michael@0 395 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 396 #define _MD_GET_FP_PTR(_t) ((void *) 0)
michael@0 397 #define _MD_SP_TYPE __ptr_t
michael@0 398 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
michael@0 399
michael@0 400 #elif defined(__i386__)
michael@0 401 /* Intel based Linux */
michael@0 402 #if defined(__GLIBC__) && __GLIBC__ >= 2
michael@0 403 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[JB_SP]
michael@0 404 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[JB_BP] = val)
michael@0 405 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 406 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[JB_BP])
michael@0 407 #define _MD_SP_TYPE int
michael@0 408 #else
michael@0 409 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
michael@0 410 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__bp = val)
michael@0 411 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 412 #define _MD_GET_FP_PTR(_t) &((_t)->md.context[0].__jmpbuf[0].__bp)
michael@0 413 #define _MD_SP_TYPE __ptr_t
michael@0 414 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
michael@0 415 #define PR_NUM_GCREGS 6
michael@0 416
michael@0 417 #elif defined(__mips__)
michael@0 418 /* Linux/MIPS */
michael@0 419 #if defined(__GLIBC__) && __GLIBC__ >= 2
michael@0 420 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__sp
michael@0 421 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__fp = (val))
michael@0 422 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 423 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__fp)
michael@0 424 #define _MD_SP_TYPE __ptr_t
michael@0 425 #else
michael@0 426 #error "Linux/MIPS pre-glibc2 not supported yet"
michael@0 427 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
michael@0 428
michael@0 429 #elif defined(__arm__)
michael@0 430 /* ARM/Linux */
michael@0 431 #if defined(__GLIBC__) && __GLIBC__ >= 2
michael@0 432 #ifdef __ARM_EABI__
michael@0 433 /* EABI */
michael@0 434 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[8]
michael@0 435 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[7] = (val))
michael@0 436 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 437 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[7])
michael@0 438 #define _MD_SP_TYPE __ptr_t
michael@0 439 #else /* __ARM_EABI__ */
michael@0 440 /* old ABI */
michael@0 441 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[20]
michael@0 442 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[19] = (val))
michael@0 443 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 444 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[19])
michael@0 445 #define _MD_SP_TYPE __ptr_t
michael@0 446 #endif /* __ARM_EABI__ */
michael@0 447 #else
michael@0 448 #error "ARM/Linux pre-glibc2 not supported yet"
michael@0 449 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
michael@0 450
michael@0 451 #elif defined(__sh__)
michael@0 452 /* SH/Linux */
michael@0 453 #if defined(__GLIBC__) && __GLIBC__ >= 2
michael@0 454 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[7]
michael@0 455 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[6] = (val))
michael@0 456 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 457 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[6])
michael@0 458 #define _MD_SP_TYPE __ptr_t
michael@0 459 #else
michael@0 460 #error "SH/Linux pre-glibc2 not supported yet"
michael@0 461 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
michael@0 462
michael@0 463 #elif defined(__m32r__)
michael@0 464 /* Linux/M32R */
michael@0 465 #if defined(__GLIBC__) && __GLIBC__ >= 2
michael@0 466 #define _MD_GET_SP(_t) (_t)->md.context[0].__jmpbuf[0].__regs[JB_SP]
michael@0 467 #define _MD_SET_FP(_t, val) ((_t)->md.context[0].__jmpbuf[0].__regs[JB_FP] = (val))
michael@0 468 #define _MD_GET_SP_PTR(_t) &(_MD_GET_SP(_t))
michael@0 469 #define _MD_GET_FP_PTR(_t) (&(_t)->md.context[0].__jmpbuf[0].__regs[JB_FP])
michael@0 470 #define _MD_SP_TYPE __ptr_t
michael@0 471 #else
michael@0 472 #error "Linux/M32R pre-glibc2 not supported yet"
michael@0 473 #endif /* defined(__GLIBC__) && __GLIBC__ >= 2 */
michael@0 474
michael@0 475 #else
michael@0 476
michael@0 477 #error "Unknown CPU architecture"
michael@0 478
michael@0 479 #endif /*__powerpc__*/
michael@0 480
michael@0 481 /*
michael@0 482 ** Initialize a thread context to run "_main()" when started
michael@0 483 */
michael@0 484 #ifdef __powerpc__
michael@0 485
michael@0 486 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
michael@0 487 { \
michael@0 488 *status = PR_TRUE; \
michael@0 489 if (sigsetjmp(CONTEXT(_thread), 1)) { \
michael@0 490 _main(); \
michael@0 491 } \
michael@0 492 _MD_GET_SP(_thread) = (unsigned char*) ((_sp) - 128); \
michael@0 493 _thread->md.sp = _MD_GET_SP_PTR(_thread); \
michael@0 494 _thread->md.fp = _MD_GET_FP_PTR(_thread); \
michael@0 495 _MD_SET_FP(_thread, 0); \
michael@0 496 }
michael@0 497
michael@0 498 #elif defined(__mips__)
michael@0 499
michael@0 500 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
michael@0 501 { \
michael@0 502 *status = PR_TRUE; \
michael@0 503 (void) sigsetjmp(CONTEXT(_thread), 1); \
michael@0 504 _thread->md.context[0].__jmpbuf[0].__pc = (__ptr_t) _main; \
michael@0 505 _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \
michael@0 506 _thread->md.sp = _MD_GET_SP_PTR(_thread); \
michael@0 507 _thread->md.fp = _MD_GET_FP_PTR(_thread); \
michael@0 508 _MD_SET_FP(_thread, 0); \
michael@0 509 }
michael@0 510
michael@0 511 #else
michael@0 512
michael@0 513 #define _MD_INIT_CONTEXT(_thread, _sp, _main, status) \
michael@0 514 { \
michael@0 515 *status = PR_TRUE; \
michael@0 516 if (sigsetjmp(CONTEXT(_thread), 1)) { \
michael@0 517 _main(); \
michael@0 518 } \
michael@0 519 _MD_GET_SP(_thread) = (_MD_SP_TYPE) ((_sp) - 64); \
michael@0 520 _thread->md.sp = _MD_GET_SP_PTR(_thread); \
michael@0 521 _thread->md.fp = _MD_GET_FP_PTR(_thread); \
michael@0 522 _MD_SET_FP(_thread, 0); \
michael@0 523 }
michael@0 524
michael@0 525 #endif /*__powerpc__*/
michael@0 526
michael@0 527 #define _MD_SWITCH_CONTEXT(_thread) \
michael@0 528 if (!sigsetjmp(CONTEXT(_thread), 1)) { \
michael@0 529 (_thread)->md.errcode = errno; \
michael@0 530 _PR_Schedule(); \
michael@0 531 }
michael@0 532
michael@0 533 /*
michael@0 534 ** Restore a thread context, saved by _MD_SWITCH_CONTEXT
michael@0 535 */
michael@0 536 #define _MD_RESTORE_CONTEXT(_thread) \
michael@0 537 { \
michael@0 538 errno = (_thread)->md.errcode; \
michael@0 539 _MD_SET_CURRENT_THREAD(_thread); \
michael@0 540 siglongjmp(CONTEXT(_thread), 1); \
michael@0 541 }
michael@0 542
michael@0 543 /* Machine-dependent (MD) data structures */
michael@0 544
michael@0 545 struct _MDThread {
michael@0 546 PR_CONTEXT_TYPE context;
michael@0 547 void *sp;
michael@0 548 void *fp;
michael@0 549 int id;
michael@0 550 int errcode;
michael@0 551 };
michael@0 552
michael@0 553 struct _MDThreadStack {
michael@0 554 PRInt8 notused;
michael@0 555 };
michael@0 556
michael@0 557 struct _MDLock {
michael@0 558 PRInt8 notused;
michael@0 559 };
michael@0 560
michael@0 561 struct _MDSemaphore {
michael@0 562 PRInt8 notused;
michael@0 563 };
michael@0 564
michael@0 565 struct _MDCVar {
michael@0 566 PRInt8 notused;
michael@0 567 };
michael@0 568
michael@0 569 struct _MDSegment {
michael@0 570 PRInt8 notused;
michael@0 571 };
michael@0 572
michael@0 573 /*
michael@0 574 * md-specific cpu structure field
michael@0 575 */
michael@0 576 #include <sys/time.h> /* for FD_SETSIZE */
michael@0 577 #define _PR_MD_MAX_OSFD FD_SETSIZE
michael@0 578
michael@0 579 struct _MDCPU_Unix {
michael@0 580 PRCList ioQ;
michael@0 581 PRUint32 ioq_timeout;
michael@0 582 PRInt32 ioq_max_osfd;
michael@0 583 PRInt32 ioq_osfd_cnt;
michael@0 584 #ifndef _PR_USE_POLL
michael@0 585 fd_set fd_read_set, fd_write_set, fd_exception_set;
michael@0 586 PRInt16 fd_read_cnt[_PR_MD_MAX_OSFD],fd_write_cnt[_PR_MD_MAX_OSFD],
michael@0 587 fd_exception_cnt[_PR_MD_MAX_OSFD];
michael@0 588 #else
michael@0 589 struct pollfd *ioq_pollfds;
michael@0 590 int ioq_pollfds_size;
michael@0 591 #endif /* _PR_USE_POLL */
michael@0 592 };
michael@0 593
michael@0 594 #define _PR_IOQ(_cpu) ((_cpu)->md.md_unix.ioQ)
michael@0 595 #define _PR_ADD_TO_IOQ(_pq, _cpu) PR_APPEND_LINK(&_pq.links, &_PR_IOQ(_cpu))
michael@0 596 #define _PR_FD_READ_SET(_cpu) ((_cpu)->md.md_unix.fd_read_set)
michael@0 597 #define _PR_FD_READ_CNT(_cpu) ((_cpu)->md.md_unix.fd_read_cnt)
michael@0 598 #define _PR_FD_WRITE_SET(_cpu) ((_cpu)->md.md_unix.fd_write_set)
michael@0 599 #define _PR_FD_WRITE_CNT(_cpu) ((_cpu)->md.md_unix.fd_write_cnt)
michael@0 600 #define _PR_FD_EXCEPTION_SET(_cpu) ((_cpu)->md.md_unix.fd_exception_set)
michael@0 601 #define _PR_FD_EXCEPTION_CNT(_cpu) ((_cpu)->md.md_unix.fd_exception_cnt)
michael@0 602 #define _PR_IOQ_TIMEOUT(_cpu) ((_cpu)->md.md_unix.ioq_timeout)
michael@0 603 #define _PR_IOQ_MAX_OSFD(_cpu) ((_cpu)->md.md_unix.ioq_max_osfd)
michael@0 604 #define _PR_IOQ_OSFD_CNT(_cpu) ((_cpu)->md.md_unix.ioq_osfd_cnt)
michael@0 605 #define _PR_IOQ_POLLFDS(_cpu) ((_cpu)->md.md_unix.ioq_pollfds)
michael@0 606 #define _PR_IOQ_POLLFDS_SIZE(_cpu) ((_cpu)->md.md_unix.ioq_pollfds_size)
michael@0 607
michael@0 608 #define _PR_IOQ_MIN_POLLFDS_SIZE(_cpu) 32
michael@0 609
michael@0 610 struct _MDCPU {
michael@0 611 struct _MDCPU_Unix md_unix;
michael@0 612 };
michael@0 613
michael@0 614 #define _MD_INIT_LOCKS()
michael@0 615 #define _MD_NEW_LOCK(lock) PR_SUCCESS
michael@0 616 #define _MD_FREE_LOCK(lock)
michael@0 617 #define _MD_LOCK(lock)
michael@0 618 #define _MD_UNLOCK(lock)
michael@0 619 #define _MD_INIT_IO()
michael@0 620 #define _MD_IOQ_LOCK()
michael@0 621 #define _MD_IOQ_UNLOCK()
michael@0 622
michael@0 623 extern PRStatus _MD_InitializeThread(PRThread *thread);
michael@0 624
michael@0 625 #define _MD_INIT_RUNNING_CPU(cpu) _MD_unix_init_running_cpu(cpu)
michael@0 626 #define _MD_INIT_THREAD _MD_InitializeThread
michael@0 627 #define _MD_EXIT_THREAD(thread)
michael@0 628 #define _MD_SUSPEND_THREAD(thread) _MD_suspend_thread
michael@0 629 #define _MD_RESUME_THREAD(thread) _MD_resume_thread
michael@0 630 #define _MD_CLEAN_THREAD(_thread)
michael@0 631
michael@0 632 extern PRStatus _MD_CREATE_THREAD(
michael@0 633 PRThread *thread,
michael@0 634 void (*start) (void *),
michael@0 635 PRThreadPriority priority,
michael@0 636 PRThreadScope scope,
michael@0 637 PRThreadState state,
michael@0 638 PRUint32 stackSize);
michael@0 639 extern void _MD_SET_PRIORITY(struct _MDThread *thread, PRUintn newPri);
michael@0 640 extern PRStatus _MD_WAIT(PRThread *, PRIntervalTime timeout);
michael@0 641 extern PRStatus _MD_WAKEUP_WAITER(PRThread *);
michael@0 642 extern void _MD_YIELD(void);
michael@0 643
michael@0 644 #endif /* ! _PR_PTHREADS */
michael@0 645
michael@0 646 extern void _MD_EarlyInit(void);
michael@0 647
michael@0 648 #define _MD_EARLY_INIT _MD_EarlyInit
michael@0 649 #define _MD_FINAL_INIT _PR_UnixInit
michael@0 650 #define HAVE_CLOCK_MONOTONIC
michael@0 651
michael@0 652 /*
michael@0 653 * We wrapped the select() call. _MD_SELECT refers to the built-in,
michael@0 654 * unwrapped version.
michael@0 655 */
michael@0 656 #define _MD_SELECT __select
michael@0 657
michael@0 658 #ifdef _PR_POLL_AVAILABLE
michael@0 659 #include <sys/poll.h>
michael@0 660 extern int __syscall_poll(struct pollfd *ufds, unsigned long int nfds,
michael@0 661 int timeout);
michael@0 662 #define _MD_POLL __syscall_poll
michael@0 663 #endif
michael@0 664
michael@0 665 /* For writev() */
michael@0 666 #include <sys/uio.h>
michael@0 667
michael@0 668 extern void _MD_linux_map_sendfile_error(int err);
michael@0 669
michael@0 670 #endif /* nspr_linux_defs_h___ */

mercurial