xiaoxiang781216 opened a new pull request, #19870:
URL: https://github.com/apache/nuttx/pull/19870
## Summary
Speed up the BSD (newlib derived) string/memory routines in
`libs/libc/string`
and fix three bugs found while doing so.
1. **`libs/libc/string: Use long long to speed up the BSD string
functions.`**
Most hardware accesses memory through a 64-bit bus, so the word at a time
loops now work on `libc_data_t` (`unsigned long long`) instead of `long`,
which is only 32-bit wide on the 32-bit platforms. The duplicated
`UNALIGNED`/`ALIGNED`/`LITTLEBLOCKSIZE`/`TOO_SMALL`/`DETECTNULL` macros
and
the `LONG_MAX` conditionals are removed from the individual C files and
moved to `libs/libc/libc.h` (net -208 lines).
2. **`libs/libc/string: Fix the address calculation in memrchr fast path.`**
The address restoration after the alignment loop was wrong and made
`memrchr()` return the wrong position, which showed up as corrupted syslog
messages.
3. **`libs/libc/string: Fix asrc alignment for unaligned access in
memrchr.`**
`memrchr()` scans backward, so it must align `src0 + 1` (as the original
private `UNALIGNED()` macro did) rather than `src0`.
4. **`libs/libc/string: Fix sign extension in memset word fill pattern.`**
`memset(p, 0x80, n)` filled the wrong bytes because `c` was sign extended
before the word sized pattern was built. C11 7.24.6.1 requires `c` to be
converted to `unsigned char` first. Fixes both `lib_memset.c` and
`lib_bsdmemset.c`.
5. **`libs/libc/string: Add 4-byte alignment middle path for BSD
functions.`**
With an 8-byte `libc_data_t`, a buffer that is 4-byte but not 8-byte
aligned falls back to the byte at a time loop. A 32-bit middle path
(`DETECTNULL32`, `UNALIGNED4`, `LITTLEBLOCKSIZE4`, ...) keeps four bytes
per iteration for `memccpy`, `memcmp`, `memcpy`, `memset`, `stpcpy`,
`stpncpy`, `strcmp`, `strcpy`, `strncmp` and `strncpy`.
## Impact
* Is new feature added? No.
* Impact on user: None. The public API and the behaviour of the affected
functions are unchanged; `memrchr()` and `memset()` now behave correctly
for
the cases described above.
* Impact on build: None. Only `libs/libc/libc.h` and `libs/libc/string/*.c`
are
touched; no new configuration option is introduced. The optimized path is
still selected by the existing `CONFIG_LIBC_NEWLIB_OPTSPEED`
(`lib_memset.c` change applies to every configuration).
* Impact on hardware: None, all architectures benefit equally.
* Impact on documentation: None.
* Impact on security: `memset()` with a fill byte >= 0x80 previously wrote
the
wrong pattern, e.g. when scrubbing a buffer; this is now correct.
* Impact on compatibility: None.
## Testing
Build and run host: Ubuntu x86_64
Target: `sim:nsh` with `CONFIG_ALLOW_BSD_COMPONENTS=y`,
`CONFIG_LIBC_NEWLIB_OPTSPEED=y`, `CONFIG_TESTING_ARCH_LIBC=y` (all
sub-tests),
`CONFIG_TESTING_OSTEST=y`.
Every commit of this series builds and runs standalone.
### `arch_libctest` (apps/testing/libc/arch_libc) at the tip of the series
```
nsh> arch_libctest
Testing memcpy...
memcpy: PASSED
memcpy(128) avg cycles: 13
Testing memmove...
memmove: PASSED
memmove(128) avg cycles: 3
Testing memset...
memset: PASSED
memset(128) avg cycles: 56
Testing memcmp...
memcmp: PASSED
memcmp(128) avg cycles: 17
Testing memchr...
memchr: PASSED
memchr(128) avg cycles: 10
Testing strlen...
strlen: PASSED
strlen(128) avg cycles: 10
Testing strcmp...
strcmp: PASSED
strcmp(128) avg cycles: 16
Testing strcpy...
strcpy: PASSED
strcpy(128) avg cycles: 16
Testing strchr...
strchr: PASSED
strchr(128) avg cycles: 16
Testing strncmp...
strncmp: PASSED
strncmp(128) avg cycles: 21
Testing strnlen...
strnlen: PASSED
strnlen(128) avg cycles: 74
Testing strncpy...
strncpy: PASSED
strncpy(128) avg cycles: 20
Testing stpcpy...
stpcpy: PASSED
stpcpy(128) avg cycles: 15
Testing strcat...
strcat: PASSED
strcat(64) avg cycles: 11
Testing strrchr...
strrchr: PASSED
strrchr(128) avg cycles: 63
Testing strchrnul...
strchrnul: PASSED
strchrnul(128) avg cycles: 13
arch_libc_test Passed
```
16/16 PASSED, 0 FAILED.
### Per commit check (CONTRIBUTING 1.7.5)
Each commit was checked out on its own, rebuilt and run:
```
[1] BUILD_OK PASSED=16 FAILED=0 libs/libc/string: Use long long to speed
up the BSD string functions.
[2] BUILD_OK PASSED=16 FAILED=0 libs/libc/string: Fix the address
calculation in memrchr fast path.
[3] BUILD_OK PASSED=16 FAILED=0 libs/libc/string: Fix asrc alignment for
unaligned access in memrchr.
[4] BUILD_OK PASSED=16 FAILED=0 libs/libc/string: Fix sign extension in
memset word fill pattern.
[5] BUILD_OK PASSED=16 FAILED=0 libs/libc/string: Add 4-byte alignment
middle path for BSD functions.
```
### `ostest`
```
NuttShell (NSH) NuttX-10.4.0
nsh> ostest
stdio_test: write fd=1
stdio_test: Standard I/O Check: printf
stdio_test: write fd=2
...
Final memory usage:
VARIABLE BEFORE AFTER
======== ======== ========
arena 4000000 4000000
ordblks 2 6
mxordblk 3e19888 3e19888
uordblks 1d76b8 1d7840
fordblks 3e28948 3e287c0
user_main: Exiting
ostest_main: Exiting with status 0
```
No failure and no memory leak (`uordblks` back to the pre-test value).
### Style
```
$ ./tools/checkpatch.sh -c -u -m -g apache/master..HEAD
✔️ All checks pass.
```
--
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]