| [c51124b] | 1 | #include <fstream.hfa>
 | 
|---|
 | 2 | #include <locks.hfa>
 | 
|---|
 | 3 | #include <thread.hfa>
 | 
|---|
 | 4 | 
 | 
|---|
 | 5 | enum { num_blockers = 17, num_unblockers = 13 };
 | 
|---|
 | 6 | 
 | 
|---|
 | 7 | void thrash() {
 | 
|---|
 | 8 |         unsigned t[100];
 | 
|---|
 | 9 |         for(i; 100) {
 | 
|---|
 | 10 |                 t[i] = 0xDEADBEEF;
 | 
|---|
 | 11 |         }
 | 
|---|
 | 12 | }
 | 
|---|
 | 13 | 
 | 
|---|
 | 14 | Semaphore0nary sem;
 | 
|---|
 | 15 | 
 | 
|---|
 | 16 | const unsigned int num_blocks = 1625;
 | 
|---|
 | 17 | 
 | 
|---|
 | 18 | thread Blocker {
 | 
|---|
 | 19 |         size_t sum;
 | 
|---|
 | 20 | };
 | 
|---|
 | 21 | void main(Blocker & this);
 | 
|---|
 | 22 | 
 | 
|---|
| [8f1a99e] | 23 | Blocker * from_thread(thread$ * t) {
 | 
|---|
| [c51124b] | 24 |         Blocker & nullb = *(Blocker*)0p;
 | 
|---|
| [8f1a99e] | 25 |         thread$ & nullt = (thread&)nullb;
 | 
|---|
| [c51124b] | 26 |         uintptr_t offset  = (uintptr_t)&nullt;
 | 
|---|
 | 27 |         uintptr_t address = ((uintptr_t)t) - offset;
 | 
|---|
 | 28 |         return (Blocker*)address;
 | 
|---|
 | 29 | }
 | 
|---|
 | 30 | 
 | 
|---|
 | 31 | void main(Blocker & this) {
 | 
|---|
| [8f1a99e] | 32 |         thread$ * me = active_thread();
 | 
|---|
| [c51124b] | 33 |         Blocker * me1 = &this;
 | 
|---|
 | 34 |         Blocker * me2 = from_thread(me);
 | 
|---|
 | 35 |         if( me1 != me2 ) sout | "Bad casting!" | me1 | "vs" | me2;
 | 
|---|
 | 36 |         this.sum = 0;
 | 
|---|
 | 37 |         for(num_blocks) {
 | 
|---|
 | 38 |                 P(sem);
 | 
|---|
 | 39 |                 if(((thread&)this).seqable.next != 0p) sout | "Link not invalidated";
 | 
|---|
 | 40 |         }
 | 
|---|
 | 41 | }
 | 
|---|
 | 42 | 
 | 
|---|
 | 43 | const unsigned int num_unblocks = 2125;
 | 
|---|
 | 44 | 
 | 
|---|
 | 45 | thread Unblocker {
 | 
|---|
 | 46 |         size_t sum;
 | 
|---|
 | 47 | };
 | 
|---|
 | 48 | 
 | 
|---|
 | 49 | void main(Unblocker & this) {
 | 
|---|
 | 50 |         this.sum = 0;
 | 
|---|
| [84cd72d] | 51 |         unsigned me = (unsigned)(uintptr_t)&this;
 | 
|---|
| [c51124b] | 52 |         for(num_unblocks) {
 | 
|---|
| [8f1a99e] | 53 |                 thread$ * t = V(sem, false);
 | 
|---|
| [c51124b] | 54 |                 Blocker * b = from_thread(t);
 | 
|---|
 | 55 |                 b->sum += me;
 | 
|---|
| [84cd72d] | 56 |                 this.sum += (unsigned)(uintptr_t)b;
 | 
|---|
| [c51124b] | 57 |                 unpark(t);
 | 
|---|
 | 58 |                 yield(random(10));
 | 
|---|
 | 59 |         }
 | 
|---|
 | 60 | }
 | 
|---|
 | 61 | 
 | 
|---|
 | 62 | int main() {
 | 
|---|
 | 63 |         size_t usum = 0;
 | 
|---|
 | 64 |         size_t bsum = 0;
 | 
|---|
 | 65 | 
 | 
|---|
 | 66 |         if((num_unblocks * num_unblockers) != (num_blocks * num_blockers)) sout | "Mismatched Operations: " | (num_unblocks * num_unblockers) | "vs" | (num_blocks * num_blockers);
 | 
|---|
 | 67 | 
 | 
|---|
 | 68 |         sout | "Starting";
 | 
|---|
 | 69 |         {
 | 
|---|
 | 70 |                 Blocker   blockers  [num_blockers  ];
 | 
|---|
 | 71 |                 Unblocker unblockers[num_unblockers];
 | 
|---|
 | 72 | 
 | 
|---|
 | 73 |                 for(i;num_blockers) {
 | 
|---|
 | 74 |                         for(num_blocks)
 | 
|---|
| [84cd72d] | 75 |                                 usum += (unsigned)(uintptr_t)&blockers[i];
 | 
|---|
| [c51124b] | 76 |                 }
 | 
|---|
 | 77 | 
 | 
|---|
 | 78 |                 for(i;num_unblockers) {
 | 
|---|
 | 79 |                         for(num_unblocks)
 | 
|---|
| [84cd72d] | 80 |                                 bsum += (unsigned)(uintptr_t)&unblockers[i];
 | 
|---|
| [c51124b] | 81 |                 }
 | 
|---|
 | 82 | 
 | 
|---|
 | 83 |                 for(i;num_blockers) {
 | 
|---|
 | 84 |                         bsum -= join(blockers[i]).sum;
 | 
|---|
 | 85 |                 }
 | 
|---|
 | 86 | 
 | 
|---|
 | 87 |                 for(i;num_unblockers) {
 | 
|---|
 | 88 |                         usum -= join(unblockers[i]).sum;
 | 
|---|
 | 89 |                 }
 | 
|---|
 | 90 |         }
 | 
|---|
 | 91 |         sout | "Done!";
 | 
|---|
 | 92 |         if(bsum == 0 && usum == 0) sout | "Match!";
 | 
|---|
 | 93 |         else sout | "No Match!" | usum | "/" | bsum;
 | 
|---|
 | 94 | }
 | 
|---|