Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

k_yield() exhibits different behavior with CONFIG_SMP #19381

Closed
ghost opened this issue Sep 25, 2019 · 4 comments
Closed

k_yield() exhibits different behavior with CONFIG_SMP #19381

ghost opened this issue Sep 25, 2019 · 4 comments
Assignees
Labels
area: Kernel area: SMP Symmetric multiprocessing bug The issue is a bug, or the PR is fixing a bug

Comments

@ghost
Copy link

ghost commented Sep 25, 2019

Using the latest master (currently 536e785).

The documentation for k_yield() says:

Yield the current thread. This routine causes the current thread to yield execution to another thread of the same or higher priority. If there are no other ready threads of the same or higher priority, the routine returns immediately.

... but the SMP scheduler (on a single-processor system) does not appear to yield control to other equal-priority threads.

Sample program:

#include <zephyr.h>
#include <sys/printk.h>

#define STACK_SIZE 8192

K_THREAD_STACK_DEFINE(stack0, STACK_SIZE);
K_THREAD_STACK_DEFINE(stack1, STACK_SIZE);
K_THREAD_STACK_DEFINE(stack2, STACK_SIZE);

void thread_func(void *p1, void *p2, void *p3)
{
	int num = POINTER_TO_INT(p1);

	k_busy_wait(500000 * num);

	for (;;) {
		k_busy_wait(1000000);
		printk("(%d)\n", num);
		k_yield();
	}
}

struct k_thread thread0;

struct k_thread thread1;
struct k_thread thread2;

void thread_func0(void *p1, void *p2, void *p3)
{
	k_thread_create(&thread1, stack1, STACK_SIZE, thread_func,
		INT_TO_POINTER(1), NULL, NULL, 0, 0, 0);

	k_thread_create(&thread2, stack2, STACK_SIZE, thread_func,
		INT_TO_POINTER(2), NULL, NULL, 0, 0, 0);
}

void main(void)
{
	k_thread_create(&thread0, stack0, STACK_SIZE, thread_func0,
		NULL, NULL, NULL, 0, 0, 0);
}

Basically, two threads are created of equal priority which busy-loop and print an identifying number periodically, yielding each time through the loop. (thread_func0 exists solely in case the main thread has a low priority.) With the old scheduler (CONFIG_SMP=n), this works as expected, with the two threads interleaving --

On a qemu_x86 target (CONFIG_SMP=n obviously):

SeaBIOS (version rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org)
Booting from ROM..Optimal CONFIG_X86_MMU_PAGE_POOL_PAGES 7
***** Booting Zephyr OS build v2.0.0-rc3-721-g536e785b932b *****
(1)
(2)
(1)
(2)
(1)
(2)

etc.

On a qemu_x86_64 target (CONFIG_SMP=n):

SeaBIOS (version rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org)
Booting from ROM..(1)
(2)
(1)
(2)

etc.

On a qemu_x86_64 target (CONFIG_SMP=y CONFIG_MP_NUM_CPUS=1):

SeaBIOS (version rel-1.12.1-0-ga5cab58e9a3f-prebuilt.qemu.org)
Booting from ROM..(1)
(1)
(1)
(1)
(1)

The second thread is never scheduled.

@ghost ghost added the bug The issue is a bug, or the PR is fixing a bug label Sep 25, 2019
@andyross
Copy link
Contributor

Did you get a chance to try over #19381?

@ghost
Copy link
Author

ghost commented Sep 25, 2019

Did you get a chance to try over #19381?

I clicked this link until my stack overflowed

@ghost
Copy link
Author

ghost commented Sep 25, 2019

a5ad00c in #18531 fixes this

@aescolar aescolar assigned ghost Sep 26, 2019
@aescolar aescolar added area: Kernel area: SMP Symmetric multiprocessing labels Sep 26, 2019
@aescolar aescolar assigned andyross and unassigned ghost Sep 26, 2019
@andyross
Copy link
Contributor

#18531 (pasted the correct link this time) is merged now, we can close this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Kernel area: SMP Symmetric multiprocessing bug The issue is a bug, or the PR is fixing a bug
Projects
None yet
Development

No branches or pull requests

2 participants