private IEnumerable <ListItemData> runOnLinkedList( TestIterationParameters parameters, List <int> executorStepOrder) { Random initializationRandom = new Random(parameters.InitializationSeed); var list = new LinkedList <LinkedListItem>( Enumerable.Range(0, parameters.InitialListLength) .Select( i => new LinkedListItem( new ListItemData( i, initializationRandom.Next( listItemValueRange)), isDummy: false))); list.AddFirst(new LinkedListItem(null, true)); list.AddLast(new LinkedListItem(null, true)); List <linkedListOperationExecutor> executors = parameters.OperationSequences.Select( eParams => new linkedListOperationExecutor(eParams, list)) .ToList(); foreach (linkedListOperationExecutor executor in executors) { executor.Initialize(); } foreach (int executorIndex in executorStepOrder) { executors[executorIndex].RunSingleOperation(); } return(list .Skip(1) .SkipLast(1) .Where(value => !value.Deleted) .Select(item => item.Data) .ToList()); }
public override void Main(string[] args) { #if Verbose const bool verbose = true; #else const bool verbose = false; #endif int operationSequencesNumber = 3; const int operationNumberPerSequence = 4; const int listSize = 4; //Seed = 669052551; Random rand2 = new Random(Seed); TestIterationParameters iterationParameters = newIterationParameters( listSize, operationSequencesNumber, operationNumberPerSequence, rand2); #if Verbose Console.WriteLine("Test of LockFreeDoublyLinkedList"); Console.WriteLine("Number of executors (Threads): " + operationSequencesNumber); Console.WriteLine("Operations per executor: " + operationNumberPerSequence); Console.WriteLine("List size: " + listSize); Console.WriteLine("seed: " + Seed); Console.WriteLine("startIndex-es: " + string.Join(" \t", iterationParameters.OperationSequences.Select(eParam => eParam.StartIndex))); Console.WriteLine("operations: "); for (int i = 0; i < iterationParameters.OperationSequences.Count; i++) { ExecutionSequenceParameters executionSequenceParameters = iterationParameters.OperationSequences[i]; Console.WriteLine("\t{0}", i); foreach (IOperationResultComparer op in executionSequenceParameters.Operations) { Console.WriteLine("\t\t{0}", op); } } #endif #if SynchronizedLfdll Tuple <List <List <operationTiming> >, ILockFreeDoublyLinkedList <ListItemData> > lfdllResult = runOnLfdll(iterationParameters); #else Tuple <List <List <operationTiming> >, ILockFreeDoublyLinkedList <ListItemData> > lfdllResult = runOnLfdll(iterationParameters); #endif List <ListItemData> lfdllResultList = lfdllResult.Item2.ToList(); List <operationExecutionInfo> timings = lfdllResult.Item1 .SelectMany((opTimings, i) => opTimings.Select( opTiming => new operationExecutionInfo(opTiming, i))) .ToList(); IEqualityComparer <ListItemData> equalityComparer = LinqHelper.ToEqualityComparer( (ListItemData item1, ListItemData item2) => item1.NodeId == item2.NodeId && item1.Value == item2.Value, item => (0x51ed270b + item.GetHashCode()) * -1521134295); #if CheckCorrectness bool found = permutations(timings) .Select( permTimings => runOnLinkedList( iterationParameters, permTimings.Select(oei => oei.ExecutorIndex) .ToList())) .Any( llResult => llResult.SequenceEqual(lfdllResultList, equalityComparer) && iterationParameters.OperationSequences.All( os => os.Operations.All(o => o.LastResultsEqual))); // ReSharper disable once RedundantLogicalConditionalExpressionOperand if (verbose && found) { Console.WriteLine("Gefunden."); } #pragma warning disable 162 // Unreachable code // ReSharper disable once ConditionIsAlwaysTrueOrFalse if (verbose || !found) #pragma warning restore 162 { Console.WriteLine("Test of LockFreeDoublyLinkedList"); Console.WriteLine("Number of executors (Threads): " + operationSequencesNumber); Console.WriteLine("Operations per executor: " + operationNumberPerSequence); Console.WriteLine("List size: " + listSize); Console.WriteLine("seed: " + Seed); Random initializationRandom = new Random(iterationParameters.InitializationSeed); Console.WriteLine("initial: \t" + string.Join(" \t", Enumerable.Range(0, listSize).Select( i => new ListItemData(i, initializationRandom.Next( listItemValueRange))))); Console.WriteLine("lfdllResult: \t" + string.Join("\t", lfdllResultList.Select(o => o.ToString()))); Console.WriteLine("linked list results: \t"); var enumerationEqualityComparer = LinqHelper .ToEqualityComparer <IEnumerable <ListItemData> >( (e1, e2) => { var el1 = e1 as ListItemData[] ?? e1.ToArray(); var el2 = e2 as ListItemData[] ?? e2.ToArray(); return(el1.Length == el2.Length && el1.Zip(el2, (i1, i2) => i1.NodeId == i2.NodeId && i1.Value == i2.Value) .All(i => i)); }, e1 => e1.Aggregate( 0x51ed270b, (hash, next) => (hash + next.Value.GetHashCode()) * -1521134295)); IEnumerable <IEnumerable <ListItemData> > perms = permutations(timings) .Select( permTimings => runOnLinkedList( iterationParameters, permTimings.Select(oei => oei.ExecutorIndex) .ToList())) .Distinct(enumerationEqualityComparer); foreach (IEnumerable <ListItemData> sequentialResult in perms) { Console.WriteLine(string.Join("", sequentialResult.Select(value => " \t" + value))); } Console.WriteLine("startIndex-es: " + string.Join(" \t", iterationParameters.OperationSequences.Select(eParam => eParam.StartIndex))); Console.WriteLine("operations:"); foreach (operationExecutionInfo timing in timings) { Console.WriteLine(" " + timing.ExecutorIndex + " \t" + timing.Start + " \t" + timing.End + " \t" + timing.Operation #if RunOperationsSequentially + " \t" + timing.Operation.LastResultsEqual #endif ); } if (!found) { Console.Write("?"); Console.ReadLine(); throw new Exception(); } } #endif }
runOnLfdll(TestIterationParameters parameters) { ILockFreeDoublyLinkedList <ListItemData> lfdll = LockFreeDoublyLinkedLists.LockFreeDoublyLinkedList. Create <ListItemData>(); Random initializationRandom = new Random(parameters.InitializationSeed); foreach (int o in Enumerable.Range(0, parameters.InitialListLength)) { lfdll.PushRight( new ListItemData( o, initializationRandom.Next(listItemValueRange))); } var timer = new Counter(); List <lfdllOperationExecutor> executors = parameters.OperationSequences.Select( (operationParams, name) => new lfdllOperationExecutor(operationParams, lfdll, timer, name)).ToList(); foreach (lfdllOperationExecutor executor in executors) { executor.Initialize(); } #if SynchronizedLfdll List <AutoResetEvent> nextStepWaitHandles = executors.Select( executor => new AutoResetEvent(false)).ToList(); #endif var executorTasks = new List <Task <List <operationTiming> > >(); for (int i = 0; i < executors.Count; i++) { lfdllOperationExecutor executor = executors[i]; #if SynchronizedLfdll AutoResetEvent nextStepWaitHandle = nextStepWaitHandles[i]; #endif Task <List <operationTiming> > task = new Task <List <operationTiming> >( () => { List <operationTiming> timings; #if HandleTaskExceptionImmediately try { #endif #if SynchronizedLfdll lfdll.NextStepWaitHandle.Value = nextStepWaitHandle; #endif timings = executor.Run(); #if SynchronizedLfdll lfdll.NextStepWaitHandle.Value.WaitOne(); nextStepWaitHandles.Remove( lfdll.NextStepWaitHandle.Value); lfdll.StepCompletedWaitHandle.Set(); #endif #if HandleTaskExceptionImmediately } catch (Exception e) { Console.WriteLine(e.StackTrace); Console.WriteLine("Exception in Thread " + Thread.CurrentThread.Name); throw; } #endif return(timings); }); executorTasks.Add(task); } foreach (Task <List <operationTiming> > task in executorTasks) { #if RunOperationsSequentially task.RunSynchronously(); #else task.Start(); #endif } Random executionRandom = new Random(parameters.ExecutionSeed); #if SynchronizedLfdll_verbose List <int> handleIndexes = new List <int>(); #endif #if SynchronizedLfdll while (true) { if (nextStepWaitHandles.Count == 0) { break; } int nextHandleIndex = executionRandom.Next(nextStepWaitHandles.Count); #if SynchronizedLfdll_verbose handleIndexes.Add(nextHandleIndex); #endif AutoResetEvent nextHandle = nextStepWaitHandles[nextHandleIndex]; nextHandle.Set(); lfdll.StepCompletedWaitHandle.WaitOne(); } #endif // ReSharper disable once CoVariantArrayConversion Task.WaitAll(executorTasks.ToArray()); #if SynchronizedLfdll_verbose Console.WriteLine(string.Join(" ", handleIndexes)); #endif return(new Tuple <List <List <operationTiming> >, ILockFreeDoublyLinkedList <ListItemData> >( executorTasks.Select(t => t.Result).ToList(), lfdll)); }