kernel: add new work queue implementation

This commit provides a complete reimplementation of the work queue
infrastructure intended to eliminate the race conditions and feature
gaps in the existing implementation.

Both bare and delayable work structures are supported.  Items can be
submitted; delayable items can be scheduled for submission at a future
time.  Items can be delayed, queued, and running all at the same time.
A running item can also be canceling.

The new implementation:
* replaces "pending" with "busy" which identifies the active states;
* supports canceling delayed and submitted items;
* prevents resubmission of a item being canceled until cancellation
  completes;
* supports waiting for cancellation to complete;
* supports flushing a work item (waiting for the last submission to
  complete without preventing resubmission);
* supports waiting for a queue to drain (only allows resubmission from
  the work thread);
* supports stopping a work queue in conjunction with draining it;
* prevents handler-reentrancy during resubmission.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
diff --git a/kernel/system_work_q.c b/kernel/system_work_q.c
index 46fd1b0..496fbbe 100644
--- a/kernel/system_work_q.c
+++ b/kernel/system_work_q.c
@@ -14,19 +14,31 @@
 #include <kernel.h>
 #include <init.h>
 
-K_KERNEL_STACK_DEFINE(sys_work_q_stack, CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE);
+static K_KERNEL_STACK_DEFINE(sys_work_q_stack,
+			     CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE);
 
 struct k_work_q k_sys_work_q;
 
 static int k_sys_work_q_init(const struct device *dev)
 {
 	ARG_UNUSED(dev);
+	struct k_work_queue_config cfg = {
+		.name = "sysworkq",
+		.no_yield = IS_ENABLED(CONFIG_SYSTEM_WORKQUEUE_NO_YIELD),
+	};
 
+#ifdef CONFIG_KERNEL_WORK1
 	k_work_q_start(&k_sys_work_q,
 		       sys_work_q_stack,
 		       K_KERNEL_STACK_SIZEOF(sys_work_q_stack),
 		       CONFIG_SYSTEM_WORKQUEUE_PRIORITY);
 	k_thread_name_set(&k_sys_work_q.thread, "sysworkq");
+#else /* CONFIG_KERNEL_WORK1 */
+	k_work_queue_start(&k_sys_work_q,
+			    sys_work_q_stack,
+			    K_KERNEL_STACK_SIZEOF(sys_work_q_stack),
+			    CONFIG_SYSTEM_WORKQUEUE_PRIORITY, &cfg);
+#endif /* CONFIG_KERNEL_WORK1 */
 
 	return 0;
 }