1 module ut.concurrency.slist; 2 3 import concurrency.slist; 4 import concurrency.sender; 5 import concurrency.operations.whenall; 6 import concurrency.operations.then; 7 import concurrency.operations.via; 8 import concurrency.thread : ThreadSender; 9 import concurrency : syncWait; 10 import std.range : walkLength; 11 import unit_threaded; 12 13 @("pushFront.race") 14 @safe unittest { 15 auto list = new shared SList!int; 16 17 auto filler = just(list).then((shared SList!int list) @safe shared { 18 foreach(i; 0..100) { 19 list.pushFront(i); 20 } 21 }).via(ThreadSender()); 22 23 whenAll(filler, filler).syncWait(); 24 25 list[].walkLength.should == 200; 26 } 27 28 @("pushBack.race") 29 @safe unittest { 30 auto list = new shared SList!int; 31 32 auto filler = just(list).then((shared SList!int list) @safe shared { 33 foreach(i; 0..100) { 34 list.pushBack(i); 35 } 36 }).via(ThreadSender()); 37 38 whenAll(filler, filler).syncWait(); 39 40 list[].walkLength.should == 200; 41 } 42 43 @("pushFront.adversary") 44 @safe unittest { 45 auto list = new shared SList!int; 46 47 foreach(i; 0..50) 48 list.pushFront(1); 49 50 auto filler = just(list).then((shared SList!int list) @safe shared { 51 foreach(i; 0..50) { 52 list.pushFront(1); 53 } 54 }).via(ThreadSender()); 55 auto remover = just(list).then((shared SList!int list) @safe shared { 56 foreach(i; 0..50) { 57 list.remove(1); 58 } 59 }).via(ThreadSender()); 60 61 whenAll(filler, remover).syncWait(); 62 63 list[].walkLength.should == 50; 64 } 65 66 @("pushBack.adversary") 67 @safe unittest { 68 auto list = new shared SList!int; 69 70 auto filler = just(list).then((shared SList!int list) @safe shared { 71 foreach(i; 0..100) { 72 list.pushBack(1); 73 } 74 }).via(ThreadSender()); 75 auto remover = just(list).then((shared SList!int list) @safe shared { 76 int n = 0; 77 while(n < 99) 78 if (list.remove(1)) 79 n++; 80 }).via(ThreadSender()); 81 82 whenAll(filler, remover).syncWait(); 83 84 list[].walkLength.should == 1; 85 } 86 87 @("remove.race") 88 @safe unittest { 89 auto list = new shared SList!int; 90 91 foreach(i; 0..100) 92 list.pushFront(i); 93 94 auto remover = just(list).then((shared SList!int list) @safe shared { 95 foreach(i; 0..100) { 96 if (i % 10 > 4) 97 list.remove(i); 98 } 99 }).via(ThreadSender()); 100 101 whenAll(remover, remover).syncWait(); 102 103 list[].walkLength.should == 50; 104 } 105 106 @("remove.adjacent") 107 @safe unittest { 108 auto list = new shared SList!int; 109 110 foreach(_; 0..2) 111 foreach(i; 0..100) 112 list.pushFront(i); 113 114 auto remover1 = just(list).then((shared SList!int list) @safe shared { 115 foreach(i; 0..100) { 116 if (i % 2 == 0) 117 list.remove(i); 118 } 119 }).via(ThreadSender()); 120 auto remover2 = just(list).then((shared SList!int list) @safe shared { 121 foreach(i; 0..100) { 122 if (i % 2 == 1) 123 list.remove(i); 124 } 125 }).via(ThreadSender()); 126 127 whenAll(remover1, remover2, remover1, remover2).syncWait(); 128 129 list[].walkLength.should == 0; 130 }