[svn-commits] sruffell: branch linux/sruffell/wctdm24xxp-cmdlist r9864 - /linux/team/sruffe...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Mar 16 16:41:08 CDT 2011


Author: sruffell
Date: Wed Mar 16 16:41:04 2011
New Revision: 9864

URL: http://svnview.digium.com/svn/dahdi?view=rev&rev=9864
Log:
wctdm24xxp: Introduce bg_create/bg_join.

Since there are several operations on the wctdm24xxp driver during
initialization that can take a significant amount of time, but which can run
in parallel with other operations, this adds a generic facility for creating
those tasks and waiting for the results.

This will be used to identify and configure the modules in parallel.

Signed-off-by: Shaun Ruffell <sruffell at digium.com>

Modified:
    linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c

Modified: linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c
URL: http://svnview.digium.com/svn/dahdi/linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c?view=diff&rev=9864&r1=9863&r2=9864
==============================================================================
--- linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c (original)
+++ linux/team/sruffell/wctdm24xxp-cmdlist/drivers/dahdi/wctdm24xxp/base.c Wed Mar 16 16:41:04 2011
@@ -295,6 +295,101 @@
 static inline __attribute_const__ int VPM_CMD_BYTE(int timeslot, int bit)
 {
 	return ((((timeslot) & 0x3) * 3 + (bit)) * 7) + ((timeslot) >> 2);
+}
+
+typedef int (*bg_work_func_t)(struct wctdm *wc, unsigned long data);
+
+struct bg {
+	struct workqueue_struct *wq;
+	struct work_struct	work;
+	struct completion	complete;
+	struct wctdm		*wc;
+	bg_work_func_t		fn;
+	unsigned long		param;
+	int			ret;
+};
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+static void bg_work_func(void *data)
+{
+	struct bg *bg = data;
+#else
+static void bg_work_func(struct work_struct *work)
+{
+	struct bg *bg = container_of(work, struct bg, work);
+#endif
+	bg->ret = bg->fn(bg->wc, bg->param);
+	complete(&bg->complete);
+}
+
+/**
+ * bg_create - Call a function running in a background thread.
+ * @wc:		The board structure passed to fn
+ * @fn:		The function to run in it's own thread.
+ * @parma:	An extra parameter to pass to the fn.
+ *
+ * Returns NULL if the thread could not be created, otherwise a pointer to be
+ * passed to bg_join in order to get the return value.
+ *
+ * The function 'fn' will be run in a new thread. The return value is the
+ * return from the bg_join function.
+ *
+ * This would probably be best served by concurrency managed workqueues before
+ * merging, but this will at least work on the older kernels tht DAHDI
+ * supports.
+ */
+static struct bg *
+bg_create(struct wctdm *wc, bg_work_func_t fn, unsigned long param)
+{
+	struct bg *bg;
+
+	bg = kzalloc(sizeof(*bg), GFP_KERNEL);
+	if (!bg)
+		return NULL;
+
+	bg->wq = create_singlethread_workqueue("wctdm_bg");
+	if (!bg->wq) {
+		kfree(bg);
+		return NULL;
+	}
+
+	init_completion(&bg->complete);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
+	INIT_WORK(&bg->work, bg_work_func, bg);
+#else
+	INIT_WORK(&bg->work, bg_work_func);
+#endif
+
+	bg->wc = wc;
+	bg->fn = fn;
+	bg->param = param;
+
+	queue_work(bg->wq, &bg->work);
+
+	return bg;
+}
+
+/**
+ * bg_join - Wait for a background function to complete and get the result.
+ * @bg:		Pointer returned from the bg_create call.
+ *
+ * Returns the result of the function passed to bg_create.
+ */
+static int bg_join(struct bg *bg)
+{
+	int ret = -ERESTARTSYS;
+
+	if (unlikely(!bg))
+		return -EINVAL;
+
+	while (ret)
+		ret = wait_for_completion_interruptible(&bg->complete);
+
+	ret = bg->ret;
+	destroy_workqueue(bg->wq);
+	kfree(bg);
+
+	return ret;
 }
 
 static void




More information about the svn-commits mailing list