home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / test / source / TestSynchronization.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  3.0 KB  |  168 lines

  1. #include <vd2/system/atomic.h>
  2. #include <vd2/system/thread.h>
  3. #include <vd2/system/vdalloc.h>
  4. #include "test.h"
  5.  
  6. class ThreadLog {
  7. public:
  8.     typedef int value_type;
  9.     typedef const value_type *const_iterator;
  10.  
  11.     enum { N = 1000000 };
  12.  
  13.     ThreadLog();
  14.  
  15.     const_iterator begin() const { return mLog; }
  16.     const_iterator end() const { int n = mPos; return mLog + (n > N ? N : n); }
  17.  
  18.     void Add(int code);
  19.  
  20. protected:
  21.     VDAtomicInt mPos;
  22.     int mLog[N];
  23. };
  24.  
  25. ThreadLog::ThreadLog()
  26.     : mPos(0)
  27. {
  28.     memset(mLog, 0, sizeof mLog);
  29. }
  30.  
  31. void ThreadLog::Add(int code) {
  32.     int pos = mPos++;
  33.  
  34.     if (pos < N)
  35.         mLog[pos] = code;
  36. }
  37.  
  38. ///////////////////////////////////////////////////////////////////////////////
  39.  
  40. class SemaphoreTestThread : public VDThread {
  41. public:
  42.     void Init(ThreadLog *log, VDSemaphore *sema, int mode);
  43.  
  44.     void ThreadRun();
  45.  
  46. protected:
  47.     ThreadLog *mpLog;
  48.     VDSemaphore *mpSema;
  49.     int mMode;
  50. };
  51.  
  52. void SemaphoreTestThread::Init(ThreadLog *log, VDSemaphore *sema, int mode) {
  53.     mpLog = log;
  54.     mpSema = sema;
  55.     mMode = mode;
  56. }
  57.  
  58. void SemaphoreTestThread::ThreadRun() {
  59.     switch(mMode) {
  60.     case 0:
  61.         for(int i=0; i<10000; ++i) {
  62.             mpLog->Add(+1);
  63.             mpSema->Post();
  64.  
  65.             for(int j=rand() & 1023; j; --j)
  66.                 volatile int k = 1/j;
  67.         }
  68.         break;
  69.  
  70.     case 1:
  71.         for(int i=0; i<10000; ++i) {
  72.             mpSema->Wait();
  73.             mpLog->Add(-1);
  74.  
  75.             for(int j=rand() & 1023; j; --j)
  76.                 volatile int k = 1/j;
  77.         }
  78.         break;
  79.  
  80.     case 2:
  81.         for(int i=0; i<10000; ++i) {
  82.             while(!mpSema->TryWait())
  83.                 VDThreadSleep(1);
  84.  
  85.             mpLog->Add(-1);
  86.  
  87.             for(int j=rand() & 1023; j; --j)
  88.                 volatile int k = 1/j;
  89.         }
  90.         break;
  91.  
  92.     case 3:
  93.         for(int i=0; i<10000; ++i) {
  94.             while(!mpSema->Wait(1))
  95.                 ;
  96.  
  97.             mpLog->Add(-1);
  98.  
  99.             for(int j=rand() & 1023; j; --j)
  100.                 volatile int k = 1/j;
  101.         }
  102.         break;
  103.     }
  104. }
  105.  
  106. static bool RunSemaphoreTest() {
  107.     for(int phase=0; phase<3; ++phase) {
  108.         SemaphoreTestThread threads[100];
  109.         VDSemaphore sema(0);
  110.         vdautoptr<ThreadLog> log(new ThreadLog);
  111.  
  112.  
  113.         switch(phase) {
  114.             case 0:
  115.                 for(int i=0; i<100; ++i) {
  116.                     threads[i].Init(log, &sema, (i&1) != 0);
  117.                 }
  118.                 break;
  119.  
  120.             case 1:
  121.                 for(int i=0; i<100; ++i) {
  122.                     threads[i].Init(log, &sema, (i&1) ? 2 : 0);
  123.                 }
  124.                 break;
  125.  
  126.             case 2:
  127.                 for(int i=0; i<100; ++i) {
  128.                     threads[i].Init(log, &sema, (i&1) ? 3 : 0);
  129.                 }
  130.                 break;
  131.         }
  132.  
  133.         for(int i=0; i<100; ++i)
  134.             threads[i].ThreadStart();
  135.  
  136.         for(int i=0; i<100; ++i)
  137.             threads[i].ThreadWait();
  138.  
  139.         ThreadLog::const_iterator it(log->begin()), itEnd(log->end());
  140.         int count = 0;
  141.         for(; it!=itEnd; ++it) {
  142.             int code = *it;
  143.  
  144.             count += code;
  145.             if (count < 0) {
  146.                 printf("Semaphore inconsistency detected.\n");
  147.                 return false;
  148.             }
  149.         }
  150.  
  151.         if (count) {
  152.             printf("Semaphore inconsistency detected.\n");
  153.             return false;
  154.         }
  155.     }
  156.  
  157.     return true;
  158. }
  159.  
  160. ///////////////////////////////////////////////////////////////////////////////
  161.  
  162. DEFINE_TEST(Synchronization) {
  163.     if (!RunSemaphoreTest())
  164.         return false;
  165.  
  166.     return true;
  167. }
  168.