Sorted out proc refcounting with ARCs
[akaros.git] / kern / src / string.c
index 3ee27ca..8cde851 100644 (file)
@@ -1,6 +1,12 @@
 // Basic string routines.  Not hardware optimized, but not shabby.
 
+#ifdef __SHARC__
+#pragma nosharc
+#endif
+
 #include <string.h>
+#include <ros/memlayout.h>
+#include <assert.h>
 
 int
 strlen(const char *s)
@@ -49,6 +55,7 @@ strncpy(char *dst, const char *src, size_t size) {
 
        ret = dst;
        for (i = 0; i < size; i++) {
+               // TODO: ivy bitches about this
                *dst++ = *src;
                // If strlen(src) < size, null-pad 'dst' out to 'size' chars
                if (*src != '\0')
@@ -101,6 +108,16 @@ strchr(const char *s, char c)
        return 0;
 }
 
+void *
+memchr(void* mem, int chr, int len)
+{
+       char* s = (char*)mem;
+       for(int i = 0; i < len; i++)
+               if(s[i] == (char)chr)
+                       return s+i;
+       return NULL;
+}
+
 // Return a pointer to the first occurrence of 'c' in 's',
 // or a pointer to the string-ending null character if the string has no 'c'.
 char *
@@ -124,6 +141,19 @@ memset16(uint32_t *COUNT(n/sizeof(uint32_t)) _v, uint32_t c, size_t n)
        v = _v;
        c = c | c<<8 | c<<16 | c<<24;
 
+       if(n >= 64 && ((uintptr_t)v) % 8 == 0)
+       {
+               uint64_t* v64 = (uint64_t*)v;
+               uint64_t c64 = c | ((uint64_t)c)<<32;
+               while(v64 < (uint64_t*)end-7)
+               {
+                       v64[3] = v64[2] = v64[1] = v64[0] = c64;
+                       v64[7] = v64[6] = v64[5] = v64[4] = c64;
+                       v64 += 8;
+               }
+               v = (uint32_t*)v64;
+       }
+
        while(v < end)
        {
                v[3] = v[2] = v[1] = v[0] = c;
@@ -139,13 +169,13 @@ static inline void *
 memcpy16(uint32_t *COUNT(n/sizeof(uint32_t)) _dst,
          const uint32_t *COUNT(n/sizeof(uint32_t)) _src, size_t n)
 {
-       uint32_t *dststart, *dstend, *srcend;
+       uint32_t *dststart, *SNT dstend, *SNT srcend;
        uint32_t *BND(_dst,dstend) dst;
-       uint32_t *BND(_src,srcend) src;
+       const uint32_t *BND(_src,srcend) src;
 
        dststart = _dst;
-       dstend = _dst + n/sizeof(uint32_t);
-       srcend = _src + n/sizeof(uint32_t);
+       dstend = (uint32_t *SNT)(_dst + n/sizeof(uint32_t));
+       srcend = (uint32_t *SNT)(_src + n/sizeof(uint32_t));
        dst = _dst;
        src = _src;
 
@@ -164,7 +194,25 @@ memcpy16(uint32_t *COUNT(n/sizeof(uint32_t)) _dst,
 }
 
 void *
-memset(void *v, int c, size_t _n)
+pagecopy(void* d, void* s)
+{
+       static_assert(PGSIZE % 64 == 0);
+       for(int i = 0; i < PGSIZE; i += 64)
+       {
+               *((uint64_t*)(d+i+0)) = *((uint64_t*)(s+i+0));
+               *((uint64_t*)(d+i+8)) = *((uint64_t*)(s+i+8));
+               *((uint64_t*)(d+i+16)) = *((uint64_t*)(s+i+16));
+               *((uint64_t*)(d+i+24)) = *((uint64_t*)(s+i+24));
+               *((uint64_t*)(d+i+32)) = *((uint64_t*)(s+i+32));
+               *((uint64_t*)(d+i+40)) = *((uint64_t*)(s+i+40));
+               *((uint64_t*)(d+i+48)) = *((uint64_t*)(s+i+48));
+               *((uint64_t*)(d+i+56)) = *((uint64_t*)(s+i+56));
+       }
+       return d;
+}
+
+void *
+memset(void *COUNT(_n) v, int c, size_t _n)
 {
        char *BND(v,v+_n) p;
        size_t n0;
@@ -174,10 +222,16 @@ memset(void *v, int c, size_t _n)
 
        p = v;
 
-       if(n >= 16 && ((uintptr_t)v & 3) == 0)
+    while (n > 0 && ((uintptr_t)p & 7))
+       {
+               *p++ = c;
+               n--;
+       }
+
+       if(n >= 16 && ((uintptr_t)p & 3) == 0)
        {
                n0 = (n/16)*16;
-               memset16((uint32_t*)v,c,n0);
+               memset16((uint32_t*COUNT(n0/sizeof(uint32_t)))p,c,n0);
                n -= n0;
                p += n0;
        }
@@ -192,7 +246,7 @@ memset(void *v, int c, size_t _n)
 }
 
 void *
-memcpy(void *dst, const void *src, size_t _n)
+(DMEMCPY(1,2,3) memcpy)(void *COUNT(_n) dst, const void *COUNT(_n) src, size_t _n)
 {
        const char *BND(src,src+_n) s;
        char *BND(dst,dst+_n) d;
@@ -205,7 +259,8 @@ memcpy(void *dst, const void *src, size_t _n)
        if(n >= 16 && ((uintptr_t)src  & 3) == 0 && ((uintptr_t)dst & 3) == 0)
        {
                n0 = (n/16)*16;
-               memcpy16((uint32_t*)dst,(const uint32_t*)src,n0);
+               memcpy16((uint32_t*COUNT(n0/sizeof(uint32_t)))dst,
+                 (const uint32_t*COUNT(n0/sizeof(uint32_t)))src,n0);
                n -= n0;
                s += n0;
                d += n0;
@@ -218,7 +273,7 @@ memcpy(void *dst, const void *src, size_t _n)
 }
 
 void *
-memmove(void *dst, const void *src, size_t _n)
+memmove(void *COUNT(_n) dst, const void *COUNT(_n) src, size_t _n)
 {
        const char *BND(src,src+_n) s;
        char *BND(dst,dst+_n) d;
@@ -239,7 +294,7 @@ memmove(void *dst, const void *src, size_t _n)
 }
 
 int
-memcmp(const void *v1, const void *v2, size_t n)
+memcmp(const void *COUNT(n) v1, const void *COUNT(n) v2, size_t n)
 {
        const uint8_t *BND(v1,v1+n) s1 = (const uint8_t *) v1;
        const uint8_t *BND(v2,v2+n) s2 = (const uint8_t *) v2;
@@ -254,14 +309,14 @@ memcmp(const void *v1, const void *v2, size_t n)
 }
 
 void *
-memfind(const void *_s, int c, size_t n)
+memfind(const void *COUNT(n) _s, int c, size_t n)
 {
        const void *SNT ends = (const char *) _s + n;
        const void *BND(_s,_s + n) s = _s;
        for (; s < ends; s++)
                if (*(const unsigned char *) s == (unsigned char) c)
                        break;
-       return (void *) s;
+       return (void *BND(_s,_s+n)) s;
 }
 
 long
@@ -311,3 +366,9 @@ strtol(const char *s, char **endptr, int base)
        return (neg ? -val : val);
 }
 
+int
+atoi(const char* s)
+{
+       // no overflow detection
+       return (int)strtol(s,NULL,10);
+}