commit 57efc95750bc7852b06c67a2c40dec9334b8df11
parent 6c78a717a2e6cde7c0a85e2e30fc7a58c938dd9b
Author: Roberto E. Vargas Caballero <roberto.vargas@midokura.com>
Date: Fri, 18 Nov 2022 19:20:06 +0100
os9: Fix memory allocator
There were several problems in the calculation of the space used and
after moving to a list of pages the allocb() interface didn't make
sense anymore.
Diffstat:
3 files changed, 17 insertions(+), 16 deletions(-)
diff --git a/include/os9/os9.h b/include/os9/os9.h
@@ -255,7 +255,7 @@ extern void unlocktask(Task *);
/* alloc.c */
extern void *alloc(size_t);
-extern void *allocb(int);
+extern void *allocb(void);
extern void freeb(void *);
extern void ialloc(void);
diff --git a/src/os9/alloc.c b/src/os9/alloc.c
@@ -14,6 +14,8 @@ struct {
mutex_t m;
} bufpool;
+static union bucket *heap;
+
void
freeb(void *bp)
{
@@ -30,7 +32,7 @@ freeb(void *bp)
}
void *
-allocb(int n)
+allocb(void)
{
union bucket *bp = NULL;
@@ -51,9 +53,8 @@ alloc(size_t size)
{
size_t n;
static size_t used;
- static union bucket *heap;
static mutex_t m;
- union bucket *bp = NULL;
+ union bucket *bp;
if (size == 0) {
errno = EINVAL;
@@ -61,16 +62,14 @@ alloc(size_t size)
}
lock(&m);
- if (!heap)
- heap = allocb(HEAPSIZ);
-
n = (size-1) / sizeof(union bucket) + 1;
size = n * sizeof(union bucket);
- if (used > SIZE_MAX - size) {
+ if (used > PAGESIZE*HEAPSIZ - size) {
+ bp = NULL;
errno = ENOMEM;
} else {
- bp = heap + used;
+ bp = heap + n;
used += size;
}
unlock(&m);
@@ -84,8 +83,10 @@ ialloc(void)
int i;
union bucket *bp, *prev;
+ heap = buffertab;
+
prev = NULL;
- for (i = 0; i < NR_BUFFERS; i++) {
+ for (i = HEAPSIZ; i < NR_BUFFERS; i++) {
bp = (union bucket *) buffertab[i];
bp->next = prev;
prev = bp;
diff --git a/src/os9/proc.c b/src/os9/proc.c
@@ -130,13 +130,13 @@ mapseg(Map *mp)
n = (mp->siz + PAGESIZE-1)/PAGESIZE;
va = mp->va;
pa = mp->pa;
- if (pa == -1) {
- if ((bp = allocb(n)) == NULL)
- return -1;
- pa = (phyaddr_t) PMEM(bp);
- }
-
for (i = 0; i < n; i++) {
+ if (mp->pa == -1) {
+ if ((bp = allocb()) == NULL)
+ return -1;
+ pa = (phyaddr_t) PMEM(bp);
+ }
+
if (vmap(pa, va, mp->perm) < 0) {
freeb(bp);
return -1;