/* * Wake up threads in LwpDelayq whose time has come. */ void lwpWakeupSleep(void) { time_t now; struct lwpQueue save; struct lwpProc *proc; if (LwpDelayq.head) { now = time(NULL); save.tail = save.head = NULL; while (NULL != (proc = lwpGetFirst(&LwpDelayq))) { if (now >= proc->runtime) { lwpStatus(proc, "sleep done"); if (proc->runtime != 0) proc->runtime = (time_t)-1; if (proc->fd >= 0) lwpWakeupFd(proc); else lwpReady(proc); } else { lwpAddTail(&save, proc); } } LwpDelayq = save; } }
void lwp_rwlock_rdlock(struct lwp_rwlock *rwlock) { if (rwlock->count < 0 || rwlock->wq.head) { lwpStatus(LwpCurrent, "blocked to acquire rwlock %s for reading", rwlock->name); lwpAddTail(&rwlock->rq, LwpCurrent); lwpReschedule(); } CANT_HAPPEN(rwlock->count < 0); rwlock->count++; lwpStatus(LwpCurrent, "acquired rwlock %s for reading", rwlock->name); }
void lwp_rwlock_wrlock(struct lwp_rwlock *rwlock) { if (rwlock->count) { lwpAddTail(&rwlock->wq, LwpCurrent); lwpStatus(LwpCurrent, "blocked to acquire rwlock %s for writing", rwlock->name); lwpReschedule(); } CANT_HAPPEN(rwlock->count != 0); rwlock->count = -1; lwpStatus(LwpCurrent, "acquired rwlock %s for writing", rwlock->name); }
int lwpSleepUntil(time_t until) { int res; lwpStatus(LwpCurrent, "sleeping for %ld sec", (long)(until - time(NULL))); LwpCurrent->runtime = until; if (LwpMaxfd == 0 && !LwpDelayq.head) { /* select process is sleeping until first waiter arrives */ lwpReady(LwpSelProc); } lwpAddTail(&LwpDelayq, LwpCurrent); lwpReschedule(); res = LwpCurrent->runtime ? 0 : -1; LwpCurrent->runtime = (time_t)-1; return res; }
int lwpSleepFd(int fd, int mask, struct timeval *timeout) { lwpStatus(LwpCurrent, "sleeping on fd %d for %d", fd, mask); if (CANT_HAPPEN(fd < 0 || fd >= FD_SETSIZE)) { errno = EBADF; return -1; } if (LwpFdwait[fd]) { lwpStatus(LwpCurrent, "multiple sleeps attempted on file descriptor %d", fd); errno = EBADF; return -1; } if (mask & LWP_FD_READ) FD_SET(fd, &LwpReadfds); if (mask & LWP_FD_WRITE) FD_SET(fd, &LwpWritefds); LwpNfds++; if (LwpMaxfd == 0 && !LwpDelayq.head) { /* select process is sleeping until first waiter arrives */ lwpStatus(LwpCurrent, "going to resched fd %d", fd); lwpReady(LwpSelProc); } lwpStatus(LwpCurrent, "going to wait on fd %d", fd); if (timeout) { LwpCurrent->runtime = time(NULL) + timeout->tv_sec + (timeout->tv_usec > 0); lwpAddTail(&LwpDelayq, LwpCurrent); } else LwpCurrent->runtime = (time_t)-1; if (fd > LwpMaxfd) LwpMaxfd = fd; LwpFdwait[fd] = LwpCurrent; LwpCurrent->fd = fd; LwpCurrent->fd_ready = 0; lwpReschedule(); return LwpCurrent->fd_ready != 0; }