nsprpub/pr/src/md/unix/hpux.c

changeset 0
6474c204b198
     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 +}

mercurial