예제 #1
0
        def t2():
            t1launched.wait()

            # This thread does the committing after t1 started but before it reads the value of refA
            self.d("** Creating ref")
            self.refA = Ref(5, None)
            self.refA.refSet(6)
예제 #2
0
    def testBarge(self):
        # Barging happens when one transaction tries to do an in-transaction-write to a ref that has
        # an in-transaction-value from another transaction
        t1wait = Event()
        t2wait = Event()

        self.t1counter = 0
        self.t2counter = 0
        
        def t1():
            # We do the first in-transaction-write
            self.refA.refSet(888)

            # Don't commit yet, we want t2 to run and barge us
            self.d("* Notify")
            t2wait.set()
            self.d("* Wait")
            t1wait.wait()
            self.d("* Done")

            self.t1counter += 1

        def t2():
            # Wait till t1 has done its write
            self.d("** Wait")
            t2wait.wait()

            # Try to write to the ref
            # We should try and succeed to barge them: we were started first
            # and should be long-lived enough
            self.d("** Before barge")
            self.refA.refSet(777)

            self.d("** After barge")
            sleep(.1)
            t1wait.set()

            self.t2counter += 1
            
        self.refA = Ref(999, None)
        th1 = self.runTransactionInThread(t1, autostart=False)
        th2 = self.runTransactionInThread(t2, autostart=False)

        # Start thread 1 first, give the GIL a cycle so it waits for t2wait
        th2.start()
        sleep(.1)
        th1.start()

        # Wait for the test to finish
        self.join_all()

        # T2 should have successfully barged T1, so T1 should have been re-run
        # The final value of the ref should be 888, as T1 ran last
        self.assertEqual(self.t1counter, 2)
        self.assertEqual(self.t2counter, 1)
        self.assertEqual(self.refA.deref(), 888)

        self.d("Final value of ref: %s and t1 ran %s times" % (self.refA.deref(), self.t1counter))
예제 #3
0
    def testCommutes(self):
        # Make sure multiple transactions that occur simultaneously each commute the same ref
        # Hard to check for this behaving properly---it should have fewer retries than if each 
        # transaction did an alter, but if transactions commit at the same time one might have to retry
        # anyway. The difference is usually an order of magnitude, so this test is pretty safe

        self.numruns = AtomicInteger()
        self.numalterruns = AtomicInteger()
        numthreads = 20

        def incr(curval):
            return curval + 1

        def adder(curval, extraval):
            return curval + extraval

        def t1():
            self.numruns.getAndIncrement()
            self.refA.commute(incr, [])

        def t2():
            # self.d("Thread %s (%s): ALTER BEING RUN, total retry num: %s" % (current_thread().ident, id(current_thread()), self.numalterruns.getAndIncrement()))
            self.numalterruns.getAndIncrement()
            self.refB.alter(adder, [100])

        self.refA = Ref(0, None)
        self.refB = Ref(0, None)
        for i in range(numthreads):
            self.runTransactionInThread(t1)

        self.join_all()

        for i in range(numthreads):
            self.runTransactionInThread(t2)

        self.join_all()

        self.d("Commute took %s runs and counter is %s" % (self.numruns.get(), self.refA.deref()))
        self.d("Alter took %s runs and counter is %s" % (self.numalterruns.get(), self.refB.deref()))

        self.assertEqual(self.refA.deref(), numthreads)
        self.assertEqual(self.refB.deref(), 2000)
        self.assertTrue(self.numalterruns.get() >= self.numruns.get())
예제 #4
0
    def testSimpleConcurrency(self):
        def t1():
            sleep(.1)
            self.ref0.refSet(1)
        def t2():
            self.ref0.refSet(2)

        # Delaying t1 means it should commit after t2
        self.ref0 = Ref(0, None)
        self.runTransactionInThread(t1)
        self.runTransactionInThread(t2)
        self.join_all()
        self.assertEqual(self.ref0.deref(), 1)
예제 #5
0
    def testRun_PASS(self):
        # Now we'll run a transaction ourselves
        self.refOne = Ref(111, None)
        self.refTwo = Ref(222, None)

        # Our transaction body will do a ref-set and an alter (increment a ref by 1)
        def body():
            # Body of the transaction!
            self.refZero.refSet(999)

            def incr(val):
                return val + 1

            self.refOne.alter(incr, [])

        # Test our transaction actually made the changes it should have
        LockingTransaction.runInTransaction(body)
        self.assertEqual(self.refZero.deref(), 999)
        self.assertEqual(self.refOne.deref(), 112)
        self.assertEqual(self.refTwo.deref(), 222)

        # Test that the transaction ended properly
        self.assertRaises(IllegalStateException, self.refZero.refSet, 999)
예제 #6
0
 def setUp(self):
     self.refZero = Ref(0, None)
     self.refOne = Ref(pv.vec(range(10)), None)
예제 #7
0
 def setUp(self):
     self.refZero = Ref(0, None)