Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added some stress tests and test driver for them.
svn path=/trunk/mono/; revision=40972
- Loading branch information
Showing
7 changed files
with
551 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,68 @@ | |||
using System; | |||
using System.Threading; | |||
using System.Collections; | |||
|
|||
class T { | |||
/* each thread will create n domains */ | |||
static int threads = 5; | |||
static int domains = 100; | |||
static int allocs = 1000; | |||
static int loops = 1; | |||
static int errors = 0; | |||
|
|||
public static void worker () { | |||
Console.WriteLine ("Domain start " + AppDomain.CurrentDomain.FriendlyName + " " + Thread.CurrentThread.GetHashCode ()); | |||
ArrayList list = new ArrayList (); | |||
for (int i = 0; i < allocs; ++i) { | |||
list.Add (new object ()); | |||
list.Add (new ArrayList ()); | |||
list.Add (new String ('x', 34)); | |||
int[] a = new int [5]; | |||
list.Add (new WeakReference (a)); | |||
if ((i % 1024) == 0) { | |||
list.RemoveRange (0, list.Count / 2); | |||
} | |||
} | |||
Console.WriteLine ("Domain end " + AppDomain.CurrentDomain.FriendlyName + " " + Thread.CurrentThread.GetHashCode ()); | |||
} | |||
|
|||
static void thread_start () { | |||
Console.WriteLine ("Thread start " + Thread.CurrentThread.GetHashCode ()); | |||
for (int i = 0; i < domains; ++i) { | |||
AppDomain appDomain = AppDomain.CreateDomain("Test-" + i); | |||
appDomain.DoCallBack (new CrossAppDomainDelegate (worker)); | |||
try { | |||
AppDomain.Unload (appDomain); | |||
} catch { | |||
Interlocked.Increment (ref errors); | |||
Console.WriteLine ("Error unloading " + "Test-" + i); | |||
} | |||
} | |||
Console.WriteLine ("Thread end " + Thread.CurrentThread.GetHashCode ()); | |||
} | |||
static int Main (string[] args) { | |||
if (args.Length > 0) | |||
threads = int.Parse (args [0]); | |||
if (args.Length > 1) | |||
domains = int.Parse (args [1]); | |||
if (args.Length > 2) | |||
allocs = int.Parse (args [2]); | |||
if (args.Length > 3) | |||
loops = int.Parse (args [3]); | |||
for (int j = 0; j < loops; ++j) { | |||
Thread[] ta = new Thread [threads]; | |||
for (int i = 0; i < threads; ++i) { | |||
Thread t = new Thread (new ThreadStart (thread_start)); | |||
ta [i] = t; | |||
t.Start (); | |||
} | |||
for (int i = 0; i < threads; ++i) { | |||
ta [i].Join (); | |||
} | |||
} | |||
//thread_start (); | |||
//Console.ReadLine (); | |||
return 0; | |||
} | |||
} | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,26 @@ | |||
using System; | |||
|
|||
class T { | |||
|
|||
static int count = 1000000; | |||
static int loops = 20; | |||
static object obj; | |||
static object obj2; | |||
|
|||
static void work () { | |||
for (int i = 0; i < count; ++i) { | |||
obj = new object (); | |||
obj2 = i; | |||
} | |||
} | |||
static void Main (string[] args) { | |||
if (args.Length > 0) | |||
loops = int.Parse (args [0]); | |||
if (args.Length > 1) | |||
count = int.Parse (args [1]); | |||
for (int i = 0; i < loops; ++i) { | |||
work (); | |||
} | |||
} | |||
} | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,117 @@ | |||
using System; | |||
using System.Runtime.InteropServices; | |||
|
|||
// in this test we spend | |||
// 30% of the time locking | |||
// 10 % allocating the handles | |||
class T { | |||
|
|||
static GCHandle[] handle_array; | |||
|
|||
static int count = 4 * 400000; /* multiple of handle types */ | |||
static int loops = 2; | |||
|
|||
static void build_array () { | |||
int i; | |||
handle_array = new GCHandle [count]; | |||
|
|||
for (i = 0; i < count; ++i) { | |||
GCHandleType t = (GCHandleType) (i & 3); | |||
handle_array [i] = GCHandle.Alloc (i, t); | |||
} | |||
} | |||
static void get_stats (){ | |||
int i; | |||
object o; | |||
int has_target = 0; | |||
int is_allocated = 0; | |||
int normal_reclaimed = 0; | |||
for (i = 0; i < count; ++i) { | |||
GCHandleType t = (GCHandleType) (i & 3); | |||
if (handle_array [i].IsAllocated) | |||
is_allocated++; | |||
else | |||
continue; | |||
o = handle_array [i].Target; | |||
if (o != null) { | |||
has_target++; | |||
int val = (int)o; | |||
if (val != i) | |||
Console.WriteLine ("obj at {0} inconsistent: {1}", i, val); | |||
} else { | |||
if (t == GCHandleType.Normal || t == GCHandleType.Pinned) { | |||
normal_reclaimed++; | |||
} | |||
} | |||
} | |||
Console.WriteLine ("allocated: {0}, has target: {1}, normal reclaimed: {2}", is_allocated, has_target, normal_reclaimed); | |||
} | |||
|
|||
static void free_some (int d) { | |||
int i; | |||
int freed = 0; | |||
for (i = 0; i < count; ++i) { | |||
if ((i % d) == 0) { | |||
if (handle_array [i].IsAllocated) { | |||
handle_array [i].Free (); | |||
freed++; | |||
} | |||
} | |||
} | |||
Console.WriteLine ("freed: {0}", freed); | |||
} | |||
|
|||
static void alloc_many () { | |||
int small_count = count / 2; | |||
GCHandle[] more = new GCHandle [small_count]; | |||
int i; | |||
for (i = 0; i < small_count; ++i) { | |||
GCHandleType t = (GCHandleType) (i & 3); | |||
more [i] = GCHandle.Alloc (i, t); | |||
} | |||
for (i = 0; i < small_count; ++i) { | |||
more [i].Free (); | |||
} | |||
Console.WriteLine ("alloc many: {0}", small_count); | |||
} | |||
|
|||
static void Main (string[] args) { | |||
if (args.Length > 0) | |||
count = 4 * int.Parse (args [0]); | |||
if (args.Length > 1) | |||
loops = int.Parse (args [1]); | |||
|
|||
for (int j = 0; j < loops; ++j) { | |||
do_one (); | |||
} | |||
} | |||
|
|||
static void do_one () { | |||
Console.WriteLine ("start"); | |||
build_array (); | |||
get_stats (); | |||
GC.Collect (); | |||
Console.WriteLine ("after collect"); | |||
get_stats (); | |||
free_some (10); | |||
Console.WriteLine ("after free(10)"); | |||
get_stats (); | |||
free_some (4); | |||
Console.WriteLine ("after free(4)"); | |||
get_stats (); | |||
GC.Collect (); | |||
Console.WriteLine ("after collect"); | |||
get_stats (); | |||
for (int i = 0; i < 10; ++i) | |||
alloc_many (); | |||
Console.WriteLine ("after alloc_many"); | |||
get_stats (); | |||
free_some (1); | |||
Console.WriteLine ("after free all"); | |||
get_stats (); | |||
GC.Collect (); | |||
Console.WriteLine ("after collect"); | |||
get_stats (); | |||
} | |||
} | |||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,60 @@ | |||
using System; | |||
using System.Threading; | |||
|
|||
class T { | |||
static int count = 20000; | |||
static int loops = 80; | |||
static int threads = 10; | |||
static object global_obj; | |||
static void stress_loop () { | |||
object obj = new object (); | |||
lock (obj) { | |||
object [] array = new object [count]; | |||
for (int i = 0; i < count; ++i) { | |||
array [i] = new object (); | |||
} | |||
for (int i = 0; i < count; ++i) { | |||
lock (array [i]) { | |||
global_obj = new String ('x', 32); | |||
if ((i % 12) == 0) { | |||
array [i] = global_obj; | |||
} | |||
} | |||
} | |||
// again, after a GC | |||
GC.Collect (); | |||
for (int i = 0; i < count; ++i) { | |||
lock (array [i]) { | |||
} | |||
} | |||
// two times, with feeling | |||
for (int i = 0; i < count; ++i) { | |||
lock (array [i]) { | |||
for (int j = 0; i < count; ++i) { | |||
lock (array [j]) { | |||
} | |||
} | |||
} | |||
} | |||
} | |||
} | |||
|
|||
static void worker () { | |||
for (int i = 0; i < loops; ++i) | |||
stress_loop (); | |||
} | |||
static void Main (string[] args) { | |||
if (args.Length > 0) | |||
loops = int.Parse (args [0]); | |||
if (args.Length > 1) | |||
count = int.Parse (args [1]); | |||
if (args.Length > 1) | |||
threads = int.Parse (args [2]); | |||
for (int i = 0; i < threads; ++i) { | |||
Thread t = new Thread (new ThreadStart (worker)); | |||
t.Start (); | |||
} | |||
/* for good measure */ | |||
worker (); | |||
} | |||
} |
Oops, something went wrong.