Page 1 of 1

Multi-tasking

Posted: Sun Aug 29, 2004 5:54 pm
by PrimeTime
Hi again,

I'm having a problem with threads.
What I am doing is creating and starting a thread from main() that
will call a routine which in turn will create and start another thread.

The first thread from main() will run a function that will open and buffer a sound file. When the buffer is full, this function starts a new thread that plays the buffer and then it gets back to work refilling the buffer. Everything works fine except in my main function. After I start the thread, the main() will continue to run until it eventually ends, which is normal, I don't want it to end however so I've placed a busy-waiting loop after starting the thread. This works, but it seems that whenever my thread read a sound file to buffer, it makes some incorrect reads.

Next, I tried placing a SleepThread or WaitSema after starting the thread. This works great. After the thread is done, I call WakeupThread and give it the ID of the main routine. Even though I called wakeupthread() at the end of my thread function, it crashes. The ps2 throws and exception at me.

My goal is to be able to stream a sound file while using the controller to browse other sound files on the HDD.

Anyway here is some code from my main(), maybe someone knows an alternative method i could use.


Code: Select all

int main()
{
   int pid=-1;
   int t=0;
   t_hddInfo hddInfo;
   int iFile;
   struct WAV decoder;
   
   SifInitRpc(0);
   init_scr();
   hddPreparePoweroff();
   hddInit();
   hddSetUserPoweroffCallback((void *)poweroffHandler,(void *)pid);
   ret = sbv_patch_enable_lmb();
   ret = sbv_patch_disable_prefix_check();
   
   rmallocInit();
	
   if &#40;OpenPartition&#40;"hdd0&#58;+WAV"&#41; < 0&#41;
      return -1;

   SjPCM_Init&#40;0&#41;;
   SjPCM_Clearbuff&#40;&#41;;
   SjPCM_Setvol&#40;0x3fff&#41;;
	
   CreateDecoder&#40;"voice.wav", 8, &decoder&#41;; //This sets up the thread with priority 8
   StartDecoder&#40;&decoder&#41;;  //StartThread&#40;&#41;;
   SleepThread&#40;&#41;;
   ClosePartition&#40;&#41;;
   scr_printf&#40;"Finished.\n"&#41;;
   SifInitRpc&#40;0&#41;;
   return 0;
&#125;

int CreateDecoder&#40;char *filename, int priority, struct WAV *decode&#41;
&#123;
   decode->thread.func = &#40;void *&#41;RunDecoder;
   decode->thread.stack = decode->decoderThreadStack;
   decode->thread.stack_size = sizeof&#40;decode->decoderThreadStack&#41;;
   decode->thread.gp_reg = &_gp;
   decode->thread.initial_priority = priority;
   decode->pid = CreateThread&#40;&decode->thread&#41;;
   strcpy&#40;decode->fileName, filename&#41;;
   decode->parent = GetThreadId&#40;&#41;;
   decode->flag = 1;

   decode->sema.init_count = 0;
   decode->sema.max_count = 1;
   decode->sema.option = 0;
   decode->Semaphore = CreateSema&#40;&decode->sema&#41;;

   return decode->pid;
&#125;

void RunDecoder&#40;void *arg&#41; //this is the threaded function
&#123;
   struct WAV *decode = &#40;struct WAV *&#41;arg;
   printf&#40;"opening...\n"&#41;;
   decode->iFile = fileXioOpen&#40;decode->fileName, O_RDONLY, 0&#41;;
   printf&#40;"opened %d\n", decode->iFile&#41;;
   WAVAudioDecoder&#40;decode->iFile&#41;; //This buffers and calls the SjPCM thread.  This function does not end until the sound is done.
   decode->flag = 2;
   WakeupThread&#40;decode->parent&#41;; //Wakes up main&#40;&#41;
   printf&#40;"RunDecoder Done\n"&#41;;  //Crashes after function exits.
&#125;



Posted: Tue Aug 31, 2004 7:46 am
by J.F.
If you noticed today's thread, mrbrown mentioned that the PS2 uses cooperative multitasking. The moment you wake the main thread, if it's a higher priority, it will run instead of the decoder thread. The main thread will cleanup and exit, then the decoder thread gets to run again - which is a serious bug.

You need to wait for the decoder thread to exit before doing any cleanup in the main thread. That might help the problem.