|
|
@ -31,7 +31,8 @@ static const struct timespec final_wait_time = {
|
|
|
|
.tv_sec = 1
|
|
|
|
.tv_sec = 1
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
void ck_ec32_wake(struct ck_ec32 *ec, const struct ck_ec_ops *ops)
|
|
|
|
void
|
|
|
|
|
|
|
|
ck_ec32_wake(struct ck_ec32 *ec, const struct ck_ec_ops *ops)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
/* Spurious wake-ups are OK. Clear the flag before futexing. */
|
|
|
|
/* Spurious wake-ups are OK. Clear the flag before futexing. */
|
|
|
|
ck_pr_and_32(&ec->counter, (1U << 31) - 1);
|
|
|
|
ck_pr_and_32(&ec->counter, (1U << 31) - 1);
|
|
|
@ -39,7 +40,8 @@ void ck_ec32_wake(struct ck_ec32 *ec, const struct ck_ec_ops *ops)
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ck_ec32_wait_slow(struct ck_ec32 *ec,
|
|
|
|
int
|
|
|
|
|
|
|
|
ck_ec32_wait_slow(struct ck_ec32 *ec,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
uint32_t old_value,
|
|
|
|
uint32_t old_value,
|
|
|
|
const struct timespec *deadline)
|
|
|
|
const struct timespec *deadline)
|
|
|
@ -49,14 +51,16 @@ int ck_ec32_wait_slow(struct ck_ec32 *ec,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CK_F_EC64
|
|
|
|
#ifdef CK_F_EC64
|
|
|
|
void ck_ec64_wake(struct ck_ec64 *ec, const struct ck_ec_ops *ops)
|
|
|
|
void
|
|
|
|
|
|
|
|
ck_ec64_wake(struct ck_ec64 *ec, const struct ck_ec_ops *ops)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
ck_pr_and_64(&ec->counter, ~1);
|
|
|
|
ck_pr_and_64(&ec->counter, ~1);
|
|
|
|
ops->wake64(ops, &ec->counter);
|
|
|
|
ops->wake64(ops, &ec->counter);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int ck_ec64_wait_slow(struct ck_ec64 *ec,
|
|
|
|
int
|
|
|
|
|
|
|
|
ck_ec64_wait_slow(struct ck_ec64 *ec,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
uint64_t old_value,
|
|
|
|
uint64_t old_value,
|
|
|
|
const struct timespec *deadline)
|
|
|
|
const struct timespec *deadline)
|
|
|
@ -66,7 +70,8 @@ int ck_ec64_wait_slow(struct ck_ec64 *ec,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
int ck_ec_deadline_impl(struct timespec *new_deadline,
|
|
|
|
int
|
|
|
|
|
|
|
|
ck_ec_deadline_impl(struct timespec *new_deadline,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
const struct timespec *timeout)
|
|
|
|
const struct timespec *timeout)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -94,8 +99,10 @@ int ck_ec_deadline_impl(struct timespec *new_deadline,
|
|
|
|
* Returns a timespec value for deadline_ptr. If deadline_ptr is NULL,
|
|
|
|
* Returns a timespec value for deadline_ptr. If deadline_ptr is NULL,
|
|
|
|
* returns a timespec far in the future.
|
|
|
|
* returns a timespec far in the future.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static struct timespec canonical_deadline(const struct timespec *deadline_ptr)
|
|
|
|
static struct timespec
|
|
|
|
|
|
|
|
canonical_deadline(const struct timespec *deadline_ptr)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
if (deadline_ptr == NULL) {
|
|
|
|
if (deadline_ptr == NULL) {
|
|
|
|
return (struct timespec) { .tv_sec = TIME_MAX };
|
|
|
|
return (struct timespec) { .tv_sec = TIME_MAX };
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -115,8 +122,8 @@ static struct timespec canonical_deadline(const struct timespec *deadline_ptr)
|
|
|
|
* TODO: add some form of randomisation to the intermediate timeout
|
|
|
|
* TODO: add some form of randomisation to the intermediate timeout
|
|
|
|
* values.
|
|
|
|
* values.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static int exponential_backoff(
|
|
|
|
static int
|
|
|
|
struct ck_ec_wait_state *wait_state,
|
|
|
|
exponential_backoff(struct ck_ec_wait_state *wait_state,
|
|
|
|
bool (*sleep)(const void *sleep_state,
|
|
|
|
bool (*sleep)(const void *sleep_state,
|
|
|
|
const struct ck_ec_wait_state *wait_state,
|
|
|
|
const struct ck_ec_wait_state *wait_state,
|
|
|
|
const struct timespec *partial_deadline),
|
|
|
|
const struct timespec *partial_deadline),
|
|
|
@ -262,7 +269,8 @@ DEF_UPGRADE(64)
|
|
|
|
* eventcount's value has changed. If partial_deadline is NULL, wait
|
|
|
|
* eventcount's value has changed. If partial_deadline is NULL, wait
|
|
|
|
* forever.
|
|
|
|
* forever.
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static bool ck_ec32_wait_slow_once(const void *vstate,
|
|
|
|
static bool
|
|
|
|
|
|
|
|
ck_ec32_wait_slow_once(const void *vstate,
|
|
|
|
const struct ck_ec_wait_state *wait_state,
|
|
|
|
const struct ck_ec_wait_state *wait_state,
|
|
|
|
const struct timespec *partial_deadline)
|
|
|
|
const struct timespec *partial_deadline)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -276,7 +284,8 @@ static bool ck_ec32_wait_slow_once(const void *vstate,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CK_F_EC64
|
|
|
|
#ifdef CK_F_EC64
|
|
|
|
static bool ck_ec64_wait_slow_once(const void *vstate,
|
|
|
|
static bool
|
|
|
|
|
|
|
|
ck_ec64_wait_slow_once(const void *vstate,
|
|
|
|
const struct ck_ec_wait_state *wait_state,
|
|
|
|
const struct ck_ec_wait_state *wait_state,
|
|
|
|
const struct timespec *partial_deadline)
|
|
|
|
const struct timespec *partial_deadline)
|
|
|
|
{
|
|
|
|
{
|
|
|
@ -371,7 +380,8 @@ static bool ck_ec64_wait_slow_once(const void *vstate,
|
|
|
|
} \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
|
|
|
|
int ck_ec32_wait_pred_slow(struct ck_ec32 *ec,
|
|
|
|
int
|
|
|
|
|
|
|
|
ck_ec32_wait_pred_slow(struct ck_ec32 *ec,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
uint32_t old_value,
|
|
|
|
uint32_t old_value,
|
|
|
|
int (*pred)(const struct ck_ec_wait_state *state,
|
|
|
|
int (*pred)(const struct ck_ec_wait_state *state,
|
|
|
@ -391,7 +401,8 @@ int ck_ec32_wait_pred_slow(struct ck_ec32 *ec,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef CK_F_EC64
|
|
|
|
#ifdef CK_F_EC64
|
|
|
|
int ck_ec64_wait_pred_slow(struct ck_ec64 *ec,
|
|
|
|
int
|
|
|
|
|
|
|
|
ck_ec64_wait_pred_slow(struct ck_ec64 *ec,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
const struct ck_ec_ops *ops,
|
|
|
|
uint64_t old_value,
|
|
|
|
uint64_t old_value,
|
|
|
|
int (*pred)(const struct ck_ec_wait_state *state,
|
|
|
|
int (*pred)(const struct ck_ec_wait_state *state,
|
|
|
|