Salome HOME
copy tag mergefrom_BR_V0_1_CC_Salome_04oct07
[modules/yacs.git] / src / bases / Test / basesTest.cxx
1
2 #include "basesTest.hxx"
3
4 #include <iostream>
5 #include <sstream>
6
7 using namespace YACS::BASES;
8 using namespace YACS;
9 using namespace std;
10
11 //#define _DEVDEBUG_
12 #include "YacsTrace.hxx"
13     
14 Mutex BasesTest::_m;
15 Semaphore BasesTest::_s1;
16 Semaphore BasesTest::_s2;
17 Condition BasesTest::_cond;
18 ostringstream BasesTest::_glob;
19 int BasesTest::_var=7;
20
21 const int BasesTest::THREAD_NUM=5;
22
23 const int BasesTest::LOOPS=4;
24
25 const int BasesTest::MAX_RESOURCE=7;
26
27 int BasesTest::_value=0;
28 int BasesTest::_waiting=0;
29 int BasesTest::_resources=BasesTest::MAX_RESOURCE;
30 int BasesTest::_ownedResources[THREAD_NUM];
31
32 void *BasesTest::th1_1(void *st)
33 {
34   char myName=*((char *) st);
35   _s1.wait();
36   _glob<< myName << _var;
37   _var+=2;
38   _s1.post();
39   _s2.post();
40 }
41
42 void *BasesTest::th1_2(void *st)
43 {
44   char myName=*((char *) st);
45   _s2.wait();
46   _glob<< myName << _var;
47   _s2.post();
48 }
49
50 void *BasesTest::th1_3(void *st)
51 {
52   char myName=*((char *) st);
53   _glob<< myName << _var++;
54   _s1.post();
55 }
56
57 void *BasesTest::th2_1(void *)
58 {
59   int i, tmp;
60   int rc = 0;      
61   for (i=0; i<LOOPS; ++i)
62     {
63       _m.lock();
64       tmp = _value;
65       tmp = tmp+1;
66       Thread::sleep(1000);
67       _value = tmp;
68       _m.unlock();
69       Thread::sleep(100000);
70     }
71 }
72
73 void *BasesTest::myFunc(void *n)
74 {
75   int id = *((int*) n);
76
77   for (int i=3; i>0; i--)
78     {
79       DEBTRACE("thread " << id << " asks for " << i << " resources");
80       get_resources(id, i);
81       DEBTRACE("thread " << id << " has got " << i << " resources");
82       CPPUNIT_ASSERT(count_resources() == BasesTest::MAX_RESOURCE);
83       Thread::sleep(10000);
84       CPPUNIT_ASSERT(count_resources() == BasesTest::MAX_RESOURCE);
85       DEBTRACE("thread " << id << " frees " << i << " resources");
86       free_resources(id, i);
87     }
88 }
89
90 void BasesTest::get_resources(int id, int amount)
91 {
92   _m.lock();
93   while (_resources < amount)
94     {
95       _waiting++;
96       _cond.wait(_m); // _m is unlocked during the wait
97     }
98   _resources -= amount;
99   _ownedResources[id] = amount;
100   _m.unlock(); 
101 }
102
103 void BasesTest::free_resources(int id, int amount)
104 {
105   _m.lock();
106   _resources += amount;
107   _ownedResources[id] = 0;
108   if (_waiting > 0)
109     {
110       _waiting = 0;
111       _cond.notify_all();
112     }
113   _m.unlock();
114 }
115
116 int BasesTest::count_resources()
117 {
118   int resources = 0;
119   int totOwned = 0;
120   {
121     _m.lock();
122     resources = _resources;
123     for (int i=0; i<THREAD_NUM; i++)
124       {
125         totOwned += _ownedResources[i];
126       }
127     _m.unlock();
128   }
129   int total = resources + totOwned;
130   DEBTRACE("resources:: owned by threads: " << totOwned << " remaining: " << resources << " total: " << total);
131   return total;
132 }
133
134 void BasesTest::setUp()
135 {
136 }
137
138 void BasesTest::tearDown()
139 {
140 }
141
142
143 void BasesTest::test1()
144 {
145   char t1Name='A'; char t2Name='B'; char t3Name='C';
146   Thread t1(th1_1,&t1Name);
147   Thread t2(th1_2,&t2Name);
148   Thread t3(th1_3,&t3Name);
149   t1.join();
150   t2.join();
151   t3.join();
152   CPPUNIT_ASSERT( _glob.str() == "C7A8B10" );
153 }
154
155 void BasesTest::test2()
156 {
157   int i;
158   Thread **ths=new Thread *[THREAD_NUM];
159   for (i=0; i<THREAD_NUM; ++i)
160     {
161       ths[i]=new Thread(th2_1,0);
162     }
163   for (i=0; i<THREAD_NUM; ++i)
164     {
165       ths[i]->join();
166       delete ths[i];
167     }
168   delete [] ths;
169   CPPUNIT_ASSERT( _value == THREAD_NUM*LOOPS );
170 }
171
172 void BasesTest::test3()
173 {
174   int i;
175   void *ret;
176   Thread **ths=new Thread *[THREAD_NUM];
177
178   int id[THREAD_NUM];
179   for (i=0; i<THREAD_NUM; i++)
180     {
181       id[i] = i;
182       _ownedResources[i] = 0;
183     }
184   
185   for (i=0; i<THREAD_NUM; i++)
186     {
187       ths[i] = new Thread(myFunc, &id[i]);
188       CPPUNIT_ASSERT(count_resources() == BasesTest::MAX_RESOURCE);
189     }
190
191   for (i=0; i<THREAD_NUM; i++)
192     {
193       ths[i]->join();
194       delete ths[i];
195       DEBTRACE("thread " << id[i] << " is finished");
196       CPPUNIT_ASSERT(count_resources() == BasesTest::MAX_RESOURCE);
197     }
198 }
199
200 typedef double (*FctPt)(double);
201
202 void BasesTest::testDL()
203 {
204   DynLibLoader *loader=new DynLibLoader(".libs/libYACSDLTest");
205   void *symb=loader->getHandleOnSymbolWithName("myYacsFct");
206   FctPt f=(FctPt) symb;
207   double res=f(1.7);
208   CPPUNIT_ASSERT_DOUBLES_EQUAL( 20.23, res, 1e-13);
209   res=f(2.3);
210   CPPUNIT_ASSERT_DOUBLES_EQUAL( 37.03, res, 1e-13);
211   delete loader;
212 }