xpcom/tests/TestDeadlockDetectorScalability.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
michael@0 2 * vim: sw=4 ts=4 et :
michael@0 3 * This Source Code Form is subject to the terms of the Mozilla Public
michael@0 4 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 6
michael@0 7 #include "TestHarness.h"
michael@0 8
michael@0 9 //#define OLD_API
michael@0 10
michael@0 11 #define PASS() \
michael@0 12 do { \
michael@0 13 passed(__FUNCTION__); \
michael@0 14 return NS_OK; \
michael@0 15 } while (0)
michael@0 16
michael@0 17 #define FAIL(why) \
michael@0 18 do { \
michael@0 19 fail("%s | %s - %s", __FILE__, __FUNCTION__, why); \
michael@0 20 return NS_ERROR_FAILURE; \
michael@0 21 } while (0)
michael@0 22
michael@0 23 #ifdef OLD_API
michael@0 24 # include "nsAutoLock.h"
michael@0 25 typedef PRLock* moz_lock_t;
michael@0 26 # define NEWLOCK(n) nsAutoLock::NewLock(n)
michael@0 27 # define DELETELOCK(v) nsAutoLock::DestroyLock(v)
michael@0 28 # define AUTOLOCK(v, l) nsAutoLock v(l)
michael@0 29 #else
michael@0 30 # include "mozilla/Mutex.h"
michael@0 31 typedef mozilla::Mutex* moz_lock_t;
michael@0 32 # define NEWLOCK(n) new mozilla::Mutex(n)
michael@0 33 # define DELETELOCK(v) delete (v)
michael@0 34 # define AUTOLOCK(v, l) mozilla::MutexAutoLock v(*l)
michael@0 35 #endif
michael@0 36
michael@0 37 // def/undef these to run particular tests.
michael@0 38 #undef DD_TEST1
michael@0 39 #undef DD_TEST2
michael@0 40 #undef DD_TEST3
michael@0 41
michael@0 42 //-----------------------------------------------------------------------------
michael@0 43
michael@0 44 #ifdef DD_TEST1
michael@0 45
michael@0 46 static void
michael@0 47 AllocLockRecurseUnlockFree(int i)
michael@0 48 {
michael@0 49 if (0 == i)
michael@0 50 return;
michael@0 51
michael@0 52 moz_lock_t lock = NEWLOCK("deadlockDetector.scalability.t1");
michael@0 53 {
michael@0 54 AUTOLOCK(_, lock);
michael@0 55 AllocLockRecurseUnlockFree(i - 1);
michael@0 56 }
michael@0 57 DELETELOCK(lock);
michael@0 58 }
michael@0 59
michael@0 60 // This test creates a resource dependency chain N elements long, then
michael@0 61 // frees all the resources in the chain.
michael@0 62 static nsresult
michael@0 63 LengthNDepChain(int N)
michael@0 64 {
michael@0 65 AllocLockRecurseUnlockFree(N);
michael@0 66 PASS();
michael@0 67 }
michael@0 68
michael@0 69 #endif
michael@0 70
michael@0 71 //-----------------------------------------------------------------------------
michael@0 72
michael@0 73 #ifdef DD_TEST2
michael@0 74
michael@0 75 // This test creates a single lock that is ordered < N resources, then
michael@0 76 // repeatedly exercises this order k times.
michael@0 77 static nsresult
michael@0 78 OneLockNDeps(const int N, const int K)
michael@0 79 {
michael@0 80 moz_lock_t lock = NEWLOCK("deadlockDetector.scalability.t2.master");
michael@0 81 moz_lock_t* locks = new moz_lock_t[N];
michael@0 82 if (!locks)
michael@0 83 NS_RUNTIMEABORT("couldn't allocate lock array");
michael@0 84
michael@0 85 for (int i = 0; i < N; ++i)
michael@0 86 locks[i] =
michael@0 87 NEWLOCK("deadlockDetector.scalability.t2.dep");
michael@0 88
michael@0 89 // establish orders
michael@0 90 {AUTOLOCK(m, lock);
michael@0 91 for (int i = 0; i < N; ++i)
michael@0 92 AUTOLOCK(s, locks[i]);
michael@0 93 }
michael@0 94
michael@0 95 // exercise order check
michael@0 96 {AUTOLOCK(m, lock);
michael@0 97 for (int i = 0; i < K; ++i)
michael@0 98 for (int j = 0; j < N; ++j)
michael@0 99 AUTOLOCK(s, locks[i]);
michael@0 100 }
michael@0 101
michael@0 102 for (int i = 0; i < N; ++i)
michael@0 103 DELETELOCK(locks[i]);
michael@0 104 delete[] locks;
michael@0 105
michael@0 106 PASS();
michael@0 107 }
michael@0 108
michael@0 109 #endif
michael@0 110
michael@0 111 //-----------------------------------------------------------------------------
michael@0 112
michael@0 113 #ifdef DD_TEST3
michael@0 114
michael@0 115 // This test creates N resources and adds the theoretical maximum number
michael@0 116 // of dependencies, O(N^2). It then repeats that sequence of
michael@0 117 // acquisitions k times. Finally, all resources are freed.
michael@0 118 //
michael@0 119 // It's very difficult to perform well on this test. It's put forth as a
michael@0 120 // challenge problem.
michael@0 121
michael@0 122 static nsresult
michael@0 123 MaxDepsNsq(const int N, const int K)
michael@0 124 {
michael@0 125 moz_lock_t* locks = new moz_lock_t[N];
michael@0 126 if (!locks)
michael@0 127 NS_RUNTIMEABORT("couldn't allocate lock array");
michael@0 128
michael@0 129 for (int i = 0; i < N; ++i)
michael@0 130 locks[i] = NEWLOCK("deadlockDetector.scalability.t3");
michael@0 131
michael@0 132 for (int i = 0; i < N; ++i) {
michael@0 133 AUTOLOCK(al1, locks[i]);
michael@0 134 for (int j = i+1; j < N; ++j)
michael@0 135 AUTOLOCK(al2, locks[j]);
michael@0 136 }
michael@0 137
michael@0 138 for (int i = 0; i < K; ++i) {
michael@0 139 for (int j = 0; j < N; ++j) {
michael@0 140 AUTOLOCK(al1, locks[j]);
michael@0 141 for (int k = j+1; k < N; ++k)
michael@0 142 AUTOLOCK(al2, locks[k]);
michael@0 143 }
michael@0 144 }
michael@0 145
michael@0 146 for (int i = 0; i < N; ++i)
michael@0 147 DELETELOCK(locks[i]);
michael@0 148 delete[] locks;
michael@0 149
michael@0 150 PASS();
michael@0 151 }
michael@0 152
michael@0 153 #endif
michael@0 154
michael@0 155 //-----------------------------------------------------------------------------
michael@0 156
michael@0 157 int
michael@0 158 main(int argc, char** argv)
michael@0 159 {
michael@0 160 ScopedXPCOM xpcom("Deadlock detector scalability (" __FILE__ ")");
michael@0 161 if (xpcom.failed())
michael@0 162 return 1;
michael@0 163
michael@0 164 int rv = 0;
michael@0 165
michael@0 166 // Uncomment these tests to run them. Not expected to be common.
michael@0 167
michael@0 168 #ifndef DD_TEST1
michael@0 169 puts("Skipping not-requested LengthNDepChain() test");
michael@0 170 #else
michael@0 171 if (NS_FAILED(LengthNDepChain(1 << 14))) // 16K
michael@0 172 rv = 1;
michael@0 173 #endif
michael@0 174
michael@0 175 #ifndef DD_TEST2
michael@0 176 puts("Skipping not-requested OneLockNDeps() test");
michael@0 177 #else
michael@0 178 if (NS_FAILED(OneLockNDeps(1 << 14, 100))) // 16k
michael@0 179 rv = 1;
michael@0 180 #endif
michael@0 181
michael@0 182 #ifndef DD_TEST3
michael@0 183 puts("Skipping not-requested MaxDepsNsq() test");
michael@0 184 #else
michael@0 185 if (NS_FAILED(MaxDepsNsq(1 << 10, 10))) // 1k
michael@0 186 rv = 1;
michael@0 187 #endif
michael@0 188
michael@0 189 return rv;
michael@0 190 }

mercurial