Import from 1.9a8 tarball
[mozilla-nspr.git] / nsprpub / pr / src / md / unix / hpux.c
blobcf43e05ed8301e75bee7bfd838768c42e4cf0fd9
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
13 * License.
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.
22 * Contributor(s):
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 ***** */
38 #include "primpl.h"
39 #include <setjmp.h>
41 #if defined(HPUX_LW_TIMER)
43 #include <machine/inline.h>
44 #include <machine/clock.h>
45 #include <unistd.h>
46 #include <sys/time.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;
57 int rv;
59 rv = pstat_getprocessor(&psp, sizeof(psp), 1, 0);
60 PR_ASSERT(rv != -1);
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)
69 int64_t time, sample;
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)
84 #ifndef _PR_PTHREADS
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,
88 * robm says:
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.
109 #ifdef HPUX9
110 #define PIDOOMA_STACK_SIZE 524288
111 #define BACKTRACE_SIZE 8192
113 jmp_buf jb;
114 char *newstack;
115 char *oldstack;
117 if(!setjmp(jb)) {
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);
122 longjmp(jb, 1);
125 #endif /* HPUX9 */
126 #endif /* !_PR_PTHREADS */
129 PRWord *_MD_HomeGCRegisters(PRThread *t, int isCurrent, int *np)
131 #ifndef _PR_PTHREADS
132 if (isCurrent) {
133 (void) setjmp(CONTEXT(t));
135 *np = sizeof(CONTEXT(t)) / sizeof(PRWord);
136 return (PRWord *) CONTEXT(t);
137 #else
138 *np = 0;
139 return NULL;
140 #endif
143 #ifndef _PR_PTHREADS
144 void
145 _MD_SET_PRIORITY(_MDThread *thread, PRUintn newPri)
147 return;
150 PRStatus
151 _MD_InitializeThread(PRThread *thread)
153 return PR_SUCCESS;
156 PRStatus
157 _MD_WAIT(PRThread *thread, PRIntervalTime ticks)
159 PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
160 _PR_MD_SWITCH_CONTEXT(thread);
161 return PR_SUCCESS;
164 PRStatus
165 _MD_WAKEUP_WAITER(PRThread *thread)
167 if (thread) {
168 PR_ASSERT(!(thread->flags & _PR_GLOBAL_SCOPE));
170 return PR_SUCCESS;
173 /* These functions should not be called for HP-UX */
174 void
175 _MD_YIELD(void)
177 PR_NOT_REACHED("_MD_YIELD should not be called for HP-UX.");
180 PRStatus
181 _MD_CREATE_THREAD(
182 PRThread *thread,
183 void (*start) (void *),
184 PRThreadPriority priority,
185 PRThreadScope scope,
186 PRThreadState state,
187 PRUint32 stackSize)
189 PR_NOT_REACHED("_MD_CREATE_THREAD should not be called for HP-UX.");
191 #endif /* _PR_PTHREADS */
193 void
194 _MD_suspend_thread(PRThread *thread)
196 #ifdef _PR_PTHREADS
197 #endif
200 void
201 _MD_resume_thread(PRThread *thread)
203 #ifdef _PR_PTHREADS
204 #endif
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
211 * of malloc is used.
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.
216 char *
217 strchr(const char *s, int c)
219 char ch;
221 if (!s) {
222 return NULL;
225 ch = (char) c;
227 while ((*s) && ((*s) != ch)) {
228 s++;
231 if ((*s) == ch) {
232 return (char *) s;
235 return NULL;
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).
242 * 2. Size = 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
246 * possible;^)
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;
254 while (n-- > 0) {
255 register int r = ((int) ((unsigned int) *p1))
256 - ((int) ((unsigned int) *p2));
257 if (r) return r;
258 p1++; p2++;
260 return 0;