[PATCH 1/3] bthread: remove thread exit codes

Ahmad Fatoum a.fatoum at pengutronix.de
Mon Jun 28 00:07:30 PDT 2021


Follow-up commit will replace blocking bthread_stop with non-blocking
bthread_cancel. Prepare for this by dropping exit codes. This is not
much of a loss, because most users of bthreads will only call
bthread_stop at cleanup time. bthread command is an exception, so have
it take manual care of passing around exit codes.

As we touch the bthread_stop prototype anyway, rename it to
__bthread_stop. This will make it clearer in the future, that it's not
meant for driver use.

Signed-off-by: Ahmad Fatoum <a.fatoum at pengutronix.de>
---
 commands/bthread.c                  | 48 ++++++++++++++++++-----------
 common/bthread.c                    | 20 ++++++------
 drivers/usb/gadget/f_mass_storage.c | 12 +++-----
 include/bthread.h                   |  5 +--
 4 files changed, 47 insertions(+), 38 deletions(-)

diff --git a/commands/bthread.c b/commands/bthread.c
index 0c9c221884e8..446fe9c37ac3 100644
--- a/commands/bthread.c
+++ b/commands/bthread.c
@@ -33,12 +33,10 @@ static int bthread_time(void)
 	return i;
 }
 
-static int bthread_infinite(void *data)
+static void bthread_infinite(void *data)
 {
 	while (!bthread_should_stop())
 		;
-
-	return 0;
 }
 
 static int bthread_isolated_time(void)
@@ -62,14 +60,20 @@ static int bthread_isolated_time(void)
 		i += 2;
 	}
 
-	bthread_stop(bthread);
+	__bthread_stop(bthread);
 	bthread_free(bthread);
 
 	return i;
 }
 
-static int bthread_printer(void *arg)
+struct arg {
+	unsigned long in;
+	long out;
+};
+
+static void bthread_printer(void *_arg)
 {
+	struct arg *arg = _arg;
 	volatile u64 start;
 	volatile unsigned long i = 0;
 	start = get_time_ns();
@@ -78,28 +82,30 @@ static int bthread_printer(void *arg)
 		if (!is_timeout_non_interruptible(start, 225 * MSECOND))
 			continue;
 
-		if ((unsigned long)arg == i++)
+		if (arg->in == i++)
 			printf("%s yield #%lu\n", bthread_name(current), i);
 		start = get_time_ns();
 	}
 
-	return i;
+	arg->out = i;
 }
 
 static int yields;
 
-static int bthread_spawner(void *arg)
+static void bthread_spawner(void *_spawner_arg)
 {
+	struct arg *arg, *spawner_arg = _spawner_arg;
 	struct bthread *bthread[4];
 	volatile u64 start;
 	volatile unsigned long i = 0;
 	int ret = 0;
-	int ecode;
 
 	start = get_time_ns();
 
 	for (i = 0; i < ARRAY_SIZE(bthread); i++) {
-		bthread[i] = bthread_run(bthread_printer, (void *)(long)i,
+		arg = malloc(sizeof(*arg));
+		arg->in = i;
+		bthread[i] = bthread_run(bthread_printer, arg,
 					 "%s-bthread%u", bthread_name(current), i+1);
 		if (!bthread[i]) {
 			ret = -ENOMEM;
@@ -112,14 +118,16 @@ static int bthread_spawner(void *arg)
 
 cleanup:
 	while (i--) {
-		ecode = bthread_stop(bthread[i]);
+		arg = bthread_data(bthread[i]);
+		__bthread_stop(bthread[i]);
 		bthread_free(bthread[i]);
 
-		if (!ret && (ecode != 4 || yields < ecode))
+		if (!ret && (arg->out != 4 || yields < arg->out))
 			ret = -EIO;
+		free(arg);
 	}
 
-	return ret;
+	spawner_arg->out = ret;
 }
 
 struct spawn {
@@ -132,8 +140,9 @@ static int do_bthread(int argc, char *argv[])
 	LIST_HEAD(spawners);
 	struct spawn *spawner, *tmp;
 	int ret = 0;
-	int ecode, opt, i = 0;
+	int opt, i = 0;
 	bool time = false;
+	struct arg *arg;
 
 	while ((opt = getopt(argc, argv, "itcv")) > 0) {
 		switch (opt) {
@@ -146,7 +155,8 @@ static int do_bthread(int argc, char *argv[])
 			break;
 		case 'v':
 			spawner = xzalloc(sizeof(*spawner));
-			spawner->bthread = bthread_run(bthread_spawner, NULL,
+			arg = malloc(sizeof(*arg));
+			spawner->bthread = bthread_run(bthread_spawner, arg,
 						       "spawner%u", ++i);
 			if (!spawner->bthread) {
 				free(spawner);
@@ -172,10 +182,12 @@ static int do_bthread(int argc, char *argv[])
 
 cleanup:
 	list_for_each_entry_safe(spawner, tmp, &spawners, list) {
-		ecode = bthread_stop(spawner->bthread);
+		arg = bthread_data(spawner->bthread);
+		__bthread_stop(spawner->bthread);
 		bthread_free(spawner->bthread);
-		if (!ret && ecode)
-			ret = ecode;
+		if (!ret && arg->out)
+			ret = arg->out;
+		free(arg);
 		free(spawner);
 	}
 
diff --git a/common/bthread.c b/common/bthread.c
index 80651344da64..48248dfad41a 100644
--- a/common/bthread.c
+++ b/common/bthread.c
@@ -20,11 +20,8 @@
 #endif
 
 static struct bthread {
-	int (*threadfn)(void *);
-	union {
-		void *data;
-		int ret;
-	};
+	void (*threadfn)(void *);
+	void *data;
 	char *name;
 	jmp_buf jmp_buf;
 	void *stack;
@@ -54,7 +51,7 @@ static void __noreturn bthread_trampoline(void)
 	finish_switch_fiber(current);
 	bthread_reschedule();
 
-	current->ret = current->threadfn(current->data);
+	current->threadfn(current->data);
 
 	bthread_suspend(current);
 	current->has_stopped = true;
@@ -81,7 +78,7 @@ const char *bthread_name(struct bthread *bthread)
 	return bthread->name;
 }
 
-struct bthread *bthread_create(int (*threadfn)(void *), void *data,
+struct bthread *bthread_create(void (*threadfn)(void *), void *data,
 			       const char *namefmt, ...)
 {
 	struct bthread *bthread;
@@ -117,6 +114,11 @@ err:
 	return NULL;
 }
 
+void *bthread_data(struct bthread *bthread)
+{
+	return bthread->data;
+}
+
 void bthread_wake(struct bthread *bthread)
 {
 	if (bthread->awake)
@@ -133,14 +135,12 @@ void bthread_suspend(struct bthread *bthread)
 	list_del(&bthread->list);
 }
 
-int bthread_stop(struct bthread *bthread)
+void __bthread_stop(struct bthread *bthread)
 {
 	bthread->should_stop = true;
 
 	while (!bthread->has_stopped)
 		bthread_reschedule();
-
-	return bthread->ret;
 }
 
 int bthread_should_stop(void)
diff --git a/drivers/usb/gadget/f_mass_storage.c b/drivers/usb/gadget/f_mass_storage.c
index 4894f91fa6ef..0033a95f68f3 100644
--- a/drivers/usb/gadget/f_mass_storage.c
+++ b/drivers/usb/gadget/f_mass_storage.c
@@ -2335,7 +2335,7 @@ static void handle_exception(struct fsg_common *common)
 
 /*-------------------------------------------------------------------------*/
 
-static int fsg_main_thread(void *common_)
+static void fsg_main_thread(void *common_)
 {
 	struct fsg_common	*common = common_;
 	int ret = 0;
@@ -2374,12 +2374,8 @@ static int fsg_main_thread(void *common_)
 			common->state = FSG_STATE_IDLE;
 	}
 
-	if (ret && ret != -ERESTARTSYS) {
+	if (ret && ret != -ERESTARTSYS)
 		pr_warn("%s: error %pe\n", __func__, ERR_PTR(ret));
-		return ret;
-	}
-
-	return 0;
 }
 
 static void fsg_common_release(struct fsg_common *common);
@@ -2541,7 +2537,7 @@ static void fsg_common_release(struct fsg_common *common)
 	/* If the thread isn't already dead, tell it to exit now */
 	if (common->state != FSG_STATE_TERMINATED) {
 		raise_exception(common, FSG_STATE_EXIT);
-		bthread_stop(thread_task);
+		__bthread_stop(thread_task);
 		bthread_free(thread_task);
 	}
 
@@ -2568,7 +2564,7 @@ static void fsg_unbind(struct usb_configuration *c, struct usb_function *f)
 		fsg->common->new_fsg = NULL;
 		raise_exception(fsg->common, FSG_STATE_CONFIG_CHANGE);
 
-		bthread_stop(thread_task);
+		__bthread_stop(thread_task);
 		while (common->fsg == fsg)
 			bthread_reschedule();
 	}
diff --git a/include/bthread.h b/include/bthread.h
index e3871fb11555..407aa830a835 100644
--- a/include/bthread.h
+++ b/include/bthread.h
@@ -12,14 +12,15 @@ struct bthread;
 
 extern struct bthread *current;
 
-struct bthread *bthread_create(int (*threadfn)(void *), void *data, const char *namefmt, ...);
+struct bthread *bthread_create(void (*threadfn)(void *), void *data, const char *namefmt, ...);
 void bthread_free(struct bthread *bthread);
 
 void bthread_schedule(struct bthread *);
 void bthread_wake(struct bthread *bthread);
 void bthread_suspend(struct bthread *bthread);
 int bthread_should_stop(void);
-int bthread_stop(struct bthread *bthread);
+void __bthread_stop(struct bthread *bthread);
+void *bthread_data(struct bthread *bthread);
 void bthread_info(void);
 const char *bthread_name(struct bthread *bthread);
 bool bthread_is_main(struct bthread *bthread);
-- 
2.30.2




More information about the barebox mailing list