diff options
author | Alex Auvolat <alex@adnab.me> | 2016-07-16 01:28:04 +0200 |
---|---|---|
committer | Alex Auvolat <alex@adnab.me> | 2016-07-16 01:28:04 +0200 |
commit | 59000174aa50ed6b2d24a71576d15e6a53c5be0c (patch) | |
tree | 38e0a7623f1b83c4dabb1fddfc49014e623f6456 /src/common | |
parent | 32407e728971006ed3d0885e01c22fb66c8adc57 (diff) | |
download | kogata-59000174aa50ed6b2d24a71576d15e6a53c5be0c.tar.gz kogata-59000174aa50ed6b2d24a71576d15e6a53c5be0c.zip |
Add stubs for many libc functions, and a few implemenations too
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/include/kogata/slab_alloc.h | 1 | ||||
-rw-r--r-- | src/common/include/string.h | 7 | ||||
-rw-r--r-- | src/common/libc/ctype.c | 50 | ||||
-rw-r--r-- | src/common/libc/string.c | 48 | ||||
-rw-r--r-- | src/common/libkogata/slab_alloc.c | 57 |
5 files changed, 158 insertions, 5 deletions
diff --git a/src/common/include/kogata/slab_alloc.h b/src/common/include/kogata/slab_alloc.h index 1191057..73b4e82 100644 --- a/src/common/include/kogata/slab_alloc.h +++ b/src/common/include/kogata/slab_alloc.h @@ -41,5 +41,6 @@ void destroy_slab_allocator(mem_allocator_t*); void* slab_alloc(mem_allocator_t* a, size_t sz); void slab_free(mem_allocator_t* a, void* ptr); +void* slab_realloc(mem_allocator_t* a, void* ptr, size_t sz); /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/include/string.h b/src/common/include/string.h index d38bbb6..f13037b 100644 --- a/src/common/include/string.h +++ b/src/common/include/string.h @@ -20,13 +20,12 @@ int strncmp(const char *s1, const char *s2, size_t n); char *strdup(const char* str); char *strndup(const char* str, size_t count); -//TODO +void *memchr(const void *s, int c, size_t n); int strcoll(const char *s1, const char *s2); size_t strspn(const char *s, const char *accept); -char *strstr(const char *haystack, const char *needle); +const char *strstr(const char *haystack, const char *needle); char* strerror(int errnum); -char *strpbrk(const char *s, const char *accept); -void *memchr(const void *s, int c, size_t n); +const char *strpbrk(const char *s, const char *accept); /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libc/ctype.c b/src/common/libc/ctype.c index 56daa6b..e54a24c 100644 --- a/src/common/libc/ctype.c +++ b/src/common/libc/ctype.c @@ -1,3 +1,51 @@ #include <ctype.h> -// TODO + +int isalnum(int c) { + return isalpha(c) || isdigit(c); +} +int isalpha(int c) { + return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'); +} +int isdigit(int c) { + return (c >= '0' && c <= '9'); +} +int isxdigit(int c) { + return isdigit(c) || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'); +} +int isspace(int c) { + return c == ' ' || c == '\t' || c == '\r' || c == '\n'; +} +int isprint(int c) { + return (c >= ' ' && c < 256) || isspace(c); +} +int isupper(int c) { + return c >= 'A' && c <= 'Z'; +} +int islower(int c) { + return c >= 'a' && c <= 'z'; +} +int ispunct(int c) { + return isprint(c) && !isspace(c); +} +int isgraph(int c) { + return c > ' ' && c < 256; +} +int iscntrl(int c) { + return c > 0 && c < ' '; +} + +int toupper(int c) { + if (islower(c)) + return c + 'A' - 'a'; + else + return c; +} +int tolower(int c) { + if (isupper(c)) + return c + 'a' - 'A'; + else + return c; +} + +/* vim: set sts=0 ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libc/string.c b/src/common/libc/string.c index e1ed21e..4b99dda 100644 --- a/src/common/libc/string.c +++ b/src/common/libc/string.c @@ -1,3 +1,4 @@ +#include <stdbool.h> #include <string.h> #include <kogata/malloc.h> @@ -149,4 +150,51 @@ int strcoll(const char *s1, const char *s2) { return strcmp(s1, s2); } +void *memchr(const void *s, int c, size_t n) { + unsigned char *p = (unsigned char*)s; + for (size_t i = 0; i < n; i++) { + if (p[i] == (unsigned char)c) + return &p[i]; + } + return NULL; +} + +size_t strspn(const char *s, const char *accept) { + size_t l = 0; + while (s[l] != 0) { + bool ok = false; + for (const char* p = accept; *p != 0; p++) { + if (s[l] == *p) { + ok = true; + break; + } + } + if (!ok) break; + l++; + } + return l; +} + +const char *strstr(const char *haystack, const char *needle) { + for (const char* p = haystack; *p != 0; p++) { + if (!strcmp(p, needle)) return p; + } + return NULL; +} + +char* strerror(int errnum) { + // TODO + return "(unspecified error)"; +} + +const char *strpbrk(const char *s, const char *accept) { + while (*s) { + for (const char *p = accept; *p != 0; p++) { + if (*s == *p) return s; + } + s++; + } + return NULL; +} + /* vim: set ts=4 sw=4 tw=0 noet :*/ diff --git a/src/common/libkogata/slab_alloc.c b/src/common/libkogata/slab_alloc.c index 6362207..1d56e6f 100644 --- a/src/common/libkogata/slab_alloc.c +++ b/src/common/libkogata/slab_alloc.c @@ -1,3 +1,5 @@ +#include <string.h> + #include <kogata/slab_alloc.h> typedef struct object { @@ -293,5 +295,60 @@ void slab_free(mem_allocator_t* a, void* addr) { } } +size_t slab_find_getsize(mem_allocator_t *a, void* addr) { + // look for block in caches + for (int i = 0; a->types[i].obj_size != 0; i++) { + size_t region_size = PAGE_SIZE * a->types[i].pages_per_cache; + for (cache_t *r = a->slabs[i].first_cache; r != 0; r = r->next_cache) { + if (addr >= r->region_addr && addr < r->region_addr + region_size) { + ASSERT((addr - r->region_addr) % a->types[i].obj_size == 0); + return a->types[i].obj_size; + } + } + } + + // otherwise the block was directly allocated : look for it in regions. + for (region_t *i = a->all_regions; i != 0; i = i->next_region) { + if (i->region_addr == addr) { + return i->region_size; + } + } + ASSERT(false); +} + +void* slab_realloc(mem_allocator_t* a, void* ptr, size_t sz) { + if (ptr == 0) return slab_alloc(a, sz); + if (sz == 0) { + slab_free(a, ptr); + return NULL; + } + + size_t old_sz = slab_find_getsize(a, ptr); + + // What size will be allocated ? + size_t new_sz = 0; + for (int i = 0; a->types[i].obj_size != 0; i++) { + const size_t obj_size = a->types[i].obj_size; + if (sz <= obj_size) { + new_sz = obj_size; + break; + } + } + if (new_sz == 0) new_sz = sz; + + // If the space is already big enough, do nothing + if (old_sz == new_sz) return ptr; + + // Reallocate + void* ptr2 = slab_alloc(a, sz); + if (ptr2 == NULL) return NULL; + + size_t min_sz = (old_sz < sz ? old_sz : sz); + memcpy(ptr2, ptr, min_sz); + slab_free(a, ptr); + + return ptr2; +} + /* vim: set ts=4 sw=4 tw=0 noet :*/ |