VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/pr/tests/switch.c@ 89890

最後變更 在這個檔案從89890是 1,由 vboxsync 提交於 55 年 前

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 7.9 KB
 
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
4 *
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/
9 *
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.
14 *
15 * The Original Code is the Netscape Portable Runtime (NSPR).
16 *
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.
21 *
22 * Contributor(s):
23 *
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.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/*
39** File: switch.c
40** Description: trying to time context switches
41*/
42
43#include "prinit.h"
44#include "prcvar.h"
45#include "prmem.h"
46#include "prinrval.h"
47#include "prlock.h"
48#include "prlog.h"
49#include "prthread.h"
50#include "prprf.h"
51
52#include "plerror.h"
53#include "plgetopt.h"
54
55#if defined(XP_MAC)
56#include "pprio.h"
57#define printf PR_LogPrint
58#else
59#include "private/pprio.h"
60#endif
61
62#include <stdlib.h>
63
64#define INNER_LOOPS 100
65#define DEFAULT_LOOPS 100
66#define DEFAULT_THREADS 10
67
68static PRFileDesc *debug_out = NULL;
69static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE;
70
71typedef struct Shared
72{
73 PRLock *ml;
74 PRCondVar *cv;
75 PRBool twiddle;
76 PRThread *thread;
77 struct Shared *next;
78} Shared;
79
80static void Help(void)
81{
82 debug_out = PR_STDOUT;
83
84 PR_fprintf(
85 debug_out, "Usage: >./switch [-c n] [-t n] [-d] [-v] [-G] [-C n]\n");
86 PR_fprintf(
87 debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
88 PR_fprintf(
89 debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
90 PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
91 PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
92 PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n");
93 PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
94} /* Help */
95
96static void PR_CALLBACK Notified(void *arg)
97{
98 Shared *shared = (Shared*)arg;
99 PRStatus status = PR_SUCCESS;
100 while (PR_SUCCESS == status)
101 {
102 PR_Lock(shared->ml);
103 while (shared->twiddle && (PR_SUCCESS == status))
104 status = PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT);
105 if (verbosity) PR_fprintf(debug_out, "+");
106 shared->twiddle = PR_TRUE;
107 shared->next->twiddle = PR_FALSE;
108 PR_NotifyCondVar(shared->next->cv);
109 PR_Unlock(shared->ml);
110 }
111} /* Notified */
112
113static Shared home;
114PRIntn PR_CALLBACK Switch(PRIntn argc, char **argv)
115{
116 PLOptStatus os;
117 PRStatus status;
118 PRBool help = PR_FALSE;
119 PRUintn concurrency = 1;
120 Shared *shared, *link;
121 PRIntervalTime timein, timeout;
122 PRThreadScope thread_scope = PR_LOCAL_THREAD;
123 PRUintn thread_count, inner_count, loop_count, average;
124 PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS;
125 PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G");
126 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
127 {
128 if (PL_OPT_BAD == os) continue;
129 switch (opt->option)
130 {
131 case 'v': /* verbose mode */
132 verbosity = PR_TRUE;
133 case 'd': /* debug mode */
134 debug_mode = PR_TRUE;
135 break;
136 case 'c': /* loop counter */
137 loop_limit = atoi(opt->value);
138 break;
139 case 't': /* thread limit */
140 thread_limit = atoi(opt->value);
141 break;
142 case 'C': /* Concurrency limit */
143 concurrency = atoi(opt->value);
144 break;
145 case 'G': /* global threads only */
146 thread_scope = PR_GLOBAL_THREAD;
147 break;
148 case 'h': /* help message */
149 Help();
150 help = PR_TRUE;
151 break;
152 default:
153 break;
154 }
155 }
156 PL_DestroyOptState(opt);
157
158 if (help) return -1;
159
160 if (PR_TRUE == debug_mode)
161 {
162 debug_out = PR_STDOUT;
163 PR_fprintf(debug_out, "Test parameters\n");
164 PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit);
165 PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit);
166 PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
167 PR_fprintf(
168 debug_out, "\tThread type: %s\n",
169 (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
170 }
171
172 PR_SetConcurrency(concurrency);
173
174 link = &home;
175 home.ml = PR_NewLock();
176 home.cv = PR_NewCondVar(home.ml);
177 home.twiddle = PR_FALSE;
178 home.next = NULL;
179
180 timeout = 0;
181
182 for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
183 {
184 shared = PR_NEWZAP(Shared);
185
186 shared->ml = home.ml;
187 shared->cv = PR_NewCondVar(home.ml);
188 shared->twiddle = PR_TRUE;
189 shared->next = link;
190 link = shared;
191
192 shared->thread = PR_CreateThread(
193 PR_USER_THREAD, Notified, shared,
194 PR_PRIORITY_HIGH, thread_scope,
195 PR_JOINABLE_THREAD, 0);
196 PR_ASSERT(shared->thread != NULL);
197 if (NULL == shared->thread)
198 failed = PR_TRUE;
199 }
200
201 for (loop_count = 1; loop_count <= loop_limit; ++loop_count)
202 {
203 timein = PR_IntervalNow();
204 for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count)
205 {
206 PR_Lock(home.ml);
207 home.twiddle = PR_TRUE;
208 shared->twiddle = PR_FALSE;
209 PR_NotifyCondVar(shared->cv);
210 while (home.twiddle)
211 {
212 status = PR_WaitCondVar(home.cv, PR_INTERVAL_NO_TIMEOUT);
213 if (PR_FAILURE == status)
214 failed = PR_TRUE;
215 }
216 PR_Unlock(home.ml);
217 }
218 timeout += (PR_IntervalNow() - timein);
219 }
220
221 if (debug_mode)
222 {
223 average = PR_IntervalToMicroseconds(timeout)
224 / (INNER_LOOPS * loop_limit * thread_count);
225 PR_fprintf(
226 debug_out, "Average switch times %d usecs for %d threads\n",
227 average, thread_limit);
228 }
229
230 link = shared;
231 for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
232 {
233 if (&home == link) break;
234 status = PR_Interrupt(link->thread);
235 if (PR_SUCCESS != status)
236 {
237 failed = PR_TRUE;
238 if (debug_mode)
239 PL_FPrintError(debug_out, "Failed to interrupt");
240 }
241 link = link->next;
242 }
243
244 for (thread_count = 1; thread_count <= thread_limit; ++thread_count)
245 {
246 link = shared->next;
247 status = PR_JoinThread(shared->thread);
248 if (PR_SUCCESS != status)
249 {
250 failed = PR_TRUE;
251 if (debug_mode)
252 PL_FPrintError(debug_out, "Failed to join");
253 }
254 PR_DestroyCondVar(shared->cv);
255 PR_DELETE(shared);
256 if (&home == link) break;
257 shared = link;
258 }
259 PR_DestroyCondVar(home.cv);
260 PR_DestroyLock(home.ml);
261
262 PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n"));
263 return ((failed) ? 1 : 0);
264} /* Switch */
265
266PRIntn main(PRIntn argc, char **argv)
267{
268 PRIntn result;
269 PR_STDIO_INIT();
270 result = PR_Initialize(Switch, argc, argv, 0);
271 return result;
272} /* main */
273
274/* switch.c */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette