Back to index

lightning-sunbird  0.9+nobinonly
hpux.c
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is the Netscape Portable Runtime (NSPR).
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998-2000
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either the GNU General Public License Version 2 or later (the "GPL"), or
00026  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "primpl.h"
00039 #include <setjmp.h>
00040 
00041 #if defined(HPUX_LW_TIMER)
00042 
00043 #include <machine/inline.h>
00044 #include <machine/clock.h>
00045 #include <unistd.h>
00046 #include <sys/time.h>
00047 #include <sys/pstat.h>
00048 
00049 int __lw_get_thread_times(int which, int64_t *sample, int64_t *time);
00050 
00051 static double msecond_per_itick;
00052 
00053 void _PR_HPUX_LW_IntervalInit(void)
00054 {
00055     struct pst_processor psp;
00056     int iticksperclktick, clk_tck;
00057     int rv;
00058 
00059     rv = pstat_getprocessor(&psp, sizeof(psp), 1, 0);
00060     PR_ASSERT(rv != -1);
00061 
00062     iticksperclktick = psp.psp_iticksperclktick;
00063     clk_tck = sysconf(_SC_CLK_TCK);
00064     msecond_per_itick = (1000.0)/(double)(iticksperclktick * clk_tck);
00065 }
00066 
00067 PRIntervalTime _PR_HPUX_LW_GetInterval(void)
00068 {
00069     int64_t time, sample;
00070 
00071     __lw_get_thread_times(1, &sample, &time);
00072     /*
00073      * Division is slower than float multiplication.
00074      * return (time / iticks_per_msecond);
00075      */
00076     return (time * msecond_per_itick);
00077 }
00078 #endif  /* HPUX_LW_TIMER */
00079 
00080 #if !defined(PTHREADS_USER)
00081 
00082 void _MD_EarlyInit(void)
00083 {
00084 #ifndef _PR_PTHREADS
00085     /*
00086      * The following piece of code is taken from ns/nspr/src/md_HP-UX.c.
00087      * In the comment for revision 1.6, dated 1995/09/11 23:33:34,
00088      * robm says:
00089      *     This version has some problems which need to be addressed.
00090      *     First, intercept all system calls and prevent them from
00091      *     executing the library code which performs stack switches
00092      *     before normal system call invocation.  In order for library
00093      *     calls which make system calls to work (like stdio), however,
00094      *     we must also allocate our own stack and switch the primordial
00095      *     stack to use it. This isn't so bad, except that I fudged the
00096      *     backtrace length when copying the old stack to the new one.
00097      *
00098      * This is the original comment of robm in the code:
00099      *    XXXrobm Horrific. To avoid a problem with HP's system call
00100      *    code, we allocate a new stack for the primordial thread and
00101      *    use it. However, we don't know how far back the original stack
00102      *    goes. We should create a routine that performs a backtrace and
00103      *    finds out just how much we need to copy. As a temporary measure,
00104      *    I just copy an arbitrary guess.
00105      *
00106      * In an email to servereng dated 2 Jan 1997, Mike Patnode (mikep)
00107      * suggests that this only needs to be done for HP-UX 9.
00108      */
00109 #ifdef HPUX9
00110 #define PIDOOMA_STACK_SIZE 524288
00111 #define BACKTRACE_SIZE 8192
00112     {
00113         jmp_buf jb;
00114         char *newstack;
00115         char *oldstack;
00116 
00117         if(!setjmp(jb)) {
00118             newstack = (char *) PR_MALLOC(PIDOOMA_STACK_SIZE);
00119            oldstack = (char *) (*(((int *) jb) + 1) - BACKTRACE_SIZE);
00120             memcpy(newstack, oldstack, BACKTRACE_SIZE);
00121             *(((int *) jb) + 1) = (int) (newstack + BACKTRACE_SIZE);
00122             longjmp(jb, 1);
00123         }
00124     }
00125 #endif  /* HPUX9 */
00126 #endif  /* !_PR_PTHREADS */
00127 }
00128 
00129 PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
00130 {
00131 #ifndef _PR_PTHREADS
00132     if (isCurrent) {
00133        (void) setjmp(CONTEXT(t));
00134     }
00135     *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
00136     return (PRWord *) CONTEXT(t);
00137 #else
00138        *np = 0;
00139        return NULL;
00140 #endif
00141 }
00142 
00143 #ifndef _PR_PTHREADS
00144 void
00145 _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
00146 {
00147     return;
00148 }
00149 
00150 PRStatus
00151 _MD_InitializeThread(PRThread *thread)
00152 {
00153        return PR_SUCCESS;
00154 }
00155 
00156 PRStatus
00157 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)
00158 {
00159     PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
00160     _PR_MD_SWITCH_CONTEXT(thread);
00161     return PR_SUCCESS;
00162 }
00163 
00164 PRStatus
00165 _MD_WAKEUP_WAITER(PRThread *thread)
00166 {
00167     if (thread) {
00168        PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
00169     }
00170     return PR_SUCCESS;
00171 }
00172 
00173 /* These functions should not be called for HP-UX */
00174 void
00175 _MD_YIELD(void)
00176 {
00177     PR_NOT_REACHED("_MD_YIELD should not be called for HP-UX.");
00178 }
00179 
00180 PRStatus
00181 _MD_CREATE_THREAD(
00182     PRThread *thread,
00183     void (*start) (void *),
00184     PRThreadPriority priority,
00185     PRThreadScope scope,
00186     PRThreadState state,
00187     PRUint32 stackSize)
00188 {
00189     PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for HP-UX.");
00190 }
00191 #endif /* _PR_PTHREADS */
00192 
00193 void
00194 _MD_suspend_thread(PRThread *thread)
00195 {
00196 #ifdef _PR_PTHREADS
00197 #endif
00198 }
00199 
00200 void
00201 _MD_resume_thread(PRThread *thread)
00202 {
00203 #ifdef _PR_PTHREADS
00204 #endif
00205 }
00206 #endif /* PTHREADS_USER */
00207 
00208 /*
00209  * The HP version of strchr is buggy. It looks past the end of the
00210  * string and causes a segmentation fault when our (NSPR) version
00211  * of malloc is used.
00212  *
00213  * A better solution might be to put a cushion in our malloc just in
00214  * case HP's version of strchr somehow gets used instead of this one.
00215  */
00216 char *
00217 strchr(const char *s, int c)
00218 {
00219     char ch;
00220 
00221     if (!s) {
00222         return NULL;
00223     }
00224 
00225     ch = (char) c;
00226 
00227     while ((*s) && ((*s) != ch)) {
00228         s++;
00229     }
00230 
00231     if ((*s) == ch) {
00232         return (char *) s;
00233     }
00234 
00235     return NULL;
00236 }
00237 
00238 /*
00239  * Implemementation of memcmp in HP-UX (verified on releases A.09.03,
00240  * A.09.07, and B.10.10) dumps core if called with:
00241  * 1. First operand with address = 1(mod 4).
00242  * 2. Size = 1(mod 4)
00243  * 3. Last byte of the second operand is the last byte of the page and 
00244  *    next page is not accessible(not mapped or protected)
00245  * Thus, using the following naive version (tons of optimizations are
00246  * possible;^)
00247  */
00248 
00249 int memcmp(const void *s1, const void *s2, size_t n)
00250 {
00251     register unsigned char *p1 = (unsigned char *) s1,
00252             *p2 = (unsigned char *) s2;
00253 
00254     while (n-- > 0) {
00255         register int r = ((int) ((unsigned int) *p1)) 
00256                 - ((int) ((unsigned int) *p2));
00257         if (r) return r;
00258         p1++; p2++;
00259     }
00260     return 0; 
00261 }