Exemple #1
0
        // This test is for the case where two different clusters are racing,
        // trying to activate the same grain.

        // This function takes two arguments, a list of client configurations, and an integer. The list of client configurations is used to
        // create multiple clients that concurrently call the grains in range [0, numGrains). We run the experiment in a series of barriers.
        // The clients all invoke grain "g", in parallel, and then wait on a signal by the main thread (this function). The main thread, then
        // wakes up the clients, after which they invoke "g+1", and so on.

        private Task CreationRace()
        {
            WriteLog("Starting ConcurrentCreation");

            var offset = random.Next();

            // take inventory now so we can exclude pre-existing entries from the validation
            var baseline = GetGrainActivations();

            // We use two objects to coordinate client threads and the main thread. coordWakeup is an object that is used to signal the coordinator
            // thread. toWait is used to signal client threads.
            var coordWakeup = new object();
            var toWait      = new object();

            // We keep a list of client threads.
            var clientThreads = new List <Tuple <Thread, ClientThreadArgs> >();
            var rand          = new Random();
            var results       = new List <Tuple <int, int> > [clients.Length];

            threadsDone = results.Length;

            int index = 0;

            // Create a client thread corresponding to each client
            // The client thread will execute ThreadFunc function.
            foreach (var client in clients)
            {
                // A client thread takes a list of tupes<int, int> as argument. The list is an ordered sequence of grains to invoke. tuple.item2
                // is the grainId. tuple.item1 is never used (this should probably be cleaned up, but I don't want to break anything :).
                var args = new List <Tuple <int, int> >();
                for (int j = 0; j < numGrains; ++j)
                {
                    var waitTime = rand.Next(16, 100);
                    args.Add(Tuple.Create(waitTime, j));
                }

                // Given a config file, create client starts a client in a new appdomain. We also create a thread on which the client will run.
                // The thread takes a "ClientThreadArgs" as argument.
                var thread         = new Thread(ThreadFunc);
                var threadFuncArgs = new ClientThreadArgs
                {
                    client      = client,
                    args        = args,
                    resultIndex = index,
                    numThreads  = clients.Length,
                    coordWakeup = coordWakeup,
                    toWait      = toWait,
                    results     = results,
                    offset      = offset
                };
                clientThreads.Add(Tuple.Create(thread, threadFuncArgs));
                index += 1;
            }

            // Go through the list of client threads, and start each of the threads with the appropriate arguments.
            foreach (var threadNArg in clientThreads)
            {
                var thread = threadNArg.Item1;
                var arg    = threadNArg.Item2;

                thread.Start(arg);
            }

            // We run numGrains iterations of the experiment. The coordinator thread calls the function "WaitForWorkers" in order to wait
            // for the client threads to finish concurrent calls to a single grain.
            for (int i = 0; i < numGrains; ++i)
            {
                WaitForWorkers(clients.Length, coordWakeup, toWait);
            }

            // Once the clients threads have finished calling the grain the appropriate number of times, we wait for them to write out their results.
            foreach (var threadNArg in clientThreads)
            {
                var thread = threadNArg.Item1;
                thread.Join();
            }

            var grains = GetGrainActivations(baseline);

            ValidateClusterRaceResults(results, grains);

            return(TaskDone.Done);
        }
        // This test is for the case where two different clusters are racing, 
        // trying to activate the same grain.   

        // This function takes two arguments, a list of client configurations, and an integer. The list of client configurations is used to
        // create multiple clients that concurrently call the grains in range [0, numGrains). We run the experiment in a series of barriers.
        // The clients all invoke grain "g", in parallel, and then wait on a signal by the main thread (this function). The main thread, then 
        // wakes up the clients, after which they invoke "g+1", and so on.

        private Task CreationRace()
        {
            WriteLog("Starting ConcurrentCreation");

            var offset = random.Next();

            // take inventory now so we can exclude pre-existing entries from the validation
            var baseline = GetGrainActivations();

            // We use two objects to coordinate client threads and the main thread. coordWakeup is an object that is used to signal the coordinator
            // thread. toWait is used to signal client threads.
            var coordWakeup = new object();
            var toWait = new object();

            // We keep a list of client threads.
            var clientThreads = new List<Tuple<Thread, ClientThreadArgs>>();
            var rand = new Random();
            var results = new List<Tuple<int, int>>[clients.Length];
            threadsDone = results.Length;

            int index = 0;

            // Create a client thread corresponding to each client
            // The client thread will execute ThreadFunc function.
            foreach (var client in clients)
            {
                // A client thread takes a list of tupes<int, int> as argument. The list is an ordered sequence of grains to invoke. tuple.item2
                // is the grainId. tuple.item1 is never used (this should probably be cleaned up, but I don't want to break anything :).
                var args = new List<Tuple<int, int>>();
                for (int j = 0; j < numGrains; ++j)
                {
                    var waitTime = rand.Next(16, 100);
                    args.Add(Tuple.Create(waitTime, j));
                }

                // Given a config file, create client starts a client in a new appdomain. We also create a thread on which the client will run.
                // The thread takes a "ClientThreadArgs" as argument.
                var thread = new Thread(ThreadFunc);
                var threadFuncArgs = new ClientThreadArgs
                {
                    client = client,
                    args = args,
                    resultIndex = index,
                    numThreads = clients.Length,
                    coordWakeup = coordWakeup,
                    toWait = toWait,
                    results = results,
                    offset = offset
                };
                clientThreads.Add(Tuple.Create(thread, threadFuncArgs));
                index += 1;
            }

            // Go through the list of client threads, and start each of the threads with the appropriate arguments.
            foreach (var threadNArg in clientThreads)
            {
                var thread = threadNArg.Item1;
                var arg = threadNArg.Item2;

                thread.Start(arg);
            }

            // We run numGrains iterations of the experiment. The coordinator thread calls the function "WaitForWorkers" in order to wait
            // for the client threads to finish concurrent calls to a single grain. 
            for (int i = 0; i < numGrains; ++i)
            {
                WaitForWorkers(clients.Length, coordWakeup, toWait);
            }

            // Once the clients threads have finished calling the grain the appropriate number of times, we wait for them to write out their results.
            foreach (var threadNArg in clientThreads)
            {
                var thread = threadNArg.Item1;
                thread.Join();
            }

            var grains = GetGrainActivations(baseline);

            ValidateClusterRaceResults(results, grains);

            return TaskDone.Done;
        }