-
Notifications
You must be signed in to change notification settings - Fork 7.4k
libc: minimal: add qsort to the minimal libc #39980
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
libc: minimal: add qsort to the minimal libc #39980
Conversation
ced3f83
to
fd695ea
Compare
d32902a
to
84b1072
Compare
6bbb75f
to
cceb454
Compare
Since this is a standard C library function that is missing from the minimal C library, I would almost consider it a bug that it is not present. Would make a lot of sense, IMHO, to add this to LTS in the v2.7-branch, as it does not break any API (and actually improves API consistence), and fixes several issues where it has been mentioned as lacking. I would be happy to present it to the TSC and / or CRB. |
From what I've gathered, there have been a few separate issues that have called for it
Agreed - it would be ideal if we used a single libc that would satisfy most requirements, but it's also nice to have some consistence. Would it make more sense to just use Heapsort in this case? That's easily maintainable and should meet the requirements of most use cases (with the exception that it is not stable). I added the choice so that users could choose to use the bsd qsort that was under
Yes, agreed as well. |
cceb454
to
01bf33c
Compare
01bf33c
to
0a2ced3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor comments
4dd889c
to
81d1d38
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have:
/*
* Normally parent is defined parent(k) = floor((k-1) / 2) but we can avoid a
* divide by noticing that floor((k-1) / 2) = (k >> 1).
*/
#define parent(k) ((k) >> 1)
Here I can't ignore the fact that floor((k-1) / 2)
is not equal to
(k >> 1)
. If used with 4, the former gives 1 while the later gives 2.
Then:
/*
* Normally left is defined left(k) = (2 * k + 1) but we can avoid a
* multiply by noticing that (2 * k + 1) = ((k << 1) + 1).
*/
#define left(k) (((k) << 1) + 1)
The +1 in the macro does match the comment, but it doesn't match its
parent()
counterpart defined above. Incideltally, removing that +1 doesn't
appear to affect the algorithm, at least as far as the test suite is concerned.
Might be worth verifying the theory if that +1 could indeed be removed which
would 1) make the code coherent and 2) reduce the generated binary slightly.
And finally:
/*
* Normally right is defined right(k) = (2 * (k) + 2) but we can avoid a
* multiply by noticing that right(k) = left(k) + 1 = child + 1.
*/
#define right(root) (child + 1)
Here I really suggest you stick to left(k) + 1
. It is very counter-intuitive
to have the macro argument being ignored in favor of some arbitrary variable.
And I bet the generated code will be the same anyway, or just as efficient.
Good catch. Was editing slightly too hastily. It should be
Good suggestion - thanks 😊 |
81d1d38
to
3ed54e3
Compare
This change implements qsort() for the minimal libc via Heapsort. Heapsort time complexity is O(n log(n)) in the best, average, and worst cases. It is O(1) in space complexity (i.e. sorts in-place) and is iterative rather than recursive. Heapsort is not stable (i.e. does not preserve order of identical elements). On cortex-m0, this implementation occupies ~240 bytes. Fixes zephyrproject-rtos#28896 Signed-off-by: Christopher Friedt <[email protected]>
This change adds tests for qsort(). Signed-off-by: Christopher Friedt <[email protected]>
3ed54e3
to
3563a01
Compare
PR zephyrproject-rtos#39980 added qsort to minimal libc but caused shell_modules sample to fail building. Signed-off-by: Sylvio Alves <[email protected]>
PR #39980 added qsort to minimal libc but caused shell_modules sample to fail building. Signed-off-by: Sylvio Alves <[email protected]>
PR #39980 added qsort to minimal libc but caused shell_modules sample to fail building. Signed-off-by: Sylvio Alves <[email protected]>
PR #39980 added qsort to minimal libc but caused shell_modules sample to fail building. Signed-off-by: Sylvio Alves <[email protected]>
This change implements qsort() for the minimal libc via Heapsort.
Heapsort time complexity is O(n log(n)) in the best, average, and worst cases. It is O(1) in space complexity (i.e. sorts in-place) and is iterative rather than recursive. Heapsort is not stable (i.e. does not preserve order of identical elements).
On cortex-m0, this implementation occupies ~240 bytes.
Fixes #28896