aboutsummaryrefslogtreecommitdiff
path: root/kernel/lib
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/lib')
-rw-r--r--kernel/lib/buffer.c167
-rw-r--r--kernel/lib/hashtbl.c166
-rw-r--r--kernel/lib/mutex.c27
-rw-r--r--kernel/lib/printf.c120
-rw-r--r--kernel/lib/slab_alloc.c283
-rw-r--r--kernel/lib/string.c90
6 files changed, 0 insertions, 853 deletions
diff --git a/kernel/lib/buffer.c b/kernel/lib/buffer.c
deleted file mode 100644
index d2f9644..0000000
--- a/kernel/lib/buffer.c
+++ /dev/null
@@ -1,167 +0,0 @@
-#include <kmalloc.h>
-
-#include <buffer.h>
-#include <string.h>
-
-#include <sys.h>
-
-// three types of buffers
-#define T_BYTES 1
-#define T_SLICE 2
-#define T_CONCAT 3
-
-struct buffer {
- uint16_t rc, type; // takes less space like this
- size_t len;
- union {
- struct {
- const char* data;
- bool owned;
- } bytes;
- struct {
- struct buffer *buf;
- size_t begin;
- } slice;
- struct {
- struct buffer *a, *b;
- } concat;
- };
-};
-
-void buffer_ref(buffer_t *b) {
- b->rc++;
-}
-
-void buffer_unref(buffer_t *b) {
- b->rc--;
- if (b->rc == 0) {
- switch (b->type) {
- case T_BYTES:
- if (b->bytes.owned) kfree((void*)b->bytes.data);
- break;
- case T_SLICE:
- buffer_unref(b->slice.buf);
- break;
- case T_CONCAT:
- buffer_unref(b->concat.a);
- buffer_unref(b->concat.b);
- break;
- default:
- ASSERT(false);
- }
- kfree(b);
- }
-}
-
-size_t buffer_size(buffer_t *b) {
- return b->len;
-}
-
-size_t read_buffer(buffer_t *b, char* dest, size_t begin, size_t n) {
- if (begin >= b->len) return 0;
- if (begin + n >= b->len) n = b->len - begin;
-
- switch (b->type) {
- case T_BYTES:
- memcpy(dest, b->bytes.data + begin, n);
- break;
- case T_SLICE:
- read_buffer(b->slice.buf, dest, begin + b->slice.begin, n);
- break;
- case T_CONCAT: {
- size_t la = b->concat.a->len;
- if (begin < la) {
- size_t r = read_buffer(b->concat.a, dest, begin, n);
- if (r < n) {
- ASSERT(read_buffer(b->concat.b, dest, 0, n - r) == n - r);
- }
- } else {
- ASSERT(read_buffer(b->concat.b, dest, begin - la, n) == n);
- }
- break;
- }
- default:
- ASSERT(false);
- }
-
- return n;
-}
-
-// ========================= //
-// BUFFER CREATION FUNCTIONS //
-// ========================= //
-
-buffer_t *buffer_from_bytes_nocopy(const char* data, size_t n, bool own_bytes) {
- buffer_t *b = (buffer_t*)kmalloc(sizeof(buffer_t));
- if (b == 0) return 0;
-
- b->rc = 1;
- b->type = T_BYTES;
- b->len = n;
- b->bytes.data = data;
- b->bytes.owned = own_bytes;
-
- return b;
-}
-buffer_t *buffer_from_bytes(const char* data, size_t n) {
- char* data2 = (char*)kmalloc(n);
- if (data2 == 0) return 0;
-
- memcpy(data2, data, n);
-
- buffer_t *b = buffer_from_bytes_nocopy(data2, n, true);
- if (b == 0) {
- kfree(data2);
- return 0;
- }
-
- return b;
-}
-
-
-buffer_t* buffer_slice(buffer_t* src, size_t begin, size_t n) {
- if (begin + n > src->len) return 0; // invalid request
-
- buffer_t *b = (buffer_t*)kmalloc(sizeof(buffer_t));
- if (b == 0) return 0;
-
- b->rc = 1;
- b->type = T_SLICE;
- b->len = n;
- b->slice.buf = src;
- b->slice.begin = begin;
-
- return b;
-}
-
-buffer_t* buffer_concat(buffer_t* a, buffer_t* b) {
- buffer_t *r = (buffer_t*)kmalloc(sizeof(buffer_t));
- if (r == 0) return r;
-
- r->rc = 1;
- r->type = T_CONCAT;
- r->len = a->len + b->len;
- r->concat.a = a;
- r->concat.b = b;
-
- return r;
-}
-
-buffer_t* buffer_slice_k(buffer_t *b, size_t begin, size_t n) {
- buffer_t *r = buffer_slice(b, begin, n);
- if (r != 0) {
- buffer_ref(b);
- }
- return r;
-}
-
-buffer_t* buffer_concat_k(buffer_t *a, buffer_t *b) {
- buffer_t *r = buffer_concat(a, b);
- if (r != 0) {
- buffer_ref(a);
- buffer_ref(b);
- }
- return r;
-}
-
-/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/kernel/lib/hashtbl.c b/kernel/lib/hashtbl.c
deleted file mode 100644
index 91fb3cb..0000000
--- a/kernel/lib/hashtbl.c
+++ /dev/null
@@ -1,166 +0,0 @@
-#include <hashtbl.h>
-#include <kmalloc.h>
-#include <string.h>
-
-#define DEFAULT_INIT_SIZE 16
-#define SLOT_OF_HASH(k, nslots) (((size_t)(k)*21179)%(size_t)(nslots))
-
-typedef struct hashtbl_item {
- void* key;
- void* val;
- struct hashtbl_item *next;
-} hashtbl_item_t;
-
-// When nitems > size * 3/4, size is multiplied by two
-// When nitems < size * 1/4, size is divided by two
-struct hashtbl {
- key_eq_fun_t ef;
- hash_fun_t hf;
- size_t size, nitems;
- hashtbl_item_t **items;
-};
-
-hashtbl_t *create_hashtbl(key_eq_fun_t ef, hash_fun_t hf, size_t initial_size) {
- hashtbl_t *ht = (hashtbl_t*)kmalloc(sizeof(hashtbl_t));
- if (ht == 0) return 0;
-
- ht->ef = ef;
- ht->hf = hf;
-
- ht->size = (initial_size == 0 ? DEFAULT_INIT_SIZE : initial_size);
- ht->nitems = 0;
-
- ht->items = (hashtbl_item_t**)kmalloc(ht->size * sizeof(hashtbl_item_t*));
- if (ht->items == 0) {
- kfree(ht);
- return 0;
- }
-
- for (size_t i = 0; i < ht->size; i++) ht->items[i] = 0;
-
- return ht;
-}
-
-void delete_hashtbl(hashtbl_t *ht) {
- // Free items
- for (size_t i = 0; i < ht->size; i++) {
- while (ht->items[i] != 0) {
- hashtbl_item_t *n = ht->items[i]->next;
- kfree(ht->items[i]);
- ht->items[i] = n;
- }
- }
-
- // Free table
- kfree(ht->items);
- kfree(ht);
-}
-
-static void hashtbl_check_size(hashtbl_t *ht) {
- size_t nsize = 0;
- if (4 * ht->nitems < ht->size) nsize = ht->size / 2;
- if (4 * ht->nitems > 3 * ht->size) nsize = ht->size * 2;
-
- if (nsize != 0) {
- hashtbl_item_t **nitems = (hashtbl_item_t**)kmalloc(nsize * sizeof(hashtbl_item_t*));
- if (nitems == 0) return; // if we can't realloc, too bad, we just lose space
-
- for (size_t i = 0; i < nsize; i++) nitems[i] = 0;
-
- // rehash
- for (size_t i = 0; i < ht->size; i++) {
- while (ht->items[i] != 0) {
- hashtbl_item_t *x = ht->items[i];
- ht->items[i] = x->next;
-
- size_t slot = SLOT_OF_HASH(ht->hf(x->key), nsize);
- x->next = nitems[slot];
- nitems[slot] = x;
- }
- }
- kfree(ht->items);
- ht->size = nsize;
- ht->items = nitems;
- }
-}
-
-int hashtbl_add(hashtbl_t *ht, void* key, void* v) {
- size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size);
-
- hashtbl_item_t *i = (hashtbl_item_t*)kmalloc(sizeof(hashtbl_item_t));
- if (i == 0) return 1; // OOM
-
- // make sure item is not already present
- hashtbl_remove(ht, key);
-
- i->key = key;
- i->val = v;
- i->next = ht->items[slot];
- ht->items[slot] = i;
- ht->nitems++;
-
- hashtbl_check_size(ht);
-
- return 0;
-}
-
-void* hashtbl_find(hashtbl_t* ht, void* key) {
- size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size);
-
- for (hashtbl_item_t *i = ht->items[slot]; i != 0; i = i->next) {
- if (ht->ef(i->key, key)) return i->val;
- }
-
- return 0;
-}
-
-void hashtbl_remove(hashtbl_t* ht, void* key) {
- size_t slot = SLOT_OF_HASH(ht->hf(key), ht->size);
-
- if (ht->items[slot] == 0) return;
-
- if (ht->ef(ht->items[slot]->key, key)) {
- hashtbl_item_t *x = ht->items[slot];
- ht->items[slot] = x->next;
- kfree(x);
- ht->nitems--;
- } else {
- for (hashtbl_item_t *i = ht->items[slot]; i->next != 0; i = i->next) {
- if (ht->ef(i->next->key, key)) {
- hashtbl_item_t *x = i->next;
- i->next = x->next;
- kfree(x);
- ht->nitems--;
- break;
- }
- }
- }
-
- hashtbl_check_size(ht);
-}
-
-size_t hashtbl_count(hashtbl_t* ht) {
- return ht->nitems;
-}
-
-hash_t id_hash_fun(const void* v) {
- return (hash_t)v;
-}
-
-hash_t str_hash_fun(const void* v) {
- hash_t h = 712;
- for (char* s = (char*)v; *s != 0; s++) {
- h = h * 101 + *s;
- }
- return h;
-}
-
-bool id_key_eq_fun(const void* a, const void* b) {
- return a == b;
-}
-
-bool str_key_eq_fun(const void* a, const void* b) {
- return strcmp((const char*)a, (const char*)b) == 0;
-}
-
-/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/kernel/lib/mutex.c b/kernel/lib/mutex.c
deleted file mode 100644
index cda8049..0000000
--- a/kernel/lib/mutex.c
+++ /dev/null
@@ -1,27 +0,0 @@
-#include <mutex.h>
-
-/* Internal use only. This function is atomic, meaning it cannot be interrupted by a system task switch. */
-static uint32_t atomic_exchange(uint32_t* ptr, uint32_t newval) {
- uint32_t r;
- asm volatile("xchg (%%ecx), %%eax" : "=a"(r) : "c"(ptr), "a"(newval));
- return r;
-}
-
-void mutex_lock(uint32_t* mutex) {
- while (atomic_exchange(mutex, MUTEX_LOCKED) == MUTEX_LOCKED) {
- yield();
- }
-}
-
-int mutex_try_lock(uint32_t* mutex) {
- if (atomic_exchange(mutex, MUTEX_LOCKED) == MUTEX_LOCKED) {
- return 0;
- }
- return 1;
-}
-
-void mutex_unlock(uint32_t* mutex) {
- *mutex = MUTEX_UNLOCKED;
-}
-
-/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/kernel/lib/printf.c b/kernel/lib/printf.c
deleted file mode 100644
index 68e08d8..0000000
--- a/kernel/lib/printf.c
+++ /dev/null
@@ -1,120 +0,0 @@
-#include <printf.h>
-#include <stdarg.h>
-
-int snprintf(char * buff, size_t len, const char *format, ...) {
- va_list ap;
-
- va_start(ap, format);
- len = vsnprintf(buff, len, format, ap);
- va_end(ap);
-
- return len;
-}
-
-int vsnprintf(char *buff, size_t len, const char* format, va_list ap){
- size_t i, result;
-
- if (!buff || !format)
- return -1;
-
-#define PUTCHAR(thechar) \
- do { \
- if (result < len-1) \
- *buff++ = (thechar); \
- result++; \
- } while (0)
-
- result = 0;
- for(i = 0; format[i] != '\0' ; i++) {
- if (format[i] == '%') {
- i++;
- switch(format[i]) {
- case '%':
- PUTCHAR('%');
- break;
-
- case 'i':;
- case 'd': {
- int integer = va_arg(ap,int);
- int cpt2 = 0;
- char buff_int[16];
-
- if (integer<0)
- PUTCHAR('-');
-
- do {
- int m10 = integer%10;
- m10 = (m10 < 0)? -m10:m10;
- buff_int[cpt2++] = (char)('0'+ m10);
- integer = integer/10;
- } while(integer != 0);
-
- for(cpt2 = cpt2 - 1; cpt2 >= 0; cpt2--)
- PUTCHAR(buff_int[cpt2]);
-
- break;
- }
- case 'c': {
- int value = va_arg(ap,int);
- PUTCHAR((char)value);
- break;
- }
- case 's': {
- char *string = va_arg(ap,char *);
- if (!string)
- string = "(null)";
- for(; *string != '\0' ; string++)
- PUTCHAR(*string);
- break;
- }
- case 'x': {
- unsigned int hexa = va_arg(ap,int);
- unsigned int nb;
- int j, had_nonzero = 0;
- for(j = 0; j < 8; j++) {
- nb = (unsigned int)(hexa << (j*4));
- nb = (nb >> 28) & 0xf;
- // Skip the leading zeros
- if (nb == 0) {
- if (had_nonzero)
- PUTCHAR('0');
- } else {
- had_nonzero = 1;
- if (nb < 10)
- PUTCHAR('0'+nb);
- else
- PUTCHAR('a'+(nb-10));
- }
- }
- if (!had_nonzero)
- PUTCHAR('0');
- break;
- }
- case 'p': {
- unsigned int hexa = va_arg(ap,int);
- unsigned int nb;
- int j;
- for (j = 0; j < 8; j++) {
- nb = (unsigned int)(hexa << (j*4));
- nb = (nb >> 28) & 0xf;
- if (nb < 10)
- PUTCHAR('0'+nb);
- else
- PUTCHAR('a'+(nb-10));
- }
- break;
- }
- default:
- PUTCHAR('%');
- PUTCHAR(format[i]);
- }
- } else {
- PUTCHAR(format[i]);
- }
- }
-
- *buff = '\0';
- return result;
-}
-
-/* vim: set ts=4 sw=4 tw=0 noet :*/
diff --git a/kernel/lib/slab_alloc.c b/kernel/lib/slab_alloc.c
deleted file mode 100644
index 714c49f..0000000
--- a/kernel/lib/slab_alloc.c
+++ /dev/null
@@ -1,283 +0,0 @@
-#include <slab_alloc.h>
-
-typedef struct object {
- struct object *next;
-} object_t;
-
-typedef struct cache {
- void* region_addr;
-
- uint32_t n_free_objs;
- object_t* first_free_obj;
-
- struct cache *next_cache; // next cache in this slab
-} cache_t;
-
-typedef struct region {
- void* region_addr;
- size_t region_size;
- struct region *next_region;
- bool contains_descriptors;
-} region_t;
-
-typedef union descriptor {
- cache_t c;
- region_t r;
- union descriptor *next_free;
-} descriptor_t;
-
-typedef struct slab {
- cache_t *first_cache; // linked list of caches
-} slab_t;
-
-struct mem_allocator {
- const slab_type_t *types;
- slab_t *slabs;
-
- descriptor_t *first_free_descriptor;
- region_t *all_regions;
-
- page_alloc_fun_t alloc_fun;
- page_free_fun_t free_fun;
-};
-
-// ============================================== //
-// Helper functions for the manipulation of lists //
-// ============================================== //
-
-static void add_free_descriptor(mem_allocator_t *a, descriptor_t *c) {
- c->next_free = a->first_free_descriptor;
- a->first_free_descriptor = c;
-}
-
-static descriptor_t *take_descriptor(mem_allocator_t *a) {
- if (a->first_free_descriptor == 0) {
- void* p = a->alloc_fun(PAGE_SIZE);
- if (p == 0) return 0;
-
- const void* end = p + PAGE_SIZE;
- for (descriptor_t *i = (descriptor_t*)p; i + 1 <= (descriptor_t*)end; i++) {
- add_free_descriptor(a, i);
- }
-
- // register the descriptor region
- descriptor_t *dd = a->first_free_descriptor;
- ASSERT(dd != 0);
- a->first_free_descriptor = dd->next_free;
-
- region_t *drd = &dd->r;
- drd->region_addr = p;
- drd->region_size = PAGE_SIZE;
- drd->contains_descriptors = true;
- drd->next_region = a->all_regions;
- a->all_regions = drd;
- }
-
- descriptor_t *x = a->first_free_descriptor;
- ASSERT(x != 0);
- a->first_free_descriptor = x->next_free;
- return x;
-}
-
-// ============================== //
-// The actual allocator functions //
-// ============================== //
-
-mem_allocator_t* create_slab_allocator(const slab_type_t *types, page_alloc_fun_t af, page_free_fun_t ff) {
- union {
- void* addr;
- mem_allocator_t *a;
- slab_t *s;
- descriptor_t *d;
- } ptr;
-
- ptr.addr = af(PAGE_SIZE);
- if (ptr.addr == 0) return 0; // could not allocate
- const void* end_addr = ptr.addr + PAGE_SIZE;
-
- mem_allocator_t *a = ptr.a;
- ptr.a++;
-
- a->all_regions = 0;
- a->alloc_fun = af;
- a->free_fun = ff;
-
- a->types = types;
- a->slabs = ptr.s;
- for (const slab_type_t *t = types; t->obj_size != 0; t++) {
- ASSERT(t->obj_size >= sizeof(object_t));
- ptr.s->first_cache = 0;
- ptr.s++;
- }
-
- a->first_free_descriptor = 0;
- while (ptr.d + 1 <= (descriptor_t*)end_addr) {
- add_free_descriptor(a, ptr.d);
- ptr.d++;
- }
-
- return a;
-}
-
-static void stack_and_destroy_regions(page_free_fun_t ff, region_t *r) {
- if (r == 0) return;
- void* addr = r->region_addr;
- ASSERT(r != r->next_region);
- stack_and_destroy_regions(ff, r->next_region);
- ff(addr);
-}
-void destroy_slab_allocator(mem_allocator_t *a) {
- for (int i = 0; a->types[i].obj_size != 0; i++) {
- for (cache_t *c = a->slabs[i].first_cache; c != 0; c = c->next_cache) {
- a->free_fun(c->region_addr);
- }
- }
- region_t *dr = 0;
- region_t *i = a->all_regions;
- while (i != 0) {
- region_t *r = i;
- i = r->next_region;
- if (r->contains_descriptors) {
- r->next_region = dr;
- dr = r;
- } else {
- a->free_fun(r->region_addr);
- }
- }
- stack_and_destroy_regions(a->free_fun, dr);
- a->free_fun(a);
-}
-
-void* slab_alloc(mem_allocator_t* a, size_t sz) {
- 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) {
- // find a cache with free space
- cache_t *fc = a->slabs[i].first_cache;
- while (fc != 0 && fc->n_free_objs == 0) {
- ASSERT(fc->first_free_obj == 0); // make sure n_free == 0 iff no object in the free stack
- fc = fc->next_cache;
- }
- // if none found, try to allocate a new one
- if (fc == 0) {
- descriptor_t *fcd = take_descriptor(a);
- if (fcd == 0) return 0;
-
- fc = &fcd->c;
- ASSERT((descriptor_t*)fc == fcd);
-
- const size_t cache_size = a->types[i].pages_per_cache * PAGE_SIZE;
- fc->region_addr = a->alloc_fun(cache_size);
- if (fc->region_addr == 0) {
- add_free_descriptor(a, fcd);
- return 0;
- }
-
- fc->n_free_objs = 0;
- fc->first_free_obj = 0;
- for (void* p = fc->region_addr; p + obj_size <= fc->region_addr + cache_size; p += obj_size) {
- object_t *x = (object_t*)p;
- x->next = fc->first_free_obj;
- fc->first_free_obj = x;
- fc->n_free_objs++;
- }
- ASSERT(fc->n_free_objs == cache_size / obj_size);
-
- fc->next_cache = a->slabs[i].first_cache;
- a->slabs[i].first_cache = fc;
- }
- // allocate on fc
- ASSERT(fc != 0 && fc->n_free_objs > 0);
-
- object_t *x = fc->first_free_obj;
- fc->first_free_obj = x->next;
- fc->n_free_objs--;
-
- ASSERT((fc->n_free_objs == 0) == (fc->first_free_obj == 0));
-
- // TODO : if fc is full, put it at the end
- return x;
- }
- }
-
- // otherwise directly allocate using a->alloc_fun
- descriptor_t *rd = take_descriptor(a);
- if (rd == 0) return 0;
- region_t *r = &rd->r;
- ASSERT((descriptor_t*)r == rd);
-
- r->region_addr = a->alloc_fun(sz);
- if (r->region_addr == 0) {
- add_free_descriptor(a, rd);
- return 0;
- } else {
- r->region_size = sz;
- r->contains_descriptors = false;
-
- r->next_region = a->all_regions;
- a->all_regions = r;
-
- return (void*)r->region_addr;
- }
-}
-
-void slab_free(mem_allocator_t* a, void* addr) {
-
- 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);
-
- object_t *o = (object_t*)addr;
- o->next = r->first_free_obj;
- r->first_free_obj = o;
- r->n_free_objs++;
-
- if (r->n_free_objs == region_size / a->types[i].obj_size) {
- // region is completely unused, free it.
- if (a->slabs[i].first_cache == r) {
- a->slabs[i].first_cache = r->next_cache;
- } else {
- for (cache_t *it = a->slabs[i].first_cache; it->next_cache != 0; it = it->next_cache) {
- if (it->next_cache == r) {
- it->next_cache = r->next_cache;
- break;
- }
- }
- }
- a->free_fun(r->region_addr);
- add_free_descriptor(a, (descriptor_t*)r);
- }
- return;
- }
- }
- }
-
- // otherwise the block was directly allocated : look for it in regions.
- ASSERT(a->all_regions != 0);
-
- if (a->all_regions->region_addr == addr) {
- a->free_fun(addr); // found it, free it
-
- region_t *r = a->all_regions;
- a->all_regions = r->next_region;
- add_free_descriptor(a, (descriptor_t*)r);
- } else {
- for (region_t *i = a->all_regions; i->next_region != 0; i = i->next_region) {
- if (i->next_region->region_addr == addr) {
- a->free_fun(addr); // found it, free it
-
- region_t *r = i->next_region;
- ASSERT(!r->contains_descriptors);
- i->next_region = r->next_region;
- add_free_descriptor(a, (descriptor_t*)r);
- return;
- }
- }
- ASSERT(false);
- }
-}
-
-/* vim: set ts=4 sw=4 tw=0 noet :*/
-
diff --git a/kernel/lib/string.c b/kernel/lib/string.c
deleted file mode 100644
index 9dce27b..0000000
--- a/kernel/lib/string.c
+++ /dev/null
@@ -1,90 +0,0 @@
-#include <string.h>
-
-
-size_t strlen(const char* str) {
- size_t ret = 0;
- while (str[ret] != 0)
- ret++;
- return ret;
-}
-
-char *strchr(const char *str, char c) {
- while (*str) {
- if (*str == c) return (char*)str;
- str++;
- }
- return NULL;
-}
-
-char *strcpy(char *dest, const char *src) {
- memcpy(dest, src, strlen(src) + 1);
- return (char*)src;
-}
-
-char *strcat(char *dest, const char *src) {
- char *dest2 = dest;
- dest2 += strlen(dest) - 1;
- while (*src) {
- *dest2 = *src;
- src++;
- dest2++;
- }
- *dest2 = 0;
- return dest;
-}
-
-int strcmp(const char *s1, const char *s2) {
- while ((*s1) && (*s1 == *s2)) {
- s1++;
- s2++;
- }
- return (*(unsigned char*)s1 - *(unsigned char*)s2);
-}
-
-void *memcpy(void *vd, const void *vs, size_t count) {
- uint8_t *dest = (uint8_t*)vd, *src = (uint8_t*)vs;
- size_t f = count % 4, n = count / 4, i;
- const uint32_t* s = (uint32_t*)src;
- uint32_t* d = (uint32_t*)dest;
- for (i = 0; i < n; i++) {
- d[i] = s[i];
- }
- if (f != 0) {
- for (i = count - f; i < count; i++) {
- dest[i] = src[i];
- }
- }
- return vd;
-}
-
-void *memmove(void *vd, const void *vs, size_t count) {
- uint8_t *dest = (uint8_t*)vd, *src = (uint8_t*)vs;
-
- if (vd < vs) {
- for (size_t i = 0; i < count; i++)
- dest[i] = src[i];
- } else {
- for (size_t i = 0; i < count; i++)
- dest[count - i] = src[count - i];
- }
- return vd;
-}
-
-int memcmp(const void *va, const void *vb, size_t count) {
- uint8_t *a = (uint8_t*)va;
- uint8_t *b = (uint8_t*)vb;
- for (size_t i = 0; i < count; i++) {
- if (a[i] != b[i]) return (int)a[i] - (int)b[i];
- }
- return 0;
-}
-
-void *memset(void *dest, int val, size_t count) {
- uint8_t *dest_c = (uint8_t*)dest;
- for (size_t i = 0; i < count; i++) {
- dest_c[i] = val;
- }
- return dest;
-}
-
-/* vim: set ts=4 sw=4 tw=0 noet :*/