+ register int i;
+ boolean_t lock_miss = FALSE;
+#if MACH_LDEBUG
+ int decrementer;
+#endif /* MACH_LDEBUG */
+
+ simple_lock(&l->interlock);
+
+#if MACH_LDEBUG
+ decrementer = DECREMENTER_TIMEOUT;
+#endif /* MACH_LDEBUG */
+
+ /*
+ * Try to acquire the want_write bit.
+ */
+ while (l->want_write) {
+ if (!lock_miss) {
+ lock_miss = TRUE;
+ }
+
+ i = lock_wait_time[l->can_sleep ? 1 : 0];
+ if (i != 0) {
+ simple_unlock(&l->interlock);
+#if MACH_LDEBUG
+ if (!--decrementer)
+ Debugger("timeout - want_write");
+#endif /* MACH_LDEBUG */
+ while (--i != 0 && l->want_write)
+ continue;
+ simple_lock(&l->interlock);
+ }
+
+ if (l->can_sleep && l->want_write) {
+ l->waiting = TRUE;
+ thread_sleep_simple_lock((event_t) l,
+ simple_lock_addr(l->interlock),
+ THREAD_UNINT);
+ /* interlock relocked */
+ }
+ }
+ l->want_write = TRUE;
+
+ /* Wait for readers (and upgrades) to finish */
+
+#if MACH_LDEBUG
+ decrementer = DECREMENTER_TIMEOUT;
+#endif /* MACH_LDEBUG */
+ while ((l->read_count != 0) || l->want_upgrade) {
+ if (!lock_miss) {
+ lock_miss = TRUE;
+ }
+
+ i = lock_wait_time[l->can_sleep ? 1 : 0];
+ if (i != 0) {
+ simple_unlock(&l->interlock);
+#if MACH_LDEBUG
+ if (!--decrementer)
+ Debugger("timeout - wait for readers");
+#endif /* MACH_LDEBUG */
+ while (--i != 0 && (l->read_count != 0 ||
+ l->want_upgrade))
+ continue;
+ simple_lock(&l->interlock);
+ }
+
+ if (l->can_sleep && (l->read_count != 0 || l->want_upgrade)) {
+ l->waiting = TRUE;
+ thread_sleep_simple_lock((event_t) l,
+ simple_lock_addr(l->interlock),
+ THREAD_UNINT);
+ /* interlock relocked */
+ }
+ }
+
+ simple_unlock(&l->interlock);