# Very rudimentary test of thread module

# Create a bunch of threads, let each do some work, wait until all are done

from test_support import verbose
import random
import thread
import time

mutex = thread.allocate_lock()
rmutex = thread.allocate_lock() # for calls to random
running = 0
done = thread.allocate_lock()
done.acquire()

numtasks = 10

def task(ident):
    global running
    rmutex.acquire()
    delay = random.random() * numtasks
    rmutex.release()
    if verbose:
        print 'task', ident, 'will run for', round(delay, 1), 'sec'
    time.sleep(delay)
    if verbose:
        print 'task', ident, 'done'
    mutex.acquire()
    running = running - 1
    if running == 0:
        done.release()
    mutex.release()

next_ident = 0
def newtask():
    global next_ident, running
    mutex.acquire()
    next_ident = next_ident + 1
    if verbose:
        print 'creating task', next_ident
    thread.start_new_thread(task, (next_ident,))
    running = running + 1
    mutex.release()

for i in range(numtasks):
    newtask()

print 'waiting for all tasks to complete'
done.acquire()
print 'all tasks done'

class barrier:
    def __init__(self, n):
        self.n = n
        self.waiting = 0
        self.checkin  = thread.allocate_lock()
        self.checkout = thread.allocate_lock()
        self.checkout.acquire()

    def enter(self):
        checkin, checkout = self.checkin, self.checkout

        checkin.acquire()
        self.waiting = self.waiting + 1
        if self.waiting == self.n:
            self.waiting = self.n - 1
            checkout.release()
            return
        checkin.release()

        checkout.acquire()
        self.waiting = self.waiting - 1
        if self.waiting == 0:
            checkin.release()
            return
        checkout.release()

numtrips = 3
def task2(ident):
    global running
    for i in range(numtrips):
        if ident == 0:
            # give it a good chance to enter the next
            # barrier before the others are all out
            # of the current one
            delay = 0.001
        else:
            rmutex.acquire()
            delay = random.random() * numtasks
            rmutex.release()
        if verbose:
            print 'task', ident, 'will run for', round(delay, 1), 'sec'
        time.sleep(delay)
        if verbose:
            print 'task', ident, 'entering barrier', i
        bar.enter()
        if verbose:
            print 'task', ident, 'leaving barrier', i
    mutex.acquire()
    running = running - 1
    if running == 0:
        done.release()
    mutex.release()

print '\n*** Barrier Test ***'
if done.acquire(0):
    raise ValueError, "'done' should have remained acquired"
bar = barrier(numtasks)
running = numtasks
for i in range(numtasks):
    thread.start_new_thread(task2, (i,))
done.acquire()
print 'all tasks done'
