commit ff92885350650362cd408a6ba613898c461641d5
parent 263d36a92c39d879c9288b572353d4f7a3fff9ce
Author: oblique <psyberbits@gmail.com>
Date: Tue, 23 Jul 2013 15:37:19 +0300
Restructure the code of krealloc() and add one feature in it.
Feature added:
If the new rounded size of krealloc() is smaller than the current
one, then allocate a smaller memory region.
Diffstat:
M | kernel/alloc.c | | | 50 | ++++++++++++++++++++++++-------------------------- |
1 file changed, 24 insertions(+), 26 deletions(-)
diff --git a/kernel/alloc.c b/kernel/alloc.c
@@ -131,46 +131,44 @@ krealloc(void *addr, size_t size)
{
void *p;
struct list_head *pos;
- struct mem_chunk *memc;
+ struct mem_chunk *memc = NULL;
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;
+ /* If addr is NULL, allocate new space */
+ if (!addr)
+ return kmalloc(size);
- 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;
+ /* 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) {
+ /* Is the new rounded size the same of the current one?
+ * If so just return the old `addr' */
+ if (roundup(size) == memc->size) {
+ spinlock_unlock(&alloclist_lock);
+ return addr;
+ }
+ break;
+ }
}
spinlock_unlock(&alloclist_lock);
- /* Allocate some space, copy over the old contents at `addr' and
- * free that space */
+ /* Allocate some space, copy over the old contents and then
+ * free them */
p = kmalloc(size);
if (!p)
return NULL;
- memcpy(p, addr, memc->size);
+ if (memc->size < size)
+ memcpy(p, addr, memc->size);
+ else
+ memcpy(p, addr, size);
kfree(addr);
return p;