aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2016-07-16 01:28:04 +0200
committerAlex Auvolat <alex@adnab.me>2016-07-16 01:28:04 +0200
commit59000174aa50ed6b2d24a71576d15e6a53c5be0c (patch)
tree38e0a7623f1b83c4dabb1fddfc49014e623f6456 /src/common
parent32407e728971006ed3d0885e01c22fb66c8adc57 (diff)
downloadkogata-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.h1
-rw-r--r--src/common/include/string.h7
-rw-r--r--src/common/libc/ctype.c50
-rw-r--r--src/common/libc/string.c48
-rw-r--r--src/common/libkogata/slab_alloc.c57
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 :*/