daily pastebin goal
83%
SHARE
TWEET

threading.c

a guest Apr 16th, 2014 41 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top