#! /usr/bin/python

# Program at end of class on Tuesday, 16 April
# With a couple of simplications

__author__="J Dean Brock"

import threading
import sys

def doUpdate(sharedInfo, key):
    siLock = sharedInfo['lock']
    siVals = sharedInfo['value']
    siLock.acquire()
    if (key in siVals):
        newCount = siVals[key]+1
    else:
        newCount = 1
    siVals[key] = newCount
    siLock.release()

class counter(threading.Thread):
    def __init__(self, countUp, sharedInfo):
        threading.Thread.__init__(self)
        self.countUp = countUp
        self.sharedInfo = sharedInfo
    def run(self):
        myCountDown = self.countUp-1
        while (myCountDown >= 0):
            key = 'rum' + str(myCountDown%100).zfill(2)
            doUpdate(self.sharedInfo, key)
            myCountDown = myCountDown - 1

def RunEm(numThreads):
    if numThreads>100:
        numThreads=100
    numIncs = 10000/numThreads
    print "Run with ", numThreads, " threads doing ", numIncs, " increments"
    print "  Total increments should be ", (numThreads*numIncs)
    shLock = threading.Lock()
    shVals = {}
    shInfo = {'value': shVals, 'lock': shLock}
    tList = []
    for x in range(numThreads):
        newThread = counter(numIncs, shInfo)
        newThread.start()
        tList.append(newThread)
    for t in tList:
        t.join()
    print "Value of shared variables are: "
    totalIncs = 0
    sillyList = shVals.keys()      # Trying to keep {j|p)ython both happy
    sillyList.sort()
    for key in sillyList:
        print "  ", key, "->", shVals[key]
        totalIncs = totalIncs + shVals[key]
    print "Total is ", totalIncs

if __name__ == "__main__":
    arg = 100
    if len(sys.argv) > 1:
        arg=int(sys.argv[1])
    RunEm(arg)

