blob: f0d66c75c1f67a8ca896354e9debdb4609f4fb22 [file] [log] [blame]
Brett Cannon66865d22008-03-13 20:27:00 +00001import os
2import unittest
Guido van Rossumb26a1b41998-05-20 17:05:52 +00003import random
Brett Cannon66865d22008-03-13 20:27:00 +00004from test import test_support
Guido van Rossumcc544171994-04-14 20:28:41 +00005import thread
6import time
7
Guido van Rossumcc544171994-04-14 20:28:41 +00008
Brett Cannon66865d22008-03-13 20:27:00 +00009NUMTASKS = 10
10NUMTRIPS = 3
Guido van Rossumd3b68421994-05-23 12:17:36 +000011
Guido van Rossumcc544171994-04-14 20:28:41 +000012
Brett Cannon66865d22008-03-13 20:27:00 +000013def verbose_print(arg):
14 """Helper function for printing out debugging output."""
15 if test_support.verbose:
16 print arg
Guido van Rossumcc544171994-04-14 20:28:41 +000017
Guido van Rossumcc544171994-04-14 20:28:41 +000018
Brett Cannon66865d22008-03-13 20:27:00 +000019class BasicThreadTest(unittest.TestCase):
Guido van Rossumd3b68421994-05-23 12:17:36 +000020
Brett Cannon66865d22008-03-13 20:27:00 +000021 def setUp(self):
22 self.done_mutex = thread.allocate_lock()
23 self.done_mutex.acquire()
24 self.running_mutex = thread.allocate_lock()
25 self.random_mutex = thread.allocate_lock()
26 self.running = 0
27 self.next_ident = 0
28
29
30class ThreadRunningTests(BasicThreadTest):
31
32 def newtask(self):
33 with self.running_mutex:
34 self.next_ident += 1
35 verbose_print("creating task %s" % self.next_ident)
36 thread.start_new_thread(self.task, (self.next_ident,))
37 self.running += 1
38
39 def task(self, ident):
40 with self.random_mutex:
41 delay = random.random() * NUMTASKS
42 verbose_print("task %s will run for %s" % (ident, round(delay, 1)))
43 time.sleep(delay)
44 verbose_print("task %s done" % ident)
45 with self.running_mutex:
46 self.running -= 1
47 if self.running == 0:
48 self.done_mutex.release()
49
50 def test_starting_threads(self):
51 # Basic test for thread creation.
52 for i in range(NUMTASKS):
53 self.newtask()
54 verbose_print("waiting for tasks to complete...")
55 self.done_mutex.acquire()
56 verbose_print("all tasks done")
57
58 def test_stack_size(self):
59 # Various stack size tests.
60 self.assertEquals(thread.stack_size(), 0, "intial stack size is not 0")
61
62 thread.stack_size(0)
63 self.assertEquals(thread.stack_size(), 0, "stack_size not reset to default")
64
65 if os.name not in ("nt", "os2", "posix"):
66 return
67
68 tss_supported = True
69 try:
70 thread.stack_size(4096)
71 except ValueError:
72 verbose_print("caught expected ValueError setting "
73 "stack_size(4096)")
74 except thread.error:
75 tss_supported = False
76 verbose_print("platform does not support changing thread stack "
77 "size")
78
79 if tss_supported:
80 fail_msg = "stack_size(%d) failed - should succeed"
81 for tss in (262144, 0x100000, 0):
82 thread.stack_size(tss)
83 self.assertEquals(thread.stack_size(), tss, fail_msg % tss)
84 verbose_print("successfully set stack_size(%d)" % tss)
85
86 for tss in (262144, 0x100000):
87 verbose_print("trying stack_size = (%d)" % tss)
88 self.next_ident = 0
89 for i in range(NUMTASKS):
90 self.newtask()
91
92 verbose_print("waiting for all tasks to complete")
93 self.done_mutex.acquire()
94 verbose_print("all tasks done")
95
96 thread.stack_size(0)
97
98
99class Barrier:
100 def __init__(self, num_threads):
101 self.num_threads = num_threads
Fred Drake004d5e62000-10-23 17:22:08 +0000102 self.waiting = 0
Brett Cannon66865d22008-03-13 20:27:00 +0000103 self.checkin_mutex = thread.allocate_lock()
104 self.checkout_mutex = thread.allocate_lock()
105 self.checkout_mutex.acquire()
Guido van Rossumd3b68421994-05-23 12:17:36 +0000106
Fred Drake004d5e62000-10-23 17:22:08 +0000107 def enter(self):
Brett Cannon66865d22008-03-13 20:27:00 +0000108 self.checkin_mutex.acquire()
Fred Drake004d5e62000-10-23 17:22:08 +0000109 self.waiting = self.waiting + 1
Brett Cannon66865d22008-03-13 20:27:00 +0000110 if self.waiting == self.num_threads:
111 self.waiting = self.num_threads - 1
112 self.checkout_mutex.release()
Fred Drake004d5e62000-10-23 17:22:08 +0000113 return
Brett Cannon66865d22008-03-13 20:27:00 +0000114 self.checkin_mutex.release()
Guido van Rossumd3b68421994-05-23 12:17:36 +0000115
Brett Cannon66865d22008-03-13 20:27:00 +0000116 self.checkout_mutex.acquire()
Fred Drake004d5e62000-10-23 17:22:08 +0000117 self.waiting = self.waiting - 1
118 if self.waiting == 0:
Brett Cannon66865d22008-03-13 20:27:00 +0000119 self.checkin_mutex.release()
Fred Drake004d5e62000-10-23 17:22:08 +0000120 return
Brett Cannon66865d22008-03-13 20:27:00 +0000121 self.checkout_mutex.release()
Guido van Rossumd3b68421994-05-23 12:17:36 +0000122
Guido van Rossumd3b68421994-05-23 12:17:36 +0000123
Brett Cannon66865d22008-03-13 20:27:00 +0000124class BarrierTest(BasicThreadTest):
Andrew MacIntyre92913322006-06-13 15:04:24 +0000125
Brett Cannon66865d22008-03-13 20:27:00 +0000126 def test_barrier(self):
127 self.bar = Barrier(NUMTASKS)
128 self.running = NUMTASKS
129 for i in range(NUMTASKS):
130 thread.start_new_thread(self.task2, (i,))
131 verbose_print("waiting for tasks to end")
132 self.done_mutex.acquire()
133 verbose_print("tasks done")
Andrew MacIntyre92913322006-06-13 15:04:24 +0000134
Brett Cannon66865d22008-03-13 20:27:00 +0000135 def task2(self, ident):
136 for i in range(NUMTRIPS):
137 if ident == 0:
138 # give it a good chance to enter the next
139 # barrier before the others are all out
140 # of the current one
141 delay = 0.001
142 else:
143 with self.random_mutex:
144 delay = random.random() * NUMTASKS
145 verbose_print("task %s will run for %s" % (ident, round(delay, 1)))
146 time.sleep(delay)
147 verbose_print("task %s entering %s" % (ident, i))
148 self.bar.enter()
149 verbose_print("task %s leaving barrier" % ident)
150 with self.running_mutex:
151 self.running -= 1
152 # Must release mutex before releasing done, else the main thread can
153 # exit and set mutex to None as part of global teardown; then
154 # mutex.release() raises AttributeError.
155 finished = self.running == 0
156 if finished:
157 self.done_mutex.release()
Andrew MacIntyre92913322006-06-13 15:04:24 +0000158
Andrew MacIntyre92913322006-06-13 15:04:24 +0000159
Brett Cannon66865d22008-03-13 20:27:00 +0000160def test_main():
161 test_support.run_unittest(ThreadRunningTests, BarrierTest)
Andrew MacIntyre92913322006-06-13 15:04:24 +0000162
Brett Cannon66865d22008-03-13 20:27:00 +0000163if __name__ == "__main__":
164 test_main()