Changeset View
Changeset View
Standalone View
Standalone View
head/sys/compat/linuxkpi/common/src/linux_compat.c
Show First 20 Lines • Show All 1,315 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
/* | /* | ||||
* Indefinite wait for done != 0 with or without signals. | * Indefinite wait for done != 0 with or without signals. | ||||
*/ | */ | ||||
long | long | ||||
linux_wait_for_common(struct completion *c, int flags) | linux_wait_for_common(struct completion *c, int flags) | ||||
{ | { | ||||
long error; | |||||
if (SCHEDULER_STOPPED()) | if (SCHEDULER_STOPPED()) | ||||
return (0); | return (0); | ||||
DROP_GIANT(); | |||||
if (flags != 0) | if (flags != 0) | ||||
flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP; | flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP; | ||||
else | else | ||||
flags = SLEEPQ_SLEEP; | flags = SLEEPQ_SLEEP; | ||||
error = 0; | |||||
for (;;) { | for (;;) { | ||||
sleepq_lock(c); | sleepq_lock(c); | ||||
if (c->done) | if (c->done) | ||||
break; | break; | ||||
sleepq_add(c, NULL, "completion", flags, 0); | sleepq_add(c, NULL, "completion", flags, 0); | ||||
if (flags & SLEEPQ_INTERRUPTIBLE) { | if (flags & SLEEPQ_INTERRUPTIBLE) { | ||||
if (sleepq_wait_sig(c, 0) != 0) | if (sleepq_wait_sig(c, 0) != 0) { | ||||
return (-ERESTARTSYS); | error = -ERESTARTSYS; | ||||
goto intr; | |||||
} | |||||
} else | } else | ||||
sleepq_wait(c, 0); | sleepq_wait(c, 0); | ||||
} | } | ||||
c->done--; | c->done--; | ||||
sleepq_release(c); | sleepq_release(c); | ||||
return (0); | intr: | ||||
PICKUP_GIANT(); | |||||
return (error); | |||||
} | } | ||||
/* | /* | ||||
* Time limited wait for done != 0 with or without signals. | * Time limited wait for done != 0 with or without signals. | ||||
*/ | */ | ||||
long | long | ||||
linux_wait_for_timeout_common(struct completion *c, long timeout, int flags) | linux_wait_for_timeout_common(struct completion *c, long timeout, int flags) | ||||
{ | { | ||||
long end = jiffies + timeout; | long end = jiffies + timeout, error; | ||||
int ret; | |||||
if (SCHEDULER_STOPPED()) | if (SCHEDULER_STOPPED()) | ||||
return (0); | return (0); | ||||
DROP_GIANT(); | |||||
if (flags != 0) | if (flags != 0) | ||||
flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP; | flags = SLEEPQ_INTERRUPTIBLE | SLEEPQ_SLEEP; | ||||
else | else | ||||
flags = SLEEPQ_SLEEP; | flags = SLEEPQ_SLEEP; | ||||
for (;;) { | |||||
int ret; | |||||
error = 0; | |||||
ret = 0; | |||||
for (;;) { | |||||
sleepq_lock(c); | sleepq_lock(c); | ||||
if (c->done) | if (c->done) | ||||
break; | break; | ||||
sleepq_add(c, NULL, "completion", flags, 0); | sleepq_add(c, NULL, "completion", flags, 0); | ||||
sleepq_set_timeout(c, linux_timer_jiffies_until(end)); | sleepq_set_timeout(c, linux_timer_jiffies_until(end)); | ||||
if (flags & SLEEPQ_INTERRUPTIBLE) | if (flags & SLEEPQ_INTERRUPTIBLE) | ||||
ret = sleepq_timedwait_sig(c, 0); | ret = sleepq_timedwait_sig(c, 0); | ||||
else | else | ||||
ret = sleepq_timedwait(c, 0); | ret = sleepq_timedwait(c, 0); | ||||
if (ret != 0) { | if (ret != 0) { | ||||
/* check for timeout or signal */ | /* check for timeout or signal */ | ||||
if (ret == EWOULDBLOCK) | if (ret == EWOULDBLOCK) | ||||
return (0); | error = 0; | ||||
else | else | ||||
return (-ERESTARTSYS); | error = -ERESTARTSYS; | ||||
goto intr; | |||||
} | } | ||||
} | } | ||||
c->done--; | c->done--; | ||||
sleepq_release(c); | sleepq_release(c); | ||||
intr: | |||||
PICKUP_GIANT(); | |||||
/* return how many jiffies are left */ | /* return how many jiffies are left */ | ||||
return (linux_timer_jiffies_until(end)); | return (ret != 0 ? error : linux_timer_jiffies_until(end)); | ||||
} | } | ||||
int | int | ||||
linux_try_wait_for_completion(struct completion *c) | linux_try_wait_for_completion(struct completion *c) | ||||
{ | { | ||||
int isdone; | int isdone; | ||||
isdone = 1; | isdone = 1; | ||||
▲ Show 20 Lines • Show All 340 Lines • Show Last 20 Lines |