1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6 /*
7 * File: priotest.c
8 * Purpose: testing priorities
9 */
10
11 #include "prcmon.h"
12 #include "prinit.h"
13 #include "prinrval.h"
14 #include "prlock.h"
15 #include "prlog.h"
16 #include "prmon.h"
17 #include "prprf.h"
18 #include "prthread.h"
19 #include "prtypes.h"
20
21 #include "plerror.h"
22 #include "plgetopt.h"
23
24 #include <stdio.h>
25 #include <stdlib.h>
26
27 #define DEFAULT_DURATION 5
28
29 static PRBool failed = PR_FALSE;
30 static PRIntervalTime oneSecond;
31 static PRFileDesc *debug_out = NULL;
32 static PRBool debug_mode = PR_FALSE;
33
PerSecond(PRIntervalTime timein)34 static PRUint32 PerSecond(PRIntervalTime timein)
35 {
36 PRUint32 loop = 0;
37 while (((PRIntervalTime)(PR_IntervalNow()) - timein) < oneSecond)
38 loop += 1;
39 return loop;
40 } /* PerSecond */
41
Low(void * arg)42 static void PR_CALLBACK Low(void *arg)
43 {
44 PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg;
45 while (1)
46 {
47 t0 = PerSecond(PR_IntervalNow());
48 *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8;
49 t3 = t2; t2 = t1; t1 = t0;
50 }
51 } /* Low */
52
High(void * arg)53 static void PR_CALLBACK High(void *arg)
54 {
55 PRUint32 t3 = 0, t2 = 0, t1 = 0, t0, *tn = (PRUint32*)arg;
56 while (1)
57 {
58 PRIntervalTime timein = PR_IntervalNow();
59 PR_Sleep(oneSecond >> 2); /* 0.25 seconds */
60 t0 = PerSecond(timein);
61 *tn = (t3 + 3 * t2 + 3 * t1 + t0) / 8;
62 t3 = t2; t2 = t1; t1 = t0;
63 }
64 } /* High */
65
Help(void)66 static void Help(void)
67 {
68 PR_fprintf(
69 debug_out, "Usage: priotest [-d] [-c n]\n");
70 PR_fprintf(
71 debug_out, "-c n\tduration of test in seconds (default: %d)\n", DEFAULT_DURATION);
72 PR_fprintf(
73 debug_out, "-d\tturn on debugging output (default: FALSE)\n");
74 } /* Help */
75
RudimentaryTests(void)76 static void RudimentaryTests(void)
77 {
78 /*
79 ** Try some rudimentary tests like setting valid priority and
80 ** getting it back, or setting invalid priorities and getting
81 ** back a valid answer.
82 */
83 PRThreadPriority priority;
84 PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
85 priority = PR_GetThreadPriority(PR_GetCurrentThread());
86 failed = ((PR_TRUE == failed) || (PR_PRIORITY_URGENT != priority))
87 ? PR_TRUE : PR_FALSE;
88 if (debug_mode && (PR_PRIORITY_URGENT != priority))
89 {
90 PR_fprintf(debug_out, "PR_[S/G]etThreadPriority() failed\n");
91 }
92
93
94 PR_SetThreadPriority(
95 PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_FIRST - 1));
96 priority = PR_GetThreadPriority(PR_GetCurrentThread());
97 failed = ((PR_TRUE == failed) || (PR_PRIORITY_FIRST != priority))
98 ? PR_TRUE : PR_FALSE;
99 if (debug_mode && (PR_PRIORITY_FIRST != priority))
100 {
101 PR_fprintf(debug_out, "PR_SetThreadPriority(-1) failed\n");
102 }
103
104 PR_SetThreadPriority(
105 PR_GetCurrentThread(), (PRThreadPriority)(PR_PRIORITY_LAST + 1));
106 priority = PR_GetThreadPriority(PR_GetCurrentThread());
107 failed = ((PR_TRUE == failed) || (PR_PRIORITY_LAST != priority))
108 ? PR_TRUE : PR_FALSE;
109 if (debug_mode && (PR_PRIORITY_LAST != priority))
110 {
111 PR_fprintf(debug_out, "PR_SetThreadPriority(+1) failed\n");
112 }
113
114 } /* RudimentataryTests */
115
CreateThreads(PRUint32 * lowCount,PRUint32 * highCount)116 static void CreateThreads(PRUint32 *lowCount, PRUint32 *highCount)
117 {
118 (void)PR_CreateThread(
119 PR_USER_THREAD, Low, lowCount, PR_PRIORITY_LOW,
120 PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
121 (void)PR_CreateThread(
122 PR_USER_THREAD, High, highCount, PR_PRIORITY_HIGH,
123 PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
124 } /* CreateThreads */
125
main(int argc,char ** argv)126 int main(int argc, char **argv)
127 {
128 PLOptStatus os;
129 PRIntn duration = DEFAULT_DURATION;
130 PRUint32 totalCount, highCount = 0, lowCount = 0;
131 PLOptState *opt = PL_CreateOptState(argc, argv, "hdc:");
132
133 debug_out = PR_STDOUT;
134 oneSecond = PR_SecondsToInterval(1);
135
136 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
137 {
138 if (PL_OPT_BAD == os) continue;
139 switch (opt->option)
140 {
141 case 'd': /* debug mode */
142 debug_mode = PR_TRUE;
143 break;
144 case 'c': /* test duration */
145 duration = atoi(opt->value);
146 break;
147 case 'h': /* help message */
148 default:
149 Help();
150 return 2;
151 }
152 }
153 PL_DestroyOptState(opt);
154 PR_STDIO_INIT();
155
156 if (duration == 0) duration = DEFAULT_DURATION;
157
158 RudimentaryTests();
159
160 printf("Priority test: running for %d seconds\n\n", duration);
161
162 (void)PerSecond(PR_IntervalNow());
163 totalCount = PerSecond(PR_IntervalNow());
164
165 PR_SetThreadPriority(PR_GetCurrentThread(), PR_PRIORITY_URGENT);
166
167 if (debug_mode)
168 {
169 PR_fprintf(debug_out,
170 "The high priority thread should get approximately three\n");
171 PR_fprintf( debug_out,
172 "times what the low priority thread manages. A maximum of \n");
173 PR_fprintf( debug_out, "%d cycles are available.\n\n", totalCount);
174 }
175
176 duration = (duration + 4) / 5;
177 CreateThreads(&lowCount, &highCount);
178 while (duration--)
179 {
180 PRIntn loop = 5;
181 while (loop--) PR_Sleep(oneSecond);
182 if (debug_mode)
183 PR_fprintf(debug_out, "high : low :: %d : %d\n", highCount, lowCount);
184 }
185
186
187 PR_ProcessExit((failed) ? 1 : 0);
188
189 PR_NOT_REACHED("You can't get here -- but you did!");
190 return 1; /* or here */
191
192 } /* main */
193
194 /* priotest.c */
195