1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/nsprpub/pr/src/md/unix/hpux.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,229 @@ 1.4 +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "primpl.h" 1.10 +#include <setjmp.h> 1.11 + 1.12 +#if defined(HPUX_LW_TIMER) 1.13 + 1.14 +#include <machine/inline.h> 1.15 +#include <machine/clock.h> 1.16 +#include <unistd.h> 1.17 +#include <sys/time.h> 1.18 +#include <sys/pstat.h> 1.19 + 1.20 +int __lw_get_thread_times(int which, int64_t *sample, int64_t *time); 1.21 + 1.22 +static double msecond_per_itick; 1.23 + 1.24 +void _PR_HPUX_LW_IntervalInit(void) 1.25 +{ 1.26 + struct pst_processor psp; 1.27 + int iticksperclktick, clk_tck; 1.28 + int rv; 1.29 + 1.30 + rv = pstat_getprocessor(&psp, sizeof(psp), 1, 0); 1.31 + PR_ASSERT(rv != -1); 1.32 + 1.33 + iticksperclktick = psp.psp_iticksperclktick; 1.34 + clk_tck = sysconf(_SC_CLK_TCK); 1.35 + msecond_per_itick = (1000.0)/(double)(iticksperclktick * clk_tck); 1.36 +} 1.37 + 1.38 +PRIntervalTime _PR_HPUX_LW_GetInterval(void) 1.39 +{ 1.40 + int64_t time, sample; 1.41 + 1.42 + __lw_get_thread_times(1, &sample, &time); 1.43 + /* 1.44 + * Division is slower than float multiplication. 1.45 + * return (time / iticks_per_msecond); 1.46 + */ 1.47 + return (time * msecond_per_itick); 1.48 +} 1.49 +#endif /* HPUX_LW_TIMER */ 1.50 + 1.51 +#if !defined(PTHREADS_USER) 1.52 + 1.53 +void _MD_EarlyInit(void) 1.54 +{ 1.55 +#ifndef _PR_PTHREADS 1.56 + /* 1.57 + * The following piece of code is taken from ns/nspr/src/md_HP-UX.c. 1.58 + * In the comment for revision 1.6, dated 1995/09/11 23:33:34, 1.59 + * robm says: 1.60 + * This version has some problems which need to be addressed. 1.61 + * First, intercept all system calls and prevent them from 1.62 + * executing the library code which performs stack switches 1.63 + * before normal system call invocation. In order for library 1.64 + * calls which make system calls to work (like stdio), however, 1.65 + * we must also allocate our own stack and switch the primordial 1.66 + * stack to use it. This isn't so bad, except that I fudged the 1.67 + * backtrace length when copying the old stack to the new one. 1.68 + * 1.69 + * This is the original comment of robm in the code: 1.70 + * XXXrobm Horrific. To avoid a problem with HP's system call 1.71 + * code, we allocate a new stack for the primordial thread and 1.72 + * use it. However, we don't know how far back the original stack 1.73 + * goes. We should create a routine that performs a backtrace and 1.74 + * finds out just how much we need to copy. As a temporary measure, 1.75 + * I just copy an arbitrary guess. 1.76 + * 1.77 + * In an email to servereng dated 2 Jan 1997, Mike Patnode (mikep) 1.78 + * suggests that this only needs to be done for HP-UX 9. 1.79 + */ 1.80 +#ifdef HPUX9 1.81 +#define PIDOOMA_STACK_SIZE 524288 1.82 +#define BACKTRACE_SIZE 8192 1.83 + { 1.84 + jmp_buf jb; 1.85 + char *newstack; 1.86 + char *oldstack; 1.87 + 1.88 + if(!setjmp(jb)) { 1.89 + newstack = (char *) PR_MALLOC(PIDOOMA_STACK_SIZE); 1.90 + oldstack = (char *) (*(((int *) jb) + 1) - BACKTRACE_SIZE); 1.91 + memcpy(newstack, oldstack, BACKTRACE_SIZE); 1.92 + *(((int *) jb) + 1) = (int) (newstack + BACKTRACE_SIZE); 1.93 + longjmp(jb, 1); 1.94 + } 1.95 + } 1.96 +#endif /* HPUX9 */ 1.97 +#endif /* !_PR_PTHREADS */ 1.98 +} 1.99 + 1.100 +PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np) 1.101 +{ 1.102 +#ifndef _PR_PTHREADS 1.103 + if (isCurrent) { 1.104 + (void) setjmp(CONTEXT(t)); 1.105 + } 1.106 + *np = sizeof(CONTEXT(t)) / sizeof(PRWord); 1.107 + return (PRWord *) CONTEXT(t); 1.108 +#else 1.109 + *np = 0; 1.110 + return NULL; 1.111 +#endif 1.112 +} 1.113 + 1.114 +#ifndef _PR_PTHREADS 1.115 +void 1.116 +_MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri) 1.117 +{ 1.118 + return; 1.119 +} 1.120 + 1.121 +PRStatus 1.122 +_MD_InitializeThread(PRThread *thread) 1.123 +{ 1.124 + return PR_SUCCESS; 1.125 +} 1.126 + 1.127 +PRStatus 1.128 +_MD_WAIT(PRThread *thread, PRIntervalTime ticks) 1.129 +{ 1.130 + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); 1.131 + _PR_MD_SWITCH_CONTEXT(thread); 1.132 + return PR_SUCCESS; 1.133 +} 1.134 + 1.135 +PRStatus 1.136 +_MD_WAKEUP_WAITER(PRThread *thread) 1.137 +{ 1.138 + if (thread) { 1.139 + PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE)); 1.140 + } 1.141 + return PR_SUCCESS; 1.142 +} 1.143 + 1.144 +/* These functions should not be called for HP-UX */ 1.145 +void 1.146 +_MD_YIELD(void) 1.147 +{ 1.148 + PR_NOT_REACHED("_MD_YIELD should not be called for HP-UX."); 1.149 +} 1.150 + 1.151 +PRStatus 1.152 +_MD_CREATE_THREAD( 1.153 + PRThread *thread, 1.154 + void (*start) (void *), 1.155 + PRThreadPriority priority, 1.156 + PRThreadScope scope, 1.157 + PRThreadState state, 1.158 + PRUint32 stackSize) 1.159 +{ 1.160 + PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for HP-UX."); 1.161 +} 1.162 +#endif /* _PR_PTHREADS */ 1.163 + 1.164 +void 1.165 +_MD_suspend_thread(PRThread *thread) 1.166 +{ 1.167 +#ifdef _PR_PTHREADS 1.168 +#endif 1.169 +} 1.170 + 1.171 +void 1.172 +_MD_resume_thread(PRThread *thread) 1.173 +{ 1.174 +#ifdef _PR_PTHREADS 1.175 +#endif 1.176 +} 1.177 +#endif /* PTHREADS_USER */ 1.178 + 1.179 +/* 1.180 + * The HP version of strchr is buggy. It looks past the end of the 1.181 + * string and causes a segmentation fault when our (NSPR) version 1.182 + * of malloc is used. 1.183 + * 1.184 + * A better solution might be to put a cushion in our malloc just in 1.185 + * case HP's version of strchr somehow gets used instead of this one. 1.186 + */ 1.187 +char * 1.188 +strchr(const char *s, int c) 1.189 +{ 1.190 + char ch; 1.191 + 1.192 + if (!s) { 1.193 + return NULL; 1.194 + } 1.195 + 1.196 + ch = (char) c; 1.197 + 1.198 + while ((*s) && ((*s) != ch)) { 1.199 + s++; 1.200 + } 1.201 + 1.202 + if ((*s) == ch) { 1.203 + return (char *) s; 1.204 + } 1.205 + 1.206 + return NULL; 1.207 +} 1.208 + 1.209 +/* 1.210 + * Implemementation of memcmp in HP-UX (verified on releases A.09.03, 1.211 + * A.09.07, and B.10.10) dumps core if called with: 1.212 + * 1. First operand with address = 1(mod 4). 1.213 + * 2. Size = 1(mod 4) 1.214 + * 3. Last byte of the second operand is the last byte of the page and 1.215 + * next page is not accessible(not mapped or protected) 1.216 + * Thus, using the following naive version (tons of optimizations are 1.217 + * possible;^) 1.218 + */ 1.219 + 1.220 +int memcmp(const void *s1, const void *s2, size_t n) 1.221 +{ 1.222 + register unsigned char *p1 = (unsigned char *) s1, 1.223 + *p2 = (unsigned char *) s2; 1.224 + 1.225 + while (n-- > 0) { 1.226 + register int r = ((int) ((unsigned int) *p1)) 1.227 + - ((int) ((unsigned int) *p2)); 1.228 + if (r) return r; 1.229 + p1++; p2++; 1.230 + } 1.231 + return 0; 1.232 +}