VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/pr/tests/lockfile.c@ 22683

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

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 8.5 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: lockfile.c
40** Purpose: test basic locking functions
41** Just because this times stuff, don't think its a perforamnce
42** test!!!
43**
44** Modification History:
45** 19-May-97 AGarcia- Converted the test to accomodate the debug_mode flag.
46** The debug mode will print all of the printfs associated with this test.
47** The regress mode will be the default mode. Since the regress tool limits
48** the output to a one line status:PASS or FAIL,all of the printf statements
49** have been handled with an if (debug_mode) statement.
50** 04-June-97 AGarcia removed the Test_Result function. Regress tool has been updated to
51** recognize the return code from tha main program.
52***********************************************************************/
53/***********************************************************************
54** Includes
55***********************************************************************/
56/* Used to get the command line option */
57#include "plgetopt.h"
58
59#include "prcmon.h"
60#include "prerror.h"
61#include "prinit.h"
62#include "prinrval.h"
63#include "prlock.h"
64#include "prlog.h"
65#include "prmon.h"
66#include "prthread.h"
67#include "prtypes.h"
68
69#ifndef XP_MAC
70#include "private/pprio.h"
71#else
72#include "pprio.h"
73#endif
74
75#include <stdio.h>
76#include <stdlib.h>
77#include <string.h>
78
79#ifdef XP_MAC
80#include "prlog.h"
81#define printf PR_LogPrint
82extern void SetupMacPrintfLog(char *logFile);
83#endif
84
85PRIntn failed_already=0;
86PRIntn debug_mode;
87
88const static PRIntervalTime contention_interval = 50;
89
90typedef struct LockContentious_s {
91 PRLock *ml;
92 PRInt32 loops;
93 PRIntervalTime overhead;
94 PRIntervalTime interval;
95} LockContentious_t;
96
97#define LOCKFILE "prlock.fil"
98
99
100
101static PRIntervalTime NonContentiousLock(PRInt32 loops)
102{
103 PRFileDesc *_lockfile;
104 while (loops-- > 0)
105 {
106 _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666);
107 if (!_lockfile) {
108 if (debug_mode) printf(
109 "could not create lockfile: %d [%d]\n",
110 PR_GetError(), PR_GetOSError());
111 return PR_INTERVAL_NO_TIMEOUT;
112 }
113 PR_LockFile(_lockfile);
114 PR_UnlockFile(_lockfile);
115 PR_Close(_lockfile);
116 }
117 return 0;
118} /* NonContentiousLock */
119
120static void PR_CALLBACK LockContender(void *arg)
121{
122 LockContentious_t *contention = (LockContentious_t*)arg;
123 PRFileDesc *_lockfile;
124 while (contention->loops-- > 0)
125 {
126 _lockfile = PR_Open(LOCKFILE, PR_CREATE_FILE|PR_RDWR, 0666);
127 if (!_lockfile) {
128 if (debug_mode) printf(
129 "could not create lockfile: %d [%d]\n",
130 PR_GetError(), PR_GetOSError());
131 break;
132 }
133 PR_LockFile(_lockfile);
134 PR_Sleep(contention->interval);
135 PR_UnlockFile(_lockfile);
136 PR_Close(_lockfile);
137 }
138
139} /* LockContender */
140
141/*
142** Win16 requires things passed to Threads not be on the stack
143*/
144static LockContentious_t contention;
145
146static PRIntervalTime ContentiousLock(PRInt32 loops)
147{
148 PRStatus status;
149 PRThread *thread = NULL;
150 PRIntervalTime overhead, timein = PR_IntervalNow();
151
152 contention.loops = loops;
153 contention.overhead = 0;
154 contention.ml = PR_NewLock();
155 contention.interval = contention_interval;
156 thread = PR_CreateThread(
157 PR_USER_THREAD, LockContender, &contention,
158 PR_PRIORITY_LOW, PR_LOCAL_THREAD, PR_JOINABLE_THREAD, 0);
159 PR_ASSERT(thread != NULL);
160
161 overhead = PR_IntervalNow() - timein;
162
163 while (contention.loops > 0)
164 {
165 PR_Lock(contention.ml);
166 contention.overhead += contention.interval;
167 PR_Sleep(contention.interval);
168 PR_Unlock(contention.ml);
169 }
170
171 timein = PR_IntervalNow();
172 status = PR_JoinThread(thread);
173 PR_DestroyLock(contention.ml);
174 overhead += (PR_IntervalNow() - timein);
175 return overhead + contention.overhead;
176} /* ContentiousLock */
177
178static PRIntervalTime Test(
179 const char* msg, PRIntervalTime (*test)(PRInt32 loops),
180 PRInt32 loops, PRIntervalTime overhead)
181{
182 /*
183 * overhead - overhead not measured by the test.
184 * duration - wall clock time it took to perform test.
185 * predicted - extra time test says should not be counted
186 *
187 * Time accountable to the test is duration - overhead - predicted
188 * All times are Intervals and accumulated for all iterations.
189 */
190 PRFloat64 elapsed;
191 PRIntervalTime accountable, duration;
192 PRUintn spaces = strlen(msg);
193 PRIntervalTime timeout, timein = PR_IntervalNow();
194 PRIntervalTime predicted = test(loops);
195 timeout = PR_IntervalNow();
196 duration = timeout - timein;
197 accountable = duration - predicted;
198 accountable -= overhead;
199 elapsed = (PRFloat64)PR_IntervalToMicroseconds(accountable);
200 if (debug_mode) printf("%s:", msg);
201 while (spaces++ < 50) if (debug_mode) printf(" ");
202 if ((PRInt32)accountable < 0) {
203 if (debug_mode) printf("*****.** usecs/iteration\n");
204 } else {
205 if (debug_mode) printf("%8.2f usecs/iteration\n", elapsed/loops);
206 }
207 return duration;
208} /* Test */
209
210int main(int argc, char **argv)
211{
212 PRIntervalTime duration;
213 PRUint32 cpu, cpus = 2;
214 PRInt32 loops = 100;
215
216
217 /* The command line argument: -d is used to determine if the test is being run
218 in debug mode. The regress tool requires only one line output:PASS or FAIL.
219 All of the printfs associated with this test has been handled with a if (debug_mode)
220 test.
221 Usage: test_name -d
222 */
223 PLOptStatus os;
224 PLOptState *opt = PL_CreateOptState(argc, argv, "d:");
225 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
226 {
227 if (PL_OPT_BAD == os) continue;
228 switch (opt->option)
229 {
230 case 'd': /* debug mode */
231 debug_mode = 1;
232 break;
233 default:
234 break;
235 }
236 }
237 PL_DestroyOptState(opt);
238
239 /* main test */
240
241 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
242 PR_STDIO_INIT();
243
244#ifdef XP_MAC
245 SetupMacPrintfLog("lockfile.log");
246 debug_mode = 1;
247#endif
248
249 if (argc > 1) loops = atoi(argv[1]);
250 if (loops == 0) loops = 100;
251 if (debug_mode) printf("Lock: Using %d loops\n", loops);
252
253 cpus = (argc < 3) ? 2 : atoi(argv[2]);
254 if (cpus == 0) cpus = 2;
255 if (debug_mode) printf("Lock: Using %d cpu(s)\n", cpus);
256
257
258 for (cpu = 1; cpu <= cpus; ++cpu)
259 {
260 if (debug_mode) printf("\nLockFile: Using %d CPU(s)\n", cpu);
261 PR_SetConcurrency(cpu);
262
263 duration = Test("LockFile non-contentious locking/unlocking", NonContentiousLock, loops, 0);
264 (void)Test("LockFile contentious locking/unlocking", ContentiousLock, loops, duration);
265 }
266
267 PR_Delete(LOCKFILE); /* try to get rid of evidence */
268
269 if (debug_mode) printf("%s: test %s\n", "Lock(mutex) test", ((failed_already) ? "failed" : "passed"));
270 if(failed_already)
271 return 1;
272 else
273 return 0;
274} /* main */
275
276/* testlock.c */
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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