Forums | developer.brewmp.com Forums | developer.brewmp.com

Developer

Forums

I'm trying to use the IThread interface.

I understand that they're cooperative threads --- that's fine, I'm used to these.

However, the documentation doesn't say whether the threads are scheduled or not. This is important, as it makes a big difference how I would use them.

The crucial questions are:

  • are there any situations when an IThread will start executing other than when I explicitly resume it? In particular, do I always need to explicitly resume the root thread to return to the event loop?
  • when I call IThread_Start() to initialise a new thread, does the thread become suspended (so that I have to resume it to make its code run), or does execution immediately switch to it?

I'm not planning on touching any of the thrdutils code.

(Non-scheduled cooperative threads are more like coroutines or Windows fibres. Scheduled cooperative threads are more like non-timesliced traditional threads. I need different algorithms to make my code work depending on what I'm using.)

The slack docs don't help much so I've been guessing that these are self-scheduled cooperative threads.   Other than a register/stack context swapout (and some callback gizmos) I believe you get roughly the same execution semantics as a normal non-threaded BREW MP environment.

The slack docs don't help much so I've been guessing that these are self-scheduled cooperative threads.   Other than a register/stack context swapout (and some callback gizmos) I believe you get roughly the same execution semantics as a normal non-threaded BREW MP environment.

Hi David,
For your first question, you don't explicitly "resume" the thread but you have to register the thread to be resumed by BREW through ISHELL_Resume. 
For your second question, when you call IThread_Start() on a thread X, BREW will schedule the thread X to be executed, i.e. imagine the thread being added to a queue. Whether it actually gets executed immediately depends on whether or not there is currently any other thread that is scheduled/queued before it. If not, it will get started once your code returns to BREW. If there is, this thread X will have to wait till the thread before it suspends itself (ITHREAD_Suspend()) and BREW will then executes X. This is due to the fact the cooperative multithreading here is essentially a single BREW thread being time-sliced to run multiple callback/subroutines.  And each callback is essentially performing tasks for each thread and it yeilds via ITHREAD_Suspend() and registers itself to be invoked again through ISHELL_Resume(pShell, ITHREAD_GetResumeCBK(pThread));.
 
You should take a look at the how-to doc and the sample code from: https://developer.brewmp.com/resources/how-to/using-ithread
 
Thanks
-Tony
 
 

Hi David,
For your first question, you don't explicitly "resume" the thread but you have to register the thread to be resumed by BREW through ISHELL_Resume. 
For your second question, when you call IThread_Start() on a thread X, BREW will schedule the thread X to be executed, i.e. imagine the thread being added to a queue. Whether it actually gets executed immediately depends on whether or not there is currently any other thread that is scheduled/queued before it. If not, it will get started once your code returns to BREW. If there is, this thread X will have to wait till the thread before it suspends itself (ITHREAD_Suspend()) and BREW will then executes X. This is due to the fact the cooperative multithreading here is essentially a single BREW thread being time-sliced to run multiple callback/subroutines.  And each callback is essentially performing tasks for each thread and it yeilds via ITHREAD_Suspend() and registers itself to be invoked again through ISHELL_Resume(pShell, ITHREAD_GetResumeCBK(pThread));.
 
You should take a look at the how-to doc and the sample code from: https://developer.brewmp.com/resources/how-to/using-ithread
 
Thanks
-Tony
 
 

Okay, so to summarise:

There is a scheduler;
Context switches occur on ITHREAD_Suspend() and in the event loop (i.e., outside the applet) only, and nowhere else (including when blocked on I/O).

Is this correct?
Also, I see no mention of thread priorities. What scheduling strategy is used? Can I guarantee that if I yield a thread (make it runnable with ISHELL_Resume() and then immediately suspend it), all other threads will get run before the thread that did the yield runs again?

Okay, so to summarise:

There is a scheduler;
Context switches occur on ITHREAD_Suspend() and in the event loop (i.e., outside the applet) only, and nowhere else (including when blocked on I/O).

Is this correct?
Also, I see no mention of thread priorities. What scheduling strategy is used? Can I guarantee that if I yield a thread (make it runnable with ISHELL_Resume() and then immediately suspend it), all other threads will get run before the thread that did the yield runs again?

There are no thread priorities for IThread. The callback for IThread gets scheduled in a FIFO manner even though it's probably better not to assume the order in which the callbacks are dispatched. 

There are no thread priorities for IThread. The callback for IThread gets scheduled in a FIFO manner even though it's probably better not to assume the order in which the callbacks are dispatched.