create clock id: id->state = OK; waiting for id: lock /* once unscheduled, the id cannot be used anymore */ while (id->state != unscheduled) { id->state = busy; unlock ret = gstpoll (timeout); lock if (id->state == unscheduled) { /* id became unscheduled, read the fd and broadcast */ read (fd) cond_broadcast () } else { if (ret != 0) { /* some other id got unlocked */ /* mark ourselves as EARLY, we release the lock and we could be * unscheduled ourselves but we don't want the unscheduling thread * to write on the fd */ id->state = EARLY; /* wait until it reads the fd and signals us */ cond_wait () } else { /* we timed out */ id->state = OK | EARLY; } } } unlock return id->state; unschedule id: lock /* when it leaves the poll, it'll detect the unscheduled. */ id->state = unscheduled; /* if it's busy waiting in poll, write to the fd */ if (id->state == busy) { write (fd) } unlock