Page 1 of 1

More thread stuff

Posted: Mon Aug 30, 2004 9:08 am
by PrimeTime
Hi, some more problems.

I'm running a thread to get the status of a controller. Inside the thread, if I hit UP it will decrease the thread's priority, and DOWN will increase it.

After I call the thread, my main goes into a busy waiting look and prints some stuff to the screen to identify that it is currently running. My controller thread also prints to identify itself.

My problem is, when I run the thread, my main() loop never identifies itself, so it is never running, when i set the priorities to be the same, it still never runs. I would assume that I would get a mix of main() and my thread messages on the screen. When I set the priority lower, my main() message takes over and I never see the thread message again().

It seems like the threads with higher priority starve on the queue. Does anybody know how I'd get these two to run concurrently?

Can someone tell me what RotateThreadReadyQueue() does? I tried to use that will all kinda parameters, it doesn't do anything.

See

Code: Select all

void PollController() //The threaded Function
{
   int i = 50;
   while (1)
   {
      controllerReturn = padRead(0, 0, &buttons);
      if (controllerReturn != 0)
      {
         paddata = 0xffff ^ &#40;&#40;buttons.btns&#91;0&#93; << 8&#41; | buttons.btns&#91;1&#93;&#41;;
         new_pad = paddata & ~old_pad;
         old_pad = paddata;
      &#125;
      if&#40;new_pad & PAD_DOWN&#41;
      &#123;
         i-=1; if &#40;i<0&#41; i = 0;
      &#125;
      if&#40;new_pad & PAD_UP&#41;
      &#123;
         i+=1; if &#40;i>255&#41; i = 255;
      &#125;
      scr_printf&#40;"Read Controller %d  Priority %d\n", controllerReturn, i&#41;;
      ChangeThreadPriority&#40;GetThreadId&#40;&#41;, i&#41;;
   &#125;
&#125;

main() after i start the thread

Code: Select all

while &#40;1&#41;
&#123;
   scr_printf&#40;"MAIN&#58; This is the main function\n"&#41;;
&#125;
Thanks,
Ryan

Posted: Tue Aug 31, 2004 2:10 am
by mrbrown
The PS2 does not support preemptive multitasking. You must manually yield your thread or wait for an interrupt to take control from it. If you want your second thread to run at all, then it must be at the same priority or higher (use a lower number) than the main() thread. With ps2link I believe this means changing main()'s priority first, because ps2link creates main() with a priority of 1 (IIRC). RotateThreadReadyQueue() only works on threads that are at the same priority. IIRC, you pass it the number of the priority (queue) that you want rotated. If using different priorities, use SleepThread()/WakeupThread() or semaphores.

Again, the PS2's kernel will never yield to a lower priority thread unless you tell it to do so (or an interrupt causes the calling thread to yield).

Posted: Tue Aug 31, 2004 2:13 am
by mrbrown
Sorry, I didn't mean for that to be so confusing. If Thread A is a higher priority than Thread B, Thread B will only run if Thread A yields - either manually or due to an interrupt calling a function that makes Thread A yield. Other than that Thread B will never run. If Thread C has a higher priority than Thread A, then it will get control once Thread A yields, not Thread B. This assumes that Thread C yielded to Thread A in the first place.

Hopefully this is clearer than the previous post.

Posted: Tue Aug 31, 2004 3:15 am
by PrimeTime
Thanks, I understand what you mean.

I realized that I wasn't really programming under an OS, so there isn't anything to schedule different threads on a ready queue. Although, this makes me curious to whether there is a way to create a scheduler thread that will sleep for a certain amount of time and then wake up to schedule then go back to sleep again.

My first bet is that this thread would have to be hooked to some kind of timer interrrupt. Kind of how the poweroff thread is hooked to an interrupt.

Is there a list of all the available interrupts on the PS2? (for example the timer interrupt)

Thanks for your help,
Ryan

Posted: Tue Aug 31, 2004 5:39 am
by mrbrown
Er, you are programming under an OS :). There is a priority (ready) queue for each of the 128 thread priorities. The OS does handle context switches for you when you make the appropiate Wait/Signal, etc. calls, it just doesn't do any active scheduling. Yes, you could designate a thread to actively schedule other threads. You could try looking at the SetAlarm() and ReleaseAlarm() syscalls. If you're looking for low-level timer code I'd suggest looking at the PS2/Linux kernel source.