To create optimized and efficient programs, note the following: 
               	 
            
 
            	 
             
               		
               		
               - Always add code to your application that checks whether the application is running under the single-threaded or multi-threaded
                  run-time system. 
                  		
               
- Use the NOREENTRANT and NOSERIAL Compiler directives (the default) wherever possible. This minimizes stack space and call
                  entry overhead but it is up to the programmer to ensure that a program that uses these directives is only active in one thread
                  at a time. 
                  		
               
- The use of the REENTRANT(1) Compiler directive increases stack space usage but does not significantly affect the call speed
                  of the program. 
                  		
               
- The use of the SERIAL program attribute significantly affects the speed of calls but does not affect the stack space requirements
                  of the program. 
                  		
               
- Use the Local-Storage Section to hold thread work variables. While this increases stack space requirements, the allocation
                  of data is very fast. 
                  		
               
- Using the Thread-Local-Storage Section significantly effects call speed. Replacing the Working-Storage Section with the Thread-Local-Storage
                  Section is an easy way to make some applications to be made entirely thread-safe.
                  		
               
 
               		
               - Use mutexes for simple locking. These are the fastest of the synchronization structures. 
                  		
               
- Use monitors to provide maximum multi-threading in programs that might cause readers and writers based problems. 
                  		
               
- If possible, initialize all synchronization data items while in single-threaded execution. If this is not possible, then use
                  a first time flag which is checked once before a CBL_THREAD_PROG_LOCK and checked again after obtaining the lock. 
                  		
               
- Remember the difference between a thread and a thread handle. Create a non-detached thread only if necessary. 
                  		
               
- Use CBL_THREAD_KILL only if absolutely necessary and if you do use it, terminate the run-unit as soon as possible afterwards.
                  Where possible, use termination polling instead. 
                  		
               
- Use CBL_THREAD_SUSPEND in preference to CBL_THREAD_YIELD. Avoid busy waits. 
                  		
               
- Keep the amount of work done between CBL_THREAD_LIST_START and CBL_THREAD_LIST_END calls to a minimum. 
                  		
               
- In certain circumstances, the application can conserve per thread memory by using the CBL_TSTORE_n routines in preference
                  to the Thread-Local-Storage Section. 
                  		
               
- Try to avoid deadlock rather than attempting to correct it once it has occurred. 
                  		
               
- Avoid nesting read locks on monitors and, if you must, then be aware of the possibility of single thread deadlock.
                  		
               
The Compiler directives available for multi-threaded applications can affect the performance of your multi-threaded and single-threaded
               applications.