                 print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ leave async {} -- postBarrierStage")
             }
 
-            print("testBarrierWithSemaphore() @ \(#line)")
+            print("testBarrierWithSemaphore() @ \(#line) -- leaving function")
         }
 
         print("testAsyncBarrierFunction() @ \(#line): v enter main test loop (will execute \(IterationsOfBarrierTest) times)")

            print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): creating semaphore")

            let semaphore = NSCondition()

            print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): v testBarrierWithSemaphore()")
            testBarrierWithSemaphore(semaphore)
            print("testAsyncBarrierFunction() @ \(#line) (\(i+1)/\(IterationsOfBarrierTest)): ^ testBarrierWithSemaphore()")

            let waitingFor = IterationsPerBarrierStage * 3  // because there are 3 test stages

    {
        print("testAsyncBarrierFunction() @ \(#line) -- entering function")

        var startAsyncWork = false
        var preBarrierStageCompleted = 0
        var inBarrierStageCompleted = 0
        var postBarrierStageCompleted = 0

        func testBarrier(with semaphore: NSCondition, startingGun: NSCondition)
        {
            XCTAssertTrue(NSThread.isMainThread())  // we expect tests to run on the main thread

            print("testBarrierWithSemaphore() @ \(#line) -- entering function")

            for i in 0..<IterationsPerBarrierStage {
                print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v enter async {} -- preBarrierStage")

                async {
                    XCTAssertTrue(!NSThread.isMainThread())

                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.lock() -- preBarrierStage")
                    startingGun.lock()
                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.lock() -- preBarrierStage")
                    while !startAsyncWork {
                        print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.wait() -- preBarrierStage")
                        startingGun.wait()
                        print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.wait() -- preBarrierStage")
                    }
                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v startingGun.unlock() -- preBarrierStage")
                    startingGun.unlock()
                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): ^ startingGun.unlock() -- preBarrierStage")

                    print("testBarrierWithSemaphore() @ \(#line) (\(i+1)/\(self.IterationsPerBarrierStage)): v semaphore.lock() -- preBarrierStage")
                    semaphore.lock()
