Il modulo xtime

Il modulo ntk.lib.xtime (TODO: replicato in ntk.wrap.xtime, perché?) risponde al problema dell'uso di sleep in un ambiente di multithread cooperativo.

Quando un microthread ha la necessità di attendere alcuni istanti prima di eseguire una certa azione, come lo fa?
Supponiamo si vuole attendere una certa condizione.

Può eseguire

    while not my_condition():
        pass

Questa è una cosidetta busy-wait. Il sistema viene appesantito, perché fino a quando la condizione non diventa vera il processo impegna la CPU.

Di norma si evita questo spreco inserendo dei piccoli sleep. Ad esempio

    while not my_condition():
        time.sleep(0.01)

Durante questa attesa la CPU non è impegnata. Soltanto una volta ogni 0.01 secondi, che per il processore è molto tempo, fa qualcosa per verificare se la condizione è divenuta vera.
Questa non è più una busy-wait, nel senso che l'intero sistema non viene appesantito. Ma in un ambiente di microthread cooperativi, questo approccio non istruisce lo schedulatore di passare il comando ad altri microthread. Così, anche se il sistema appare scarico, il nostro programma non va avanti.

Va quindi aggiunta una chiamata alla stackless.schedule, che nel nostro programma è nel metodo micro.micro_block().

    while not my_condition():
        time.sleep(0.01)
        micro.micro_block()

Nota: la chiamata a time.sleep resta necessaria, altrimenti ritorneremo ancora ad una situazione di busy-wait.

Il modulo xtime facilita questo lavoro implementando una funzione swait che automaticamente intervalla uno sleep di 0.001 secondi con una chiamata micro_block fino a quando non è passato il tempo richiesto.
Notare inoltre che in questo modulo sia la funzione swait sia la funzione time usano come unità il millisecondo, invece del secondo come nel modulo standard time. (TODO: C'è un motivo particolare?)
  xtime.swait(500)