Commit 9f583d08 authored by Claes Sjofors's avatar Claes Sjofors

Size of pool offset type increased -> maximum pool size increased

parent 6934ff89
...@@ -51,7 +51,9 @@ ...@@ -51,7 +51,9 @@
#include "rt_pool.h" #include "rt_pool.h"
/* Convert bytesize to size expressed in pool_sEntry units. */ /* Convert bytesize to size expressed in pool_sEntry units. */
#define entryUnits(size) (((size)+sizeof(pool_sEntry)-1)>>pool_cOffsAlign) #define pool_Align(offs) (((offs) + (pool_cDataSize-1)) & ~(pool_cDataSize-1))
#define entryUnits(size) (pool_Align(size)/pool_cDataSize)
#define entryPAdd(ep,offs) ((pool_sEntry *)((char *)ep + offs))
#define cEntryMark (4711) #define cEntryMark (4711)
...@@ -94,7 +96,7 @@ static pool_sSegment * ...@@ -94,7 +96,7 @@ static pool_sSegment *
newSegment ( newSegment (
pwr_tStatus *sts, pwr_tStatus *sts,
pool_sHead *php, pool_sHead *php,
pwr_tUInt32 size /* Requested size in pool_sEntry units */ size_t size /* Requested size in pool_sEntry units */
); );
static pwr_tBoolean static pwr_tBoolean
...@@ -122,18 +124,18 @@ allocLookaside ( ...@@ -122,18 +124,18 @@ allocLookaside (
pool_sSegment *psp = &php->seg[lp->seg]; pool_sSegment *psp = &php->seg[lp->seg];
ep = psp->base + lp->next; ep = entryPAdd(psp->base, lp->next * pool_cDataSize);
lp->next = ep->next; lp->next = ep->next;
pr.m = pool_cNRef; pr.m = pool_cNRef;
pr.b.seg = psp->seg; pr.b.seg = psp->seg;
pr.b.offs = (pool_sData *)(ep+1) - (pool_sData *)psp->base; pr.b.offs = (pool_tOffset)((char *)ep + sizeof(pool_sEntry) - (char *)psp->base);
pwr_Assert(entryUnits(lp->size) + 1 == ep->size); pwr_Assert(entryUnits(lp->size + sizeof(pool_sEntry)) == ep->size);
ep->next = pr.m; ep->next = pr.m;
psp->gpsp->alloccnt++; psp->gpsp->alloccnt++;
memset(ep+1, 0, (ep->size-1)<<pool_cOffsAlign); memset( entryPAdd( ep, sizeof(pool_sEntry)), 0, ep->size*pool_cDataSize - sizeof(pool_sEntry));
return (void *)(ep+1); return (void *)entryPAdd( ep, sizeof(pool_sEntry));
} }
static pwr_tBoolean static pwr_tBoolean
...@@ -223,13 +225,13 @@ freeItem ( ...@@ -223,13 +225,13 @@ freeItem (
pr.m = ep->next; pr.m = ep->next;
/* Fill returned entry with with the bit pattern '01010101'... */ /* Fill returned entry with with the bit pattern '01010101'... */
memset(ep+1, 85, (ep->size-1)<<pool_cOffsAlign); memset( entryPAdd(ep, sizeof(pool_sEntry)), 85, ep->size*pool_cDataSize - sizeof(pool_sEntry));
/* Setup pointers */ /* Setup pointers */
gphp = php->gphp; gphp = php->gphp;
seg = pr.b.seg; seg = pr.b.seg;
offs = entryUnits(pr.b.offs) - 1; offs = entryUnits(pr.b.offs - sizeof(pool_sEntry));
psp = &php->seg[seg]; psp = &php->seg[seg];
gpsp = &gphp->seg[seg]; gpsp = &gphp->seg[seg];
...@@ -258,14 +260,14 @@ freeItem ( ...@@ -258,14 +260,14 @@ freeItem (
prevp = &gpsp->freeroot; prevp = &gpsp->freeroot;
while (prevp->next != pool_cNOffset) { while (prevp->next != pool_cNOffset) {
if (offs < prevp->next) break; /* found */ if (offs < prevp->next) break; /* found */
prevp = psp->base + prevp->next; /* try next */ prevp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize); /* try next */
} /* While more free entries */ } /* While more free entries */
/* Here prevp points to the entry after which insertion should be done /* Here prevp points to the entry after which insertion should be done
NOTE. Prevp can point to the header or to the last fragment! */ NOTE. Prevp can point to the header or to the last fragment! */
ep->next = prevp->next; ep->next = prevp->next;
prevp->next = ep - psp->base; prevp->next = ((char *)ep - (char *)psp->base)/pool_cDataSize;
gpsp->fragcnt++; gpsp->fragcnt++;
gpsp->fragsize += ep->size; gpsp->fragsize += ep->size;
gpsp->alloccnt--; gpsp->alloccnt--;
...@@ -280,9 +282,9 @@ freeItem ( ...@@ -280,9 +282,9 @@ freeItem (
/* Join with succeeding/preceeding fragment? */ /* Join with succeeding/preceeding fragment? */
do { do {
tmpp = psp->base + prevp->next; tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
if ((prevp + prevp->size) == tmpp) { if (entryPAdd(prevp, prevp->size * pool_cDataSize) == tmpp) {
prevp->size += tmpp->size; prevp->size += tmpp->size;
prevp->next = tmpp->next; prevp->next = tmpp->next;
/* Fill recovered list info with the bit pattern '01010101'... */ /* Fill recovered list info with the bit pattern '01010101'... */
...@@ -346,7 +348,7 @@ static pool_sSegment * ...@@ -346,7 +348,7 @@ static pool_sSegment *
newSegment ( newSegment (
pwr_tStatus *sts, pwr_tStatus *sts,
pool_sHead *php, pool_sHead *php,
pwr_tUInt32 size /* Requested size in pool_sEntry units */ size_t size /* Requested size in pool_sEntry units */
) )
{ {
pool_sGhead *gphp; pool_sGhead *gphp;
...@@ -445,7 +447,7 @@ pool_Address ( ...@@ -445,7 +447,7 @@ pool_Address (
if (psp == NULL) errh_ReturnOrBugcheck(NULL, sts, lsts, ""); if (psp == NULL) errh_ReturnOrBugcheck(NULL, sts, lsts, "");
if (prf.b.offs < gpsp->size) { if (prf.b.offs < gpsp->size) {
return (pool_sData *)psp->base + prf.b.offs; return (pool_sData *)((char *)psp->base + prf.b.offs);
} }
} }
...@@ -500,7 +502,7 @@ pool_Alloc ( ...@@ -500,7 +502,7 @@ pool_Alloc (
return allocLookaside(sts, php, &gphp->la[3]); return allocLookaside(sts, php, &gphp->la[3]);
} }
esize = entryUnits(size) + 1; /* Add space for header */ esize = entryUnits(size + sizeof(pool_sEntry)); /* Add space for header */
/* Find a segment where there is room. */ /* Find a segment where there is room. */
...@@ -539,7 +541,7 @@ pool_Alloc ( ...@@ -539,7 +541,7 @@ pool_Alloc (
ep = NULL; ep = NULL;
prevp = &gpsp->freeroot; prevp = &gpsp->freeroot;
while (prevp->next != pool_cNOffset) { while (prevp->next != pool_cNOffset) {
tmpp = psp->base + prevp->next; tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
if (tmpp->size >= esize) { /* Found */ if (tmpp->size >= esize) { /* Found */
ep = tmpp; ep = tmpp;
break; break;
...@@ -560,18 +562,20 @@ pool_Alloc ( ...@@ -560,18 +562,20 @@ pool_Alloc (
tmpsize = ep->size; tmpsize = ep->size;
if (ep->size == esize) { /* Entry fits exactly */ if (ep->size == esize ||
(ep->size - esize > 0 &&
(ep->size - esize) * pool_cDataSize < sizeof(pool_sEntry))) { /* Entry fits exactly */
prevp->next = ep->next; prevp->next = ep->next;
--gpsp->fragcnt; --gpsp->fragcnt;
} }
else { /* Entry is to big, split it */ else { /* Entry is to big, split it */
prevp->next += esize; prevp->next = prevp->next + esize;
tmpp = psp->base + prevp->next; tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
tmpp->next = ep->next; tmpp->next = ep->next;
tmpp->size = ep->size - esize; tmpp->size = ep->size - esize;
ep->size = esize; ep->size = esize;
} }
memset(ep+1, 0, (esize-1)<<pool_cOffsAlign); memset( entryPAdd(ep, sizeof(pool_sEntry)), 0, esize*pool_cDataSize - sizeof(pool_sEntry));
ep->next = cEntryMark; ep->next = cEntryMark;
gpsp->alloccnt++; gpsp->alloccnt++;
...@@ -586,7 +590,7 @@ pool_Alloc ( ...@@ -586,7 +590,7 @@ pool_Alloc (
gpsp->fragmaxcnt = 1; gpsp->fragmaxcnt = 1;
prevp = &gpsp->freeroot; prevp = &gpsp->freeroot;
while (prevp->next != pool_cNOffset) { while (prevp->next != pool_cNOffset) {
tmpp = psp->base + prevp->next; tmpp = (pool_sEntry *)((char *)psp->base + prevp->next * pool_cDataSize);
if (tmpp->size >= gpsp->fragmax) { if (tmpp->size >= gpsp->fragmax) {
if (tmpp->size == gpsp->fragmax) gpsp->fragmaxcnt++; if (tmpp->size == gpsp->fragmax) gpsp->fragmaxcnt++;
else { else {
...@@ -601,10 +605,10 @@ pool_Alloc ( ...@@ -601,10 +605,10 @@ pool_Alloc (
pr.m = pool_cNRef; pr.m = pool_cNRef;
pr.b.seg = psp->seg; pr.b.seg = psp->seg;
pr.b.offs = (pool_sData *)(ep+1) - (pool_sData *)psp->base; pr.b.offs = (pool_tOffset)((char *)ep + sizeof(pool_sEntry) - (char *)psp->base);
ep->next = pr.m; ep->next = pr.m;
return (void *)(ep+1); return (void *)(entryPAdd(ep, sizeof(pool_sEntry)));
} }
pwr_tBoolean pwr_tBoolean
...@@ -645,7 +649,7 @@ pool_AllocLookasideSegment ( ...@@ -645,7 +649,7 @@ pool_AllocLookasideSegment (
/* Allocate the section */ /* Allocate the section */
if (gpsp->generation == 0) { if (gpsp->generation == 0) {
esize = entryUnits(size) + 1; /* Add space for entry header. */ esize = entryUnits(size + sizeof(pool_sEntry)); /* Add space for entry header. */
psp = newSegment(sts, php, count * esize); psp = newSegment(sts, php, count * esize);
if (psp == NULL) return NO; if (psp == NULL) return NO;
gpsp = psp->gpsp; gpsp = psp->gpsp;
...@@ -657,7 +661,7 @@ pool_AllocLookasideSegment ( ...@@ -657,7 +661,7 @@ pool_AllocLookasideSegment (
gphp->la[gphp->la_idx].size = size; gphp->la[gphp->la_idx].size = size;
gphp->la_idx++; gphp->la_idx++;
for (i = 0, offs = 0; i < count - 1; i++) { for (i = 0, offs = 0; i < count - 1; i++) {
ep = psp->base + offs; ep = (pool_sEntry *)((char *)psp->base + offs * pool_cDataSize);
ep->size = esize; ep->size = esize;
offs += esize; offs += esize;
ep->next = offs; ep->next = offs;
...@@ -725,8 +729,8 @@ pool_Create ( ...@@ -725,8 +729,8 @@ pool_Create (
pwr_tStatus *sts, pwr_tStatus *sts,
pool_sHead *php, pool_sHead *php,
char *name, char *name,
pwr_tUInt32 initsize, size_t initsize,
pwr_tUInt32 extendsize size_t extendsize
) )
{ {
pwr_tStatus lsts; pwr_tStatus lsts;
...@@ -737,8 +741,8 @@ pool_Create ( ...@@ -737,8 +741,8 @@ pool_Create (
pool_sGhead *gphp; pool_sGhead *gphp;
pool_sHead *lphp = NULL; pool_sHead *lphp = NULL;
sect_sHead *shp; sect_sHead *shp;
pwr_tUInt32 alloc_size = 0; size_t alloc_size = 0;
pwr_tUInt32 alloced_size = 0; size_t alloced_size = 0;
if (php == NULL) php = lphp = (pool_sHead *) calloc(1, sizeof(*lphp)); if (php == NULL) php = lphp = (pool_sHead *) calloc(1, sizeof(*lphp));
if (php == NULL) if (php == NULL)
...@@ -867,7 +871,7 @@ pool_Free ( ...@@ -867,7 +871,7 @@ pool_Free (
ep = (pool_sEntry *) p; ep = (pool_sEntry *) p;
ep -= 1; /* Back to the header */ ep = entryPAdd( ep, -sizeof(pool_sEntry)); /* Back to the header */
if (p != pool_Address(&lsts, php, ep->next)) if (p != pool_Address(&lsts, php, ep->next))
errh_ReturnOrBugcheck(NO, sts, POOL__NOMARK, ""); errh_ReturnOrBugcheck(NO, sts, POOL__NOMARK, "");
...@@ -895,7 +899,7 @@ pool_FreeReference ( ...@@ -895,7 +899,7 @@ pool_FreeReference (
ep = (pool_sEntry *) pool_Address(&lsts, php, r); ep = (pool_sEntry *) pool_Address(&lsts, php, r);
ep -= 1; /* Back to the header */ ep = entryPAdd( ep, -sizeof(pool_sEntry)); /* Back to the header */
if (r != ep->next) if (r != ep->next)
errh_ReturnOrBugcheck(NO, sts, POOL__NOMARK, ""); errh_ReturnOrBugcheck(NO, sts, POOL__NOMARK, "");
...@@ -944,7 +948,7 @@ pool_InPool ( ...@@ -944,7 +948,7 @@ pool_InPool (
pr.m = 0; pr.m = 0;
pr.b.seg = psp->seg; pr.b.seg = psp->seg;
pr.b.offs = (pool_sData *)adrs - (pool_sData *)psp->base; pr.b.offs = (char *)adrs - (char *)psp->base;
if (pr.b.offs + size >= gpsp->size) break; if (pr.b.offs + size >= gpsp->size) break;
return pr.m; return pr.m;
} }
...@@ -969,7 +973,7 @@ pool_ItemReference ( ...@@ -969,7 +973,7 @@ pool_ItemReference (
) )
{ {
pwr_tStatus lsts; pwr_tStatus lsts;
pool_sEntry *pep = (pool_sEntry *)p - 1; pool_sEntry *pep = entryPAdd(p, -sizeof(pool_sEntry));
if (p == pool_Address(&lsts, php, pep->next)) if (p == pool_Address(&lsts, php, pep->next))
return pep->next; return pep->next;
...@@ -990,7 +994,7 @@ pool_Qalloc ( ...@@ -990,7 +994,7 @@ pool_Qalloc (
head = pool_Alloc(sts, php, sizeof(*head)); head = pool_Alloc(sts, php, sizeof(*head));
head->flink = head->blink = head->self = (((pool_sEntry *)head) - 1)->next; head->flink = head->blink = head->self = ((pool_sEntry *)entryPAdd(head,-sizeof(pool_sEntry)))->next;
return head; return head;
} }
...@@ -1401,7 +1405,7 @@ pool_RefAlloc ( ...@@ -1401,7 +1405,7 @@ pool_RefAlloc (
ep = pool_Alloc(sts, php, size); ep = pool_Alloc(sts, php, size);
if (ep == NULL) return pool_cNRef; if (ep == NULL) return pool_cNRef;
return (--ep)->next; return entryPAdd(ep, -sizeof(pool_sEntry))->next;
} }
/* Translate a virtual address to a pool reference. /* Translate a virtual address to a pool reference.
...@@ -1445,7 +1449,7 @@ pool_Reference ( ...@@ -1445,7 +1449,7 @@ pool_Reference (
pr.m = 0; pr.m = 0;
pr.b.seg = psp->seg; pr.b.seg = psp->seg;
pr.b.offs = (pool_sData *)adrs - (pool_sData *)psp->base; pr.b.offs = (char *)adrs - (char *)psp->base;
return pr.m; return pr.m;
} }
......
...@@ -32,14 +32,28 @@ ...@@ -32,14 +32,28 @@
and a maximum segment size of (1<<24) which is 16 Mb. Hence, the max and a maximum segment size of (1<<24) which is 16 Mb. Hence, the max
size of any pool is 256*16 Mbyte = 4 Gbyte! */ size of any pool is 256*16 Mbyte = 4 Gbyte! */
#if defined OS_LINUX && defined HW_X86_64
typedef pwr_tInt64 pool_tRef;
#define pool_cSegBits 10 /* Bits in segidx field */
#define pool_cOffsBits 54 /* Bits in offset field */
#define pool_cOffsAlign 3 /* Entry alignment */
#define pool_cOffsGranul 0 /* Entry granularity */
#else
typedef pwr_tInt32 pool_tRef;
#define pool_cSegBits 8 /* Bits in segidx field */ #define pool_cSegBits 8 /* Bits in segidx field */
#define pool_cOffsBits 24 /* Bits in offset field */ #define pool_cOffsBits 24 /* Bits in offset field */
#define pool_cOffsAlign 3 /* Entry alignment */ #define pool_cOffsAlign 3 /* Entry alignment */
#define pool_cOffsGranul 0 /* Entry granularity */ #define pool_cOffsGranul 0 /* Entry granularity */
#endif
#define pool_cSegs (1<<pool_cSegBits) /* Max number of segments in one directory. */ #define pool_cSegs (1<<pool_cSegBits) /* Max number of segments in one directory. */
#define pool_cMaxSize (1<<(pool_cOffsBits + pool_cOffsGranul)) #define pool_cMaxSize ((pool_tRef)1<<(pool_cOffsBits + pool_cOffsGranul))
#define pool_cMaxOffs (pool_cMaxSize-1) #define pool_cMaxOffs (pool_cMaxSize-1)
/* max size of a segment */ /* max size of a segment */
...@@ -50,7 +64,6 @@ ...@@ -50,7 +64,6 @@
that the lowest possible valid offset in any segment (as the that the lowest possible valid offset in any segment (as the
user sees it) is 1! */ user sees it) is 1! */
typedef ptrdiff_t pool_tRef;
#define pool_cNRef (pool_tRef)0 #define pool_cNRef (pool_tRef)0
typedef struct { typedef struct {
...@@ -62,6 +75,15 @@ typedef struct { ...@@ -62,6 +75,15 @@ typedef struct {
#define pool_QisUnlinked(a) ((a)->self == (a)->flink && (a)->self == (a)->blink) #define pool_QisUnlinked(a) ((a)->self == (a)->flink && (a)->self == (a)->blink)
/* Internal interpretation of a pool_tRef */ /* Internal interpretation of a pool_tRef */
#if defined OS_LINUX && defined HW_X86_64
typedef union {
struct { pwr_Endian_4 (
unsigned long int offs : pool_cOffsBits;, /* offset in section, in quadwords */
unsigned long int seg : pool_cSegBits;,, /* */
) } b;
pool_tRef m;
} pool_uRefBits;
#else
typedef union { typedef union {
struct { pwr_Endian_4 ( struct { pwr_Endian_4 (
pwr_Bits( offs, pool_cOffsBits), /* offset in section, in quadwords */ pwr_Bits( offs, pool_cOffsBits), /* offset in section, in quadwords */
...@@ -69,14 +91,15 @@ typedef union { ...@@ -69,14 +91,15 @@ typedef union {
) } b; ) } b;
pool_tRef m; pool_tRef m;
} pool_uRefBits; } pool_uRefBits;
#endif
typedef void *pool_tHead; typedef void *pool_tHead;
typedef struct { typedef struct {
char filler[1<<pool_cOffsGranul]; char filler[1<<pool_cOffsGranul];
} pool_sData; } pool_sData;
typedef pwr_tInt32 pool_tOffset; /* Segment offset, in pool_sData units */ static const int pool_cDataSize = 8;
typedef ptrdiff_t pool_tOffset; /* Segment offset, in pool_sData units */
#define pool_cNOffset (pool_tOffset)-1 /* where -1=>NULL */ #define pool_cNOffset (pool_tOffset)-1 /* where -1=>NULL */
...@@ -84,7 +107,7 @@ typedef pwr_tInt32 pool_tOffset; /* Segment offset, in pool_sData units */ ...@@ -84,7 +107,7 @@ typedef pwr_tInt32 pool_tOffset; /* Segment offset, in pool_sData units */
typedef struct { typedef struct {
pool_tOffset next; /* Next entry if free list, or mark */ pool_tOffset next; /* Next entry if free list, or mark */
pwr_tUInt32 size; /* Size of entry, in pool_sData units */ size_t size; /* Size of entry, in pool_sData units */
} pool_sEntry; } pool_sEntry;
typedef enum { typedef enum {
...@@ -153,7 +176,7 @@ void *pool_Address (pwr_tStatus*, pool_sHead*, pool_tRef); ...@@ -153,7 +176,7 @@ void *pool_Address (pwr_tStatus*, pool_sHead*, pool_tRef);
void *pool_Alloc (pwr_tStatus*, pool_sHead*, pwr_tUInt32); void *pool_Alloc (pwr_tStatus*, pool_sHead*, pwr_tUInt32);
pwr_tBoolean pool_AllocLookasideSegment (pwr_tStatus*, pool_sHead*, pwr_tUInt32, pwr_tUInt32); pwr_tBoolean pool_AllocLookasideSegment (pwr_tStatus*, pool_sHead*, pwr_tUInt32, pwr_tUInt32);
void *pool_AllocNamedSegment (pwr_tStatus*, pool_sHead*, pwr_tUInt32, char*); void *pool_AllocNamedSegment (pwr_tStatus*, pool_sHead*, pwr_tUInt32, char*);
pool_sHead *pool_Create (pwr_tStatus*, pool_sHead*, char*, pwr_tUInt32, pwr_tUInt32); pool_sHead *pool_Create (pwr_tStatus*, pool_sHead*, char*, size_t, size_t);
void pool_Dump (pwr_tStatus*, pool_sHead*); void pool_Dump (pwr_tStatus*, pool_sHead*);
pwr_tBoolean pool_Free (pwr_tStatus*, pool_sHead*, void*); pwr_tBoolean pool_Free (pwr_tStatus*, pool_sHead*, void*);
pwr_tBoolean pool_FreeReference (pwr_tStatus*, pool_sHead*, pool_tRef); pwr_tBoolean pool_FreeReference (pwr_tStatus*, pool_sHead*, pool_tRef);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment