* General sleep call. Suspends the current thread until a wakeup is * performed on the specified identifier. The thread will then be made * runnable with the specified priority. Sleeps at most sbt units of time * (0 means no timeout). If pri includes the PCATCH flag, let signals * interrupt the sleep, otherwise ignore them while sleeping. Returns 0 if * awakened, EWOULDBLOCK if the timeo
| 132 | * flag the lock is not re-locked before returning. |
| 133 | */ |
| 134 | int |
| 135 | _sleep(const void *ident, struct lock_object *lock, int priority, |
| 136 | const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags) |
| 137 | { |
| 138 | struct thread *td; |
| 139 | struct lock_class *class; |
| 140 | uintptr_t lock_state; |
| 141 | int catch, pri, rval, sleepq_flags; |
| 142 | WITNESS_SAVE_DECL(lock_witness); |
| 143 | |
| 144 | td = curthread; |
| 145 | #ifdef KTRACE |
| 146 | if (KTRPOINT(td, KTR_CSW)) |
| 147 | ktrcsw(1, 0, wmesg); |
| 148 | #endif |
| 149 | WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, lock, |
| 150 | "Sleeping on \"%s\"", wmesg); |
| 151 | KASSERT(sbt != 0 || mtx_owned(&Giant) || lock != NULL, |
| 152 | ("sleeping without a lock")); |
| 153 | KASSERT(ident != NULL, ("_sleep: NULL ident")); |
| 154 | KASSERT(TD_IS_RUNNING(td), ("_sleep: curthread not running")); |
| 155 | if (priority & PDROP) |
| 156 | KASSERT(lock != NULL && lock != &Giant.lock_object, |
| 157 | ("PDROP requires a non-Giant lock")); |
| 158 | if (lock != NULL) |
| 159 | class = LOCK_CLASS(lock); |
| 160 | else |
| 161 | class = NULL; |
| 162 | |
| 163 | if (SCHEDULER_STOPPED_TD(td)) { |
| 164 | if (lock != NULL && priority & PDROP) |
| 165 | class->lc_unlock(lock); |
| 166 | return (0); |
| 167 | } |
| 168 | catch = priority & PCATCH; |
| 169 | pri = priority & PRIMASK; |
| 170 | |
| 171 | KASSERT(!TD_ON_SLEEPQ(td), ("recursive sleep")); |
| 172 | |
| 173 | if ((uintptr_t)ident >= (uintptr_t)&pause_wchan[0] && |
| 174 | (uintptr_t)ident <= (uintptr_t)&pause_wchan[MAXCPU - 1]) |
| 175 | sleepq_flags = SLEEPQ_PAUSE; |
| 176 | else |
| 177 | sleepq_flags = SLEEPQ_SLEEP; |
| 178 | if (catch) |
| 179 | sleepq_flags |= SLEEPQ_INTERRUPTIBLE; |
| 180 | |
| 181 | sleepq_lock(ident); |
| 182 | CTR5(KTR_PROC, "sleep: thread %ld (pid %ld, %s) on %s (%p)", |
| 183 | td->td_tid, td->td_proc->p_pid, td->td_name, wmesg, ident); |
| 184 | |
| 185 | if (lock == &Giant.lock_object) |
| 186 | mtx_assert(&Giant, MA_OWNED); |
| 187 | DROP_GIANT(); |
| 188 | if (lock != NULL && lock != &Giant.lock_object && |
| 189 | !(class->lc_flags & LC_SLEEPABLE)) { |
| 190 | WITNESS_SAVE(lock, lock_witness); |
| 191 | lock_state = class->lc_unlock(lock); |
no test coverage detected