#define CHK_ST_OUT_ALLOC 0x0080 /* check blocked waiting for output buffer allocation */
#define CHK_ST_CLOSE_CONN 0x0100 /* check is waiting that the connection gets closed */
#define CHK_ST_PURGE 0x0200 /* check must be freed */
-#define CHK_ST_SLEEPING 0x0400 /* check was sleeping, i.e. not currently bound to a thread */
-#define CHK_ST_FASTINTER 0x0800 /* force fastinter check */
+#define CHK_ST_FASTINTER 0x0400 /* force fastinter check */
+#define CHK_ST_READY 0x0800 /* check ready to migrate or run, see below */
+#define CHK_ST_SLEEPING 0x1000 /* check was sleeping, i.e. not currently bound to a thread, see below */
+
+/* 4 possible states for CHK_ST_SLEEPING and CHK_ST_READY:
+ * SLP RDY State Description
+ * 0 0 - (reserved)
+ * 0 1 RUNNING Check is bound to current thread and running
+ * 1 0 SLEEPING Check is sleeping, not bound to a thread
+ * 1 1 MIGRATING Check is migrating to another thread
+ */
/* check status */
enum healthcheck_status {
* than half of the current thread's load, and if so we'll
* bounce the task there. It's possible because it's not yet
* tied to the current thread. The other thread will not bounce
- * the task again because we're removing CHK_ST_SLEEPING.
+ * the task again because we're setting CHK_ST_READY indicating
+ * a migration.
*/
uint my_load = HA_ATOMIC_LOAD(&th_ctx->rq_total);
- check->state &= ~CHK_ST_SLEEPING;
-
- if (my_load >= 2) {
+ if (!(check->state & CHK_ST_READY) && my_load >= 2) {
uint new_tid = statistical_prng_range(global.nbthread);
uint new_load = HA_ATOMIC_LOAD(&ha_thread_ctx[new_tid].rq_total);
* BUG_ON() as we're not allowed to call task_queue() for a
* foreign thread. The recipient will restore the expiration.
*/
+ check->state |= CHK_ST_READY;
task_unlink_wq(t);
t->expire = TICK_ETERNITY;
task_set_thread(t, new_tid);
/* OK we're keeping it so this check is ours now */
task_set_thread(t, tid);
+ check->state &= ~CHK_ST_SLEEPING;
+
+ /* OK let's run, now we cannot roll back anymore */
+ check->state |= CHK_ST_READY;
}
+ /* at this point, CHK_ST_SLEEPING = 0 and CHK_ST_READY = 1*/
+
if (check->server)
HA_SPIN_LOCK(SERVER_LOCK, &check->server->lock);
check_release_buf(check, &check->bi);
check_release_buf(check, &check->bo);
check->state &= ~(CHK_ST_INPROGRESS|CHK_ST_IN_ALLOC|CHK_ST_OUT_ALLOC);
+ check->state &= ~CHK_ST_READY;
check->state |= CHK_ST_SLEEPING;
update_timer: