Un protothread viene eseguito all'interno di una singola funzione C e non può estendersi su altre funzioni. Può, ovviamente, chiamare normali funzioni C ma, al tempo stesso, non può “bloccarsi” all'interno di una funzione chiamata.
Questo codice, quindi, non potrà mai né eseguirsi né tanto meno compilarsi correttamente:
void f( ) {
...
MR_PTI_YIELD();
...
}
MR_PT_THREAD(g) {
...
f();
...
}
Questo perché il protothread g() cercherà di bloccare l'esecuzione quando si trova nella funzione f(), che a sua volta non è un protothread. Per superare questo limite può essere generato un protothread separato per ciascuna funzione potenzialmente bloccante e allocata, di conseguenza, una variabile mr_protothread a lui dedicata.
MR_PT_THREAD(f) {
...
MR_PTI_YIELD();
...
}
mr_protothread fThread;
MR_PT_THREAD(g) {
...
MR_PTI_SPAWN(&fThread, f(&fThread));
...
}
Il vantaggio di questo approccio è che il blocco è esplicito, e quindi il programmatore sa esattamente quali funzioni possono bloccare quelle non possono bloccare, semplificando quindi il debugging.