anchao commented on code in PR #20853:
URL: https://github.com/apache/nuttx/pull/20853#discussion_r4346430739
##########
sched/task/task_setup.c:
##########
@@ -614,16 +635,23 @@ int nxtask_setup_stackargs(FAR struct tcb_s *tcb,
for (i = 0; i < argc; i++)
{
/* Save the pointer to the location in the string buffer and
- * copy the argument into the buffer. Increment str to skip
- * over the argument and its NUL terminator in the string
- * buffer.
+ * copy the argument into the buffer. Use cached lengths for
+ * the common short argv case. For larger argv lists, stpcpy()
+ * still avoids the separate strlen() before copying and
+ * returns the address of the terminating NUL.
*/
stackargv[i + 1] = str;
- nbytes = strlen(argv[i]) + 1;
- strlcpy(str, argv[i], strtablen);
- str += nbytes;
- strtablen -= nbytes;
+ if (i < NXTASK_ARG_LEN_CACHE_SIZE)
+ {
+ nbytes = arglen[i];
+ memcpy(str, argv[i], nbytes);
+ str += nbytes;
+ }
+ else
+ {
+ str = stpcpy(str, argv[i]) + 1;
Review Comment:
The benefit is not just the generic C loop shape.
We already compute each string length during the sizing pass. Caching the
first few lengths lets the copy pass use memcpy() for the common small-argv
case instead of doing another terminator-driven copy.
memcpy() has a known size up front, so optimized implementations can use
word/vector/SIMD fast paths. stpcpy()/strlcpy() must keep checking for the
NUL terminator while copying, which is harder to optimize in the same way.
The cache is capped at 4 entries, so the stack cost is only 16 bytes on
32-bit or 32 bytes on 64-bit. Larger argv lists still fall back to stpcpy() to
avoid a CONFIG_TASK_MAX_ARGS-sized stack array.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]