Advertisement
Guest User

threading.c

a guest
Apr 16th, 2014
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.25 KB | None | 0 0
  1. /*
  2.  
  3.  
  4. custom threading system
  5.  
  6. usage;  you basically do;
  7.  
  8.     void main(){
  9.         int mythreadid=13;
  10.  
  11.         threading_init();  //only need to be done once
  12.  
  13.         threading_start(run_this_func, mythreadid );
  14.  
  15.         threading_wait_on(mythreadid);  //option 1: block until thread is done
  16.  
  17.         while( !threading_done(mythreadid) ){   //option 2: watch for thread to be complete
  18.             //do animation or something else while thread is running, if you chose not to block.
  19.         }
  20.     }
  21.            
  22.     static void *run_this_func(void *arg) {
  23.         //your code here
  24.        
  25.         while( threading_loop() ){
  26.             //your code here
  27.         }
  28.  
  29.         threading_halt_self();  //tell threading system than we done
  30.  
  31.     } //end sure that all threads end normally or you will run out of thread slots
  32.  
  33. */
  34.  
  35. #include <errno.h>
  36. #include <ogcsys.h>
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <unistd.h>
  40.  
  41. #include <string.h>
  42.  
  43. //-----------------------------------------------------------------------------------
  44.  
  45. #define THREADING_MAX_CONCURRENT 10
  46.  
  47. #define THREADMAX 18
  48.  
  49. #define STACKSIZE 8*1024  //was 8*1024
  50.  
  51. static lwp_t main_thread[THREADMAX];  //singleton
  52. lwpq_t thread_queue;
  53.  
  54. static volatile bool main_thread_active[THREADMAX];
  55. //static volatile bool main_thread_complete = false;
  56. //static volatile bool main_thread_busy = false;
  57.  
  58. static u8 stack1[THREADMAX][STACKSIZE] ATTRIBUTE_ALIGN (32);
  59.  
  60. static int current_thread=0;
  61.  
  62. static int threading_system_initialized=0;
  63. static int threading_system_halted=0;
  64.  
  65. static bool threading_debug = false;
  66.  
  67. int testint;
  68.  
  69. //----------------------------------------------------------------
  70.  
  71. typedef struct {
  72.     int thread_key;
  73.     bool active;
  74. } ThreadKeyStruct;
  75.  
  76.  
  77. //-------------------------------------------
  78.  
  79. ThreadKeyStruct threadkey_list[THREADMAX];
  80.  
  81.  
  82. //----------------------------------------------------------------
  83.  
  84. int threading_active_count(){  //internal function
  85.  
  86.     unsigned int i;
  87.     int temp=0;
  88.     for(i=1;i<THREADMAX;++i) {  //probably i should start from current_thread instead of zero
  89.         if( threadkey_list[i].active ) temp++;
  90.     }      
  91.     return temp;
  92. }
  93.  
  94.  
  95. //---------------------------------------------------------------------------
  96.  
  97. bool threading_loop(){
  98.     usleep(5);
  99.     if( threading_system_halted==1 ) return false;
  100.     return true;
  101. }
  102.  
  103. //----------------------------------------------------------------
  104.  
  105. bool threading_done(int thread_key){
  106.  
  107.     int i;
  108.     for(i=0;i<THREADMAX;++i){
  109.         if( threadkey_list[i].thread_key == thread_key ) {
  110.             //printf("thread closed normally. i=%i, tk=%i\n", i, threadkey_list[i].thread_key);
  111.        
  112.             if(main_thread[i] == LWP_CLOSED ) threadkey_list[i].active=false;      
  113.            
  114.             if(LWP_ThreadIsSuspended(main_thread[i])){
  115.                 threadkey_list[i].active=false;  //thread must suspend itself when done by calling threading_halt_self()
  116.                 //or the thread will just keep running forever.
  117.                    
  118.             }
  119.            
  120.             return !threadkey_list[i].active;      
  121.         }
  122.     }
  123.  
  124.     return true; //probably not done or not in list at all
  125. }
  126.  
  127. int threading_test(){
  128.     return testint;
  129. }
  130.  
  131. void threading_debug_flag(bool flag){
  132.     threading_debug = flag;
  133. }
  134.  
  135. //----------------------------------------------------------------
  136.  
  137. void threading_init(){
  138.  
  139.     if(threading_system_initialized !=0 ) return;  //already initialized
  140.    
  141.     int i; 
  142.     for(i=0;i<THREADMAX;++i) {
  143.         main_thread[i] = LWP_THREAD_NULL;
  144.         threadkey_list[i].active=false;
  145.         threadkey_list[i].thread_key=-1;
  146.     }
  147.  
  148.     threading_system_halted=0;
  149.     threading_system_initialized=1;
  150.     current_thread=0;
  151.    
  152. }
  153.  
  154. //----------------------------------------------------------------
  155.  
  156.  
  157. static void threading_find_next_empty_slot(){  //internal function
  158.  
  159.     if(current_thread > THREADMAX-1 ) current_thread = 0;
  160.  
  161.     if( threading_active_count() > THREADING_MAX_CONCURRENT-1 ){  //if too many threads open waiting until one stops
  162.    
  163.         if(threading_debug) printf("Too many threads open (%i/%i) waiting for a free slot ....\n", threading_active_count(), THREADING_MAX_CONCURRENT-1 );
  164.  
  165.         while(threading_loop()){  
  166.             if( threading_active_count() < THREADING_MAX_CONCURRENT ) break; //wait until a slot is free
  167.             LWP_YieldThread();
  168.         }
  169.  
  170.         if(threading_debug) printf("....done waiting for free slot (%i/%i).\n", threading_active_count(), THREADING_MAX_CONCURRENT-1 );
  171.     }
  172.  
  173.     if( threadkey_list[current_thread].active ){ //slot if already in use
  174.         unsigned int i;
  175.         for(i=0;i<THREADMAX;++i) {  //probably i should start from current_thread instead of zero
  176.                            
  177.             if(main_thread[i] == LWP_CLOSED ) threadkey_list[i].active=false;      
  178.  
  179.             if( threadkey_list[i].active ){ //check if this thread is suspended for some reason
  180.                 //if( LWP_ThreadIsSuspended(main_thread[i]) ) LWP_ResumeThread(main_thread[i]);
  181.             }
  182.  
  183.             if( !threadkey_list[i].active ){
  184.                 current_thread=i;  //set this to current and exit
  185.                 break;
  186.             }  
  187.         }      
  188.     } else {
  189.         //no need to do anything because this one is not active USED IT
  190.     }
  191.    
  192.     //if it can't find a empty slot its going to just take the first one
  193. }
  194.  
  195. //----------------------------------------------------------------
  196.  
  197. bool threading_start( void * (*thread_func)(void *), int thread_key ){
  198.  
  199.     if(threading_system_initialized == 0 ) threading_init();  
  200.  
  201.     threading_find_next_empty_slot();
  202.  
  203.     if(threading_debug) printf("thread selected. %i tk:%i\n", current_thread, thread_key );
  204.  
  205.     threadkey_list[current_thread].thread_key = thread_key;
  206.     threadkey_list[current_thread].active = true;
  207.  
  208.     if(threading_debug) printf("thread created....\n");
  209.    
  210.     memset (&stack1[current_thread], 0, STACKSIZE); // Clear memory  
  211.     s32 result = LWP_CreateThread(&main_thread[current_thread], thread_func, NULL, stack1[current_thread], STACKSIZE, 60+current_thread);
  212.  
  213.     if (result >= 0) {
  214.         testint=555;
  215.         return true;
  216.     }
  217.  
  218.     testint=threading_active_count();
  219.        
  220.     if(threading_debug) printf("thread failed to create.\n");
  221.     return false;
  222. }
  223.  
  224.  
  225. //---------------------------------------------------------------------------
  226.  
  227. void threading_wait_on(int thread_key){  //block until a thread is done
  228.  
  229.     if(threading_debug)
  230.     printf("threading_wait_on(%i)...\n", thread_key);
  231.    
  232.     while( threading_loop() ){     
  233.         if( threading_done(thread_key) ) break;
  234.         //fflush(stdout);
  235.         //usleep(5);
  236.         if( threading_system_halted==1 ) break;
  237.         LWP_YieldThread();
  238.     }
  239.  
  240.     if(threading_debug)
  241.     printf("...done waiting on thread (%i)\n", thread_key);
  242. }
  243.  
  244. //---------------------------------------------------------------------------
  245.  
  246. void threading_exit(){
  247.     threading_system_halted=1;
  248.     threading_system_initialized=0;
  249.    
  250.     int i;
  251.     for(i=0;i<THREADMAX;++i){
  252.  
  253.         if( !threadkey_list[i].active ) continue; //only check active threads
  254.        
  255.         threadkey_list[i].active=false;
  256.  
  257.         if( LWP_SuspendThread( main_thread[i] ) < 0 ){ 
  258.             if(threading_debug)
  259.             printf("failed to suspend thread. i=%i, tk=%i\n", i, threadkey_list[i].thread_key);
  260.         }
  261.     }
  262.  
  263.     if(threading_debug) printf("threading exited\n");
  264. }
  265.  
  266. //---------------------------------------------------------------------------
  267.  
  268. void threading_halt_self(){
  269.  
  270.     int i, tk, t_id;
  271.     //bool found=false;  //check to make sure this thread belongs to us before we halt it!
  272.     for(i=0;i<THREADMAX;++i){
  273.         if( !threadkey_list[i].active ) continue; //only check active threads
  274.         if( main_thread[i] == LWP_GetSelf() ){
  275.             t_id = i;
  276.             threadkey_list[t_id].active=false;         
  277.             break;
  278.         }
  279.     }
  280.    
  281.    
  282. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement