Ver Fonte

Add a memset function

tangyuxin há 2 anos atrás
pai
commit
45a3fb27bb
4 ficheiros alterados com 99 adições e 2 exclusões
  1. 2 1
      include/cb_libc.h
  2. 1 1
      src/libc/cb_memcpy.c
  3. 66 0
      src/libc/cb_memset.c
  4. 30 0
      test/cb_memset_test.cpp

+ 2 - 1
include/cb_libc.h

@@ -15,7 +15,8 @@ extern "C" {
 
 /* string */
 long cb_strcmp(const char* s1, const char* s2);
-void* cb_memcpy(void* dst, const void* src, unsigned int count);
+void* cb_memcpy(void* dst, const void* src, unsigned long count);
+void* cb_memset(void* dst, int c, unsigned long count);
 
 /* stdlib */
 void cb_srandom(unsigned int seed);

+ 1 - 1
src/libc/cb_memcpy.c

@@ -8,7 +8,7 @@
 
 #include "cb_libc.h"
 
-void* cb_memcpy(void* dst, const void* src, unsigned int count)
+void* cb_memcpy(void* dst, const void* src, unsigned long count)
 {
     char* dst_ptr = (char *)dst;
     char* src_ptr = (char *)src;

+ 66 - 0
src/libc/cb_memset.c

@@ -0,0 +1,66 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-10-14     tyx          first implementation
+ */
+
+#include "cb_libc.h"
+#include "cb_def.h"
+
+void* cb_memset(void* dst, int c, unsigned long count)
+{
+    unsigned char* dst_ptr = dst;
+    unsigned char* zero = cb_null;
+    unsigned char v = c & 0xFFU;
+    unsigned long lv = v, i;
+
+    for (i = 1; i < sizeof(unsigned long); i = i << 1)
+    {
+        lv = lv + (lv << (8 * i));
+    }
+
+    if (count > (sizeof(unsigned long) << 2))
+    {
+        if (((dst_ptr - zero) & (sizeof(void *) - 1)) == 0)
+        {
+            unsigned long *aligned_dst = (unsigned long*)dst_ptr;
+
+            /* Copy 4X long words at a time if possible. */
+            while (count >= (sizeof(unsigned long) << 2))
+            {
+                *aligned_dst++ = lv;
+                *aligned_dst++ = lv;
+                *aligned_dst++ = lv;
+                *aligned_dst++ = lv;
+                count -= (sizeof(unsigned long) << 2);
+            }
+            /* Copy one long word at a time if possible. */
+            while (count >= sizeof(unsigned long))
+            {
+                *aligned_dst++ = lv;
+                count -= sizeof(unsigned long);
+            }
+            /* Pick up any residual with a byte copier. */
+            dst_ptr = (unsigned char*)aligned_dst;
+        }
+    }
+    while (count >= (sizeof(unsigned char) << 3))
+    {
+        *dst_ptr++ = v;
+        *dst_ptr++ = v;
+        *dst_ptr++ = v;
+        *dst_ptr++ = v;
+        *dst_ptr++ = v;
+        *dst_ptr++ = v;
+        *dst_ptr++ = v;
+        *dst_ptr++ = v;
+        count -= (sizeof(char) << 3);
+    }
+    while (count--)
+    {
+        *dst_ptr++ = v;
+    }
+    return dst;
+}

+ 30 - 0
test/cb_memset_test.cpp

@@ -0,0 +1,30 @@
+/*
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2023-10-15     tyx          first implementation
+ */
+
+#include <string.h>
+#include <gtest/gtest.h>
+#include "cb_libc.h"
+
+TEST(testCase, cb_memset_test01)
+{
+    unsigned char buf_test[32];
+    unsigned char buf_cmp[sizeof(buf_test)];
+    unsigned long pos, len;
+
+    for (len = 0; len < sizeof(buf_test); len++)
+    {
+        for (pos = 0; pos < len; pos++)
+        {
+            memset(buf_test, '#', sizeof(buf_test));
+            memset(buf_cmp, '#', sizeof(buf_cmp));
+            cb_memset(&buf_test[pos], 0x11, len - pos);
+            memset(&buf_cmp[pos], 0x11, len - pos);
+            EXPECT_EQ(memcmp(buf_test, buf_cmp, sizeof(buf_test)), 0);
+        }
+    }
+}