001/****************************************************************************
002 * Copyright/Copyleft:
003 *
004 * For this source the LGPL Lesser General Public License,
005 * published by the Free Software Foundation is valid.
006 * It means:
007 * 1) You can use this source without any restriction for any desired purpose.
008 * 2) You can redistribute copies of this source to everybody.
009 * 3) Every user of this source, also the user of redistribute copies
010 *    with or without payment, must accept this license for further using.
011 * 4) But the LPGL is not appropriate for a whole software product,
012 *    if this source is only a part of them. It means, the user
013 *    must publish this part of source,
014 *    but don't need to publish the whole source of the own product.
015 * 5) You can study and modify (improve) this source
016 *    for own using or for redistribution, but you have to license the
017 *    modified sources likewise under this LGPL Lesser General Public License.
018 *    You mustn't delete this Copyright/Copyleft inscription in this source file.
019 *
020 * @author Hartmut Schorrig: hartmut.schorrig@vishia.de, www.vishia.org
021 * @version 0.93 2011-01-05  (year-month-day)
022 *******************************************************************************/ 
023package org.vishia.java2C.test;
024
025/**This class demonstrates and tests the usage of threads with the synchronized access to data (mutex). 
026 * It implements the run()-Method of the Thread defined in the interface Runnable. 
027 * <br><br>
028 * The threads private data which should be able to access only by the current thread are stored
029 * in an extra class, here defined as static inner class.
030 *
031 */
032public class TestThread implements Runnable
033{
034  
035  /**This is a central thread-control variable. If it is set to true, if the thread is started. */
036  private boolean threadRunning;
037  
038  /**This is a central thread-control variable. If it is set to false, if the thread is finished. */
039  private boolean threadFinished;
040  
041  /**Two test counter, they will be count always simultaneously. Therefore a <code>synchronized</code>
042   * is used. The data of an instance of this class, especially this counters are visible from outside the thread.
043   * Because there are private, an access to it is only possible in this class. But the method which is accessing
044   * may be called from another thread. Therefore a mutex-access is necessary, 
045   * see {@link #testSynchronized(org.vishia.java2C.test.TestThread.TestThreadLocalData)}
046   * and {@link #otherThreadRoutine()}.
047   * 
048   */
049  private int testCt1 = 0, testCt2 = 0;
050  
051  /**This counter is used to test whether the interrupting of the thread works. */
052  int testCtInterrupted = 0;
053  
054  /**A Thread-instance is a composite part of this class. The thread-instance organizes the thread only.
055   * Another possibility is deriving this class from Thread instead implementing Runnable. It is realized
056   * in {@link TestWaitNotify}. 
057   */
058  final Thread theThread = new Thread(this, "TestThread");
059  
060  /**This class is defined only to use in the threads context. No other thread should have access to it.
061   * Therefore the instance can be defined in a thread-local data range. For Java2C it is possible
062   * to create a stack-instance. It is done in the {@link TestThread#run()}. routine.
063   * <br><br>
064   * 
065   */
066  private final static class TestThreadLocalData
067  {
068    float x,y;
069    
070    /**Example for a large data area. The buffer is allocated in C in the class as embedded instance,
071     * because the class' instances is allocated in stack, the buffer is located in the stack.
072     * <br><br>
073     * If the Java program takes the reference of the buffer and stores it in another instance,
074     * which is accessed from another thread, it is possible in Java because in Standard-Java
075     * it's a normal instance in heap. But the implementation in C in a protected memory system
076     * will force a memory protection error, because the data area is located in the stack of another thread.
077     * The stacks of several threads should not accessible one to another. That is ones of distinctions
078     * between a standard Java environment to test and the implementation in a target system.
079     * Such errors should recognized in the test of target. 
080     */
081    final StringBuffer threadownBuffer = new StringBuffer(3000);
082  }
083  
084  /**Aggregation to data to check wait/notify. */
085  private final TestWaitNotify.WaitNotifyData theNotifyingData;
086  
087  /**Constructor. 
088   * @param theNotifyingData The aggregation to data, which is used to test wait-notify.
089   */
090  TestThread(TestWaitNotify.WaitNotifyData theNotifyingData)
091  {
092    this.theNotifyingData = theNotifyingData;
093  }
094  
095  /**This is the thread main-routine complying the Java rules. The routine is started 
096   * if the java.lang.Thread-instance, which associates the class ({@link #theThread}, 
097   * is called with ,,start(),,-method. 
098   * implements {@link java.lang.Runnable#run()}
099   * <br><br>
100   * The thread-main-routine creates instances, which are only accessed by this thread.
101   * In Java the instances are referenced, but the reference is only known in stack context,
102   * provided to called routines via parameter. In C the instances are allocated in the stack
103   * because a <code>@ java2c=stackInstance.</code> is written thereby. Large-size instances need
104   * an adequate stack size. The Java-code for this code-snippet is:
105   * <pre class="Java">
106     ...* @java2c=stackInstance. * /
107    TestThreadLocalData threadLocalData = new TestThreadLocalData();
108   * </pre>
109   * The generated C-code is:
110   * <pre class="CCode">
111    TestThread_Test__TestThreadLocalData_s threadLocalData;  
112    ...
113    init_ObjectJc(&(threadLocalData.base.object), sizeof(threadLocalData), 0); 
114    ctorO_TestThread_Test__TestThreadLocalData(&(threadLocalData.base.object), _thCxt);
115   * </pre>
116   * The thread contains a <code>for</code>-loop to force a determined call  of <code>testSynchronized</code>,
117   * and a call of <code>notify(...)</code> to test the wait/notify-concept with a third thread.
118   * Than a sleep is called to delay the execution of the thread with deterministic milliseconds-time. 
119   * The Java-form is:
120   * <pre class="Java">
121    for(int liveCt = 0; liveCt <200; liveCt++){
122      testSynchronized(threadLocalData);
123      theNotifyingData.notify(testCt1);
124      try{ Thread.sleep(10); } 
125      catch(InterruptedException exc){
126        testCtInterrupted +=1;
127      }
128      
129    }//for
130   * </pre>
131   * The catch clause is processed if the thread was woken up abnormal. The coding of this catch is prescribed in Java.
132   * In C it is mapped too, but it isn't used yet. 
133   * <br><br>
134   * The C-code of this snippet is:
135   * <pre class="CCode">
136      for(liveCt = 0; liveCt < 200; liveCt++)
137        { testSynchronized_TestThread_Test(ythis, & (threadLocalData), _thCxt);
138          theNotifyingDataMtbl.mtbl->notify( (theNotifyingDataMtbl.ref), ythis->testCt1, _thCxt);
139          TRY
140          { sleep_ThreadJc(10, _thCxt);
141          }_TRY
142          CATCH(InterruptedException, exc)
143            { ythis->testCtInterrupted += 1;
144            }
145          END_TRY
146        }
147   * </pre>
148   * The call of <code>theNotifyingDataMtbl.mtbl->notify(...)</code> is executed dynamically,
149   * because the destination instance can be an derived class of the reference type
150   * in an enhancement of the example. To prevent effort to get the method table reference,
151   * the Java-code contains a stack-local reference at top of the routine, 
152   * see {@link org.vishia.java2C.Docu.D_SuperClassesAndInterfaces#D6_callingOverrideableMethods()}.
153   * <pre class="Java">
154    /**Use local variable to enforce only one preparation of the method table for dynamic call:
155     * @java2c=dynamic-call.
156     * /
157    final TestWaitNotify.WaitNotifyData theNotifyingDataMtbl = theNotifyingData;
158   * </pre> 
159   */
160  public void run(){
161    threadRunning = true;
162    /**Use local variable to enforce only one preparation of the method table for dynamic call:
163     * @java2c=dynamic-call.
164     */
165    final TestWaitNotify.WaitNotifyData theNotifyingDataMtbl = theNotifyingData;
166    /**This instance is only visible in the threads context. It is allocated in the stack.
167     * @java2c=stackInstance. */
168    TestThreadLocalData threadLocalData = new TestThreadLocalData();
169    for(int liveCt = 0; liveCt <200; liveCt++){
170      testSynchronized(threadLocalData);
171      theNotifyingDataMtbl.notify(testCt1);
172      try{ Thread.sleep(10); } 
173      catch(InterruptedException exc){
174        testCtInterrupted +=1;
175      }
176      
177    }//for
178    System.out.println("test-thread stopped at " + threadLocalData.x);
179    threadFinished = true;
180  }
181
182
183  
184  /**This routine shows and support test of a mutex-access. 
185   * The {@link #testCt1} and {@link #testCt2} of this class are decremented together. 
186   * The rule is: both counter should contain the same number. There are incremented 
187   * in the routine {@link #otherThreadRoutine()} from another thread and decremented here
188   * independently, but similar. The equality of both counter values are tested on entry 
189   * using an assert statement. The Java-Code is
190   * <pre class="Java">
191    synchronized(this)
192    { assert(testCt1 == testCt2);
193      testCt1 -=2;
194      try{ Thread.sleep(5);} 
195      catch (InterruptedException e){}   
196      testCt2 -=2;
197      threadLocalData.x = testCt1;
198    }  
199   * </pre> 
200   * The C-Code is:
201   * <pre class="CCode">
202    synchronized_ObjectJc(& ((* (ythis)).base.RunnableJc.base.object)); {
203      { ASSERT(ythis->testCt1 == ythis->testCt2);
204        ythis->testCt1 -= 2;
205        TRY
206        { sleep_ThreadJc(5, _thCxt);
207        }_TRY
208        CATCH(InterruptedException, e){} END_TRY
209        ythis->testCt2 -= 2;
210        threadLocalData->x = ((float)(ythis->testCt1));
211      }
212    } endSynchronized_ObjectJc(& ((* (ythis)).base.RunnableJc.base.object));
213   * </pre>
214   * The <code>sleep</code>-call is disposed here only to provoke a thread switch 
215   * during this mutex-saved operation. Without <code>synchronized</code> the interruption of this
216   * statement block between the two counter-increments from the other thread accessing the counters
217   * is likely, the <code>synchronized</code> is effective well able to test.
218   * <br><br>
219   * The Java construction 
220   * <pre class="Java">
221   * synchronized {
222   *   ...guarded block
223   * }  
224   * <pre>
225   * is well bounded with <code>{ .... }</code>, the programmer can't forget the exit from the guard.
226   * It is the syntax of Java. Hand written in C, the exit of the guard block (critical section)
227   * may be missed because the programmer has forgotten it. The C-translation of Java is safety respectively this problem,
228   * though an extra routine <code>endSynchronized_ObjectJc</code> is called.
229   * @param threadLocalData
230   */
231  final void testSynchronized(TestThreadLocalData threadLocalData)
232  { synchronized(this)
233    { assert(testCt1 == testCt2);
234      testCt1 -=2;
235      
236      /**Let the thread sleeping to provoke a switch to the other thread. 
237       * It isn't a pattern for a well programming, because it is in a synchronized block.
238       * It is only prober to force errors.
239       */
240      try{ Thread.sleep(5);} 
241      catch (InterruptedException e){}   
242      testCt2 -=2;
243      threadLocalData.x = (float)testCt1;
244    }
245  }
246  
247  
248  
249  
250  /**Facade routine to start the Thread.
251   * The Java-lines are:
252   * <pre class="Java">
253    / **@java2c=stackSize(TestThreadLocalData+2000). * /
254    theThread.start();
255   * </pre>
256   * The stackSize is necessary for the C-implementation. Because an instance of <code>TestThreadLocalData</code>
257   * is created in the {@link #run()}-Method, its size should be regarded. 
258   * The rest, 2000 Bytes, is a proper value for typical stack usages.
259   * <br><br>
260   * The translated C-code is
261   * <pre class="CCode">
262    start_ThreadJc(& (ythis->theThread)
263                  , sizeof(TestThread_Test__TestThreadLocalData_s)+2000, _thCxt);
264   * </pre> 
265   * The stackSize-annotation is translated to the stackSize-parameter-value for the <code>start_ThreadJc</code>-routine.
266   * The really size should be tested at C-level-debugging.
267   */
268  public void start()
269  { /**@java2c=stackSize(TestThreadLocalData+2000). */
270    theThread.start();
271  }
272  
273  /**This routine is called from outside in another thread. It demonstrates a concurrent access 
274   * which is guard with a <code>synchronized</code> adequate to {@link #run()}.
275   * This routine works with 500 loops in a time of 10 ms. At its end {@link #shouldRun} is set to <code>false</code>,
276   * which causes an aborting of the {@link #run()}-routine and therefore the finishing of the thread.
277   * 
278   */
279  public void otherThreadRoutine()
280  {
281    for(int i = 0; i < 200; i++){
282      synchronized(this)
283      //if(testCt1 ==5){}
284      { assert(testCt1 == testCt2);
285        testCt1 +=3;
286        testCt2 +=3;
287      }
288      try{ Thread.sleep(10);} 
289      catch (InterruptedException e){}
290    }//for
291    
292    /**Wait unil the thread of the instance is finished: */
293    int ctWaitFinished = 0;
294    while(!isThreadFinished()){
295      ctWaitFinished ++;
296      /**This is a polling loop. It should be contain a reasonable wait statement to release the CPU-ressource while polling: */
297      try{ Thread.sleep(5);} 
298      catch (InterruptedException e){}
299    }
300    System.out.println("main-thread stopped at " + testCt1 + ", ctWaitFinished=" + ctWaitFinished);
301
302  }
303
304  /**Returns true if the class private variable {@link #threadFinished} is set. That occurs at last action
305   * of the {@link #run()}-routine of the thread.
306   * @return
307   */
308  public final boolean isThreadFinished()
309  {
310    return threadFinished;
311  }
312}