1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is the Netscape Portable Runtime (NSPR).
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998-2000
20 * the Initial Developer. All Rights Reserved.
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
41 #if defined(HPUX_LW_TIMER)
43 #include <machine/inline.h>
44 #include <machine/clock.h>
47 #include <sys/pstat.h>
49 int __lw_get_thread_times(int which
, int64_t *sample
, int64_t *time
);
51 static double msecond_per_itick
;
53 void _PR_HPUX_LW_IntervalInit(void)
55 struct pst_processor psp
;
56 int iticksperclktick
, clk_tck
;
59 rv
= pstat_getprocessor(&psp
, sizeof(psp
), 1, 0);
62 iticksperclktick
= psp
.psp_iticksperclktick
;
63 clk_tck
= sysconf(_SC_CLK_TCK
);
64 msecond_per_itick
= (1000.0)/(double)(iticksperclktick
* clk_tck
);
67 PRIntervalTime
_PR_HPUX_LW_GetInterval(void)
71 __lw_get_thread_times(1, &sample
, &time
);
73 * Division is slower than float multiplication.
74 * return (time / iticks_per_msecond);
76 return (time
* msecond_per_itick
);
78 #endif /* HPUX_LW_TIMER */
80 #if !defined(PTHREADS_USER)
82 void _MD_EarlyInit(void)
86 * The following piece of code is taken from ns/nspr/src/md_HP-UX.c.
87 * In the comment for revision 1.6, dated 1995/09/11 23:33:34,
89 * This version has some problems which need to be addressed.
90 * First, intercept all system calls and prevent them from
91 * executing the library code which performs stack switches
92 * before normal system call invocation. In order for library
93 * calls which make system calls to work (like stdio), however,
94 * we must also allocate our own stack and switch the primordial
95 * stack to use it. This isn't so bad, except that I fudged the
96 * backtrace length when copying the old stack to the new one.
98 * This is the original comment of robm in the code:
99 * XXXrobm Horrific. To avoid a problem with HP's system call
100 * code, we allocate a new stack for the primordial thread and
101 * use it. However, we don't know how far back the original stack
102 * goes. We should create a routine that performs a backtrace and
103 * finds out just how much we need to copy. As a temporary measure,
104 * I just copy an arbitrary guess.
106 * In an email to servereng dated 2 Jan 1997, Mike Patnode (mikep)
107 * suggests that this only needs to be done for HP-UX 9.
110 #define PIDOOMA_STACK_SIZE 524288
111 #define BACKTRACE_SIZE 8192
118 newstack
= (char *) PR_MALLOC(PIDOOMA_STACK_SIZE
);
119 oldstack
= (char *) (*(((int *) jb
) + 1) - BACKTRACE_SIZE
);
120 memcpy(newstack
, oldstack
, BACKTRACE_SIZE
);
121 *(((int *) jb
) + 1) = (int) (newstack
+ BACKTRACE_SIZE
);
126 #endif /* !_PR_PTHREADS */
129 PRWord
*_MD_HomeGCRegisters(PRThread
*t
, int isCurrent
, int *np
)
133 (void) setjmp(CONTEXT(t
));
135 *np
= sizeof(CONTEXT(t
)) / sizeof(PRWord
);
136 return (PRWord
*) CONTEXT(t
);
145 _MD_SET_PRIORITY(_MDThread
*thread
, PRUintn newPri
)
151 _MD_InitializeThread(PRThread
*thread
)
157 _MD_WAIT(PRThread
*thread
, PRIntervalTime ticks
)
159 PR_ASSERT(!(thread
->flags
& _PR_GLOBAL_SCOPE
));
160 _PR_MD_SWITCH_CONTEXT(thread
);
165 _MD_WAKEUP_WAITER(PRThread
*thread
)
168 PR_ASSERT(!(thread
->flags
& _PR_GLOBAL_SCOPE
));
173 /* These functions should not be called for HP-UX */
177 PR_NOT_REACHED("_MD_YIELD should not be called for HP-UX.");
183 void (*start
) (void *),
184 PRThreadPriority priority
,
189 PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for HP-UX.");
191 #endif /* _PR_PTHREADS */
194 _MD_suspend_thread(PRThread
*thread
)
201 _MD_resume_thread(PRThread
*thread
)
206 #endif /* PTHREADS_USER */
209 * The HP version of strchr is buggy. It looks past the end of the
210 * string and causes a segmentation fault when our (NSPR) version
213 * A better solution might be to put a cushion in our malloc just in
214 * case HP's version of strchr somehow gets used instead of this one.
217 strchr(const char *s
, int c
)
227 while ((*s
) && ((*s
) != ch
)) {
239 * Implemementation of memcmp in HP-UX (verified on releases A.09.03,
240 * A.09.07, and B.10.10) dumps core if called with:
241 * 1. First operand with address = 1(mod 4).
243 * 3. Last byte of the second operand is the last byte of the page and
244 * next page is not accessible(not mapped or protected)
245 * Thus, using the following naive version (tons of optimizations are
249 int memcmp(const void *s1
, const void *s2
, size_t n
)
251 register unsigned char *p1
= (unsigned char *) s1
,
252 *p2
= (unsigned char *) s2
;
255 register int r
= ((int) ((unsigned int) *p1
))
256 - ((int) ((unsigned int) *p2
));