MINOR: connection: align toremove_{lock,connections} and cleanup into idle_conns

We used to have 3 thread-based arrays for toremove_lock, idle_cleanup,
and toremove_connections. The problem is that these items are small,
and that this creates false sharing between threads since it's possible
to pack up to 8-16 of these values into a single cache line. This can
cause real damage where there is contention on the lock.

This patch creates a new array of struct "idle_conns" that is aligned
on a cache line and which contains all three members above. This way
each thread has access to its variables without hindering the other
ones. Just doing this increased the HTTP/1 request rate by 5% on a
16-thread machine.

The definition was moved to connection.{c,h} since it appeared a more
natural evolution of the ongoing changes given that there was already
one of them declared in connection.h previously.
diff --git a/src/mux_h2.c b/src/mux_h2.c
index bec6af0..c6634c5 100644
--- a/src/mux_h2.c
+++ b/src/mux_h2.c
@@ -3524,13 +3524,13 @@
 	int ret = 0;
 
 
-	HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
+	HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 	if (t->context == NULL) {
 		/* The connection has been taken over by another thread,
 		 * we're no longer responsible for it, so just free the
 		 * tasklet, and do nothing.
 		 */
-		HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
+		HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 		tasklet_free(tl);
 		goto leave;
 	}
@@ -3547,7 +3547,7 @@
 	if (conn_in_list)
 		MT_LIST_DEL(&conn->list);
 
-	HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
+	HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 
 	if (!(h2c->wait_event.events & SUB_RETRY_SEND))
 		ret = h2_send(h2c);
@@ -3643,15 +3643,15 @@
 		}
 
 		/* connections in error must be removed from the idle lists */
-		HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
+		HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 		MT_LIST_DEL((struct mt_list *)&conn->list);
-		HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
+		HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 	}
 	else if (h2c->st0 == H2_CS_ERROR) {
 		/* connections in error must be removed from the idle lists */
-		HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
+		HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 		MT_LIST_DEL((struct mt_list *)&conn->list);
-		HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
+		HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 	}
 
 	if (!b_data(&h2c->dbuf))
@@ -3721,7 +3721,7 @@
 	/* We're about to destroy the connection, so make sure nobody attempts
 	 * to steal it from us.
 	 */
-	HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
+	HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 
 	if (h2c && h2c->conn->flags & CO_FL_LIST_MASK)
 		MT_LIST_DEL(&h2c->conn->list);
@@ -3732,7 +3732,7 @@
 	if (!t->context)
 		h2c = NULL;
 
-	HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
+	HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 
 	task_destroy(t);
 
@@ -3778,9 +3778,9 @@
 	}
 
 	/* in any case this connection must not be considered idle anymore */
-	HA_SPIN_LOCK(OTHER_LOCK, &toremove_lock[tid]);
+	HA_SPIN_LOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 	MT_LIST_DEL((struct mt_list *)&h2c->conn->list);
-	HA_SPIN_UNLOCK(OTHER_LOCK, &toremove_lock[tid]);
+	HA_SPIN_UNLOCK(OTHER_LOCK, &idle_conns[tid].toremove_lock);
 
 	/* either we can release everything now or it will be done later once
 	 * the last stream closes.