summaryrefslogtreecommitdiff
path: root/nuttx/lib/string
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-21 00:41:44 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2012-10-21 00:41:44 +0000
commitb007f9897061c921e685d3970035228f21a2e506 (patch)
tree35873755480bfc436875406748f17798082c333e /nuttx/lib/string
parentde7e070e684796f52cf5b4466e7b16755a3a92c8 (diff)
downloadpx4-nuttx-b007f9897061c921e685d3970035228f21a2e506.tar.gz
px4-nuttx-b007f9897061c921e685d3970035228f21a2e506.tar.bz2
px4-nuttx-b007f9897061c921e685d3970035228f21a2e506.zip
Add a versin of memset() optimized for speed
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@5242 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/lib/string')
-rw-r--r--nuttx/lib/string/lib_memset.c84
1 files changed, 84 insertions, 0 deletions
diff --git a/nuttx/lib/string/lib_memset.c b/nuttx/lib/string/lib_memset.c
index 916351b97..c910d2ce0 100644
--- a/nuttx/lib/string/lib_memset.c
+++ b/nuttx/lib/string/lib_memset.c
@@ -42,8 +42,12 @@
************************************************************/
#include <nuttx/config.h>
+
#include <sys/types.h>
+
+#include <stdint.h>
#include <string.h>
+#include <assert.h>
/************************************************************
* Global Functions
@@ -52,8 +56,88 @@
#ifndef CONFIG_ARCH_MEMSET
void *memset(void *s, int c, size_t n)
{
+#ifdef CONFIG_MEMSET_OPTSPEED
+ /* This version is optimized for speed (you could do better
+ * still by exploiting processor caching or memory burst
+ * knowledge. 64-bit support might improve performance as
+ * well.
+ */
+
+ uintptr_t addr = (uintptr_t)s;
+ uint16_t val16 = ((uint16_t)c << 8) | (uint16_t)c;
+ uint32_t val32 = ((uint32_t)val16 << 16) | (uint32_t)val16;
+
+ /* Make sure that there is something to be cleared */
+
+ if (n > 0)
+ {
+ /* Align to a 16-bit boundary */
+
+ if ((addr & 1) != 0)
+ {
+ *(uint8_t*)addr = (uint8_t)c;
+ addr += 1;
+ n -= 1;
+ }
+
+ /* Check if there are at least 16-bits left to be zeroed */
+
+ if (n >= 2)
+ {
+ /* Align to a 32-bit boundary (we know that the destination
+ * address is already aligned to at least a 16-bit boundary).
+ */
+
+ if ((addr & 3) != 0)
+ {
+ *(uint16_t*)addr = val16;
+ addr += 2;
+ n -= 2;
+ }
+
+ /* Loop while there are at least 32-bits left to be zeroed */
+
+ while (n >= 4)
+ {
+ *(uint32_t*)addr = val32;
+ addr += 4;
+ n -= 4;
+ }
+ }
+
+ /* We may get here under the following conditions:
+ *
+ * n = 0, addr may or may not be aligned
+ * n = 1, addr may or may not be aligned
+ * n = 2, addr is aligned to a 32-bit boundary
+ * n = 3, addr is aligned to a 32-bit boundary
+ */
+
+ switch (n)
+ {
+ default:
+ case 0:
+ DEBUGASSERT(n == 0);
+ break;
+
+ case 2:
+ *(uint16_t*)addr = val16;
+ break;
+
+ case 3:
+ *(uint16_t*)addr = val16;
+ addr += 2;
+ case 1:
+ *(uint8_t*)addr = (uint8_t)c;
+ break;
+ }
+ }
+#else
+ /* This version is optimized for size */
+
unsigned char *p = (unsigned char*)s;
while (n-- > 0) *p++ = c;
+#endif
return s;
}
#endif