commit 549af230590c98b3d5f925a76a45db8d81b4eeba
parent 07d1667da8f73c5a270a975076efb4a3ba13a837
Author: sin <sin@2f30.org>
Date: Tue, 16 Jul 2013 22:19:47 +0100
Add krealloc() and kcalloc()
Diffstat:
2 files changed, 63 insertions(+), 0 deletions(-)
diff --git a/include/alloc.h b/include/alloc.h
@@ -5,6 +5,8 @@
void *kmalloc(size_t size);
void kfree(void *addr);
+void *krealloc(void *addr, size_t size);
+void *kcalloc(size_t nmemb, size_t size);
void kdump(void);
#endif /* __ALLOC_H */
diff --git a/kernel/alloc.c b/kernel/alloc.c
@@ -126,6 +126,67 @@ kfree(void *addr)
spinlock_unlock(&alloclist_lock);
}
+void *
+krealloc(void *addr, size_t size)
+{
+ void *p;
+ struct list_head *pos;
+ struct mem_chunk *memc;
+
+ if (!size && addr) {
+ kfree(addr);
+ return NULL;
+ }
+
+ if (addr) {
+ /* Lookup for the old base pointer `addr' if it is part of a
+ * previous allocation */
+ spinlock_lock(&alloclist_lock);
+ list_for_each(pos, &alloclist) {
+ memc = list_entry(pos, struct mem_chunk, list);
+ if (addr == memc->start)
+ goto found;
+ }
+ spinlock_unlock(&alloclist_lock);
+ }
+
+ /* Allocate new space at a different base address */
+ p = kmalloc(size);
+ if (!p)
+ return NULL;
+
+ return p;
+found:
+ /* Are we shrinking the space? If so just return the old `addr' */
+ if (size <= memc->size) {
+ spinlock_unlock(&alloclist_lock);
+ return addr;
+ }
+ spinlock_unlock(&alloclist_lock);
+
+ /* Allocate some space, copy over the old contents at `addr' and
+ * free that space */
+ p = kmalloc(size);
+ if (!p)
+ return NULL;
+
+ memcpy(p, addr, memc->size);
+ kfree(addr);
+
+ return p;
+}
+
+void *
+kcalloc(size_t nmemb, size_t size)
+{
+ void *p;
+
+ p = kmalloc(size * nmemb);
+ if (!p)
+ return NULL;
+ memset(p, 0, size * nmemb);
+ return p;
+}
void
kdump(void)