Now using a lock in prarena instead of compare-and-swap.

This commit is contained in:
bjorn%netscape.com 1998-09-23 20:19:28 +00:00
Родитель 728050bc38
Коммит d376dd5861
3 изменённых файлов: 39 добавлений и 29 удалений

Просмотреть файл

@ -80,7 +80,7 @@ js_InitGC(JSRuntime *rt, uint32 maxbytes)
gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString; gc_finalizers[GCX_STRING] = (GCFinalizeOp)js_FinalizeString;
gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble; gc_finalizers[GCX_DOUBLE] = (GCFinalizeOp)js_FinalizeDouble;
} }
PR_ArenaInit();
PR_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE, PR_InitArenaPool(&rt->gcArenaPool, "gc-arena", GC_ARENA_SIZE,
sizeof(JSGCThing)); sizeof(JSGCThing));
PR_InitArenaPool(&rt->gcFlagsPool, "gc-flags", GC_FLAGS_SIZE, PR_InitArenaPool(&rt->gcFlagsPool, "gc-flags", GC_FLAGS_SIZE,

Просмотреть файл

@ -29,11 +29,13 @@
#include "prassert.h" #include "prassert.h"
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
extern js_CompareAndSwap(prword *, prword, prword); #include "prlock.h"
#endif #endif
static PRArena *arena_freelist; static PRArena *arena_freelist=0;
#ifdef JS_THREADSAFE
static PRLock *arena_lock=0;
#endif
#ifdef PR_ARENAMETER #ifdef PR_ARENAMETER
static PRArenaStats *arena_stats_list; static PRArenaStats *arena_stats_list;
@ -67,9 +69,6 @@ PR_PUBLIC_API(void *)
PR_ArenaAllocate(PRArenaPool *pool, PRUint32 nb) PR_ArenaAllocate(PRArenaPool *pool, PRUint32 nb)
{ {
PRArena **ap, *a, *b; PRArena **ap, *a, *b;
#ifdef JS_THREADSAFE
PRArena *c;
#endif
PRUint32 sz; PRUint32 sz;
void *p; void *p;
@ -84,23 +83,25 @@ PR_ArenaAllocate(PRArenaPool *pool, PRUint32 nb)
a = a->next; a = a->next;
continue; continue;
} }
#ifdef JS_THREADSAFE
PR_Lock(arena_lock);
#endif
while ((b = *ap) != NULL) { /* reclaim a free arena */ while ((b = *ap) != NULL) { /* reclaim a free arena */
if (b->limit - b->base == pool->arenasize) { if (b->limit - b->base == pool->arenasize) {
#ifdef JS_THREADSAFE
do {
b = *ap;
c = b->next;
} while (!js_CompareAndSwap((prword *)ap,(prword)b,(prword)c));
#else
*ap = b->next; *ap = b->next;
#endif
b->next = NULL; b->next = NULL;
a = a->next = b; a = a->next = b;
COUNT(pool, nreclaims); COUNT(pool, nreclaims);
#ifdef JS_THREADSAFE
PR_Unlock(arena_lock);
#endif
goto claim; goto claim;
} }
ap = &b->next; ap = &b->next;
} }
#ifdef JS_THREADSAFE
PR_Unlock(arena_lock);
#endif
sz = PR_MAX(pool->arenasize, nb); /* allocate a new arena */ sz = PR_MAX(pool->arenasize, nb); /* allocate a new arena */
sz += sizeof *a + pool->mask; /* header and alignment slop */ sz += sizeof *a + pool->mask; /* header and alignment slop */
b = malloc(sz); b = malloc(sz);
@ -137,9 +138,6 @@ static void
FreeArenaList(PRArenaPool *pool, PRArena *head, PRBool reallyFree) FreeArenaList(PRArenaPool *pool, PRArena *head, PRBool reallyFree)
{ {
PRArena **ap, *a; PRArena **ap, *a;
#ifdef JS_THREADSAFE
PRArena *b;
#endif
ap = &head->next; ap = &head->next;
a = *ap; a = *ap;
@ -164,16 +162,16 @@ FreeArenaList(PRArenaPool *pool, PRArena *head, PRBool reallyFree)
} while ((a = *ap) != NULL); } while ((a = *ap) != NULL);
} else { } else {
/* Insert the whole arena chain at the front of the freelist. */ /* Insert the whole arena chain at the front of the freelist. */
#ifdef JS_THREADSAFE
PR_Lock(arena_lock);
#endif
do { do {
ap = &(*ap)->next; ap = &(*ap)->next;
} while (*ap); } while (*ap);
#ifdef JS_THREADSAFE
do {
*ap = b = arena_freelist;
} while (!js_CompareAndSwap((prword*)&arena_freelist,(prword)b,(prword)a));
#else
*ap = arena_freelist; *ap = arena_freelist;
arena_freelist = a; arena_freelist = a;
#ifdef JS_THREADSAFE
PR_Unlock(arena_lock);
#endif #endif
head->next = NULL; head->next = NULL;
} }
@ -237,24 +235,30 @@ PR_CompactArenaPool(PRArenaPool *pool)
#endif #endif
} }
PR_PUBLIC_API(void)
PR_ArenaInit()
{
#ifdef JS_THREADSAFE
arena_lock = PR_NewLock();
#endif
}
PR_PUBLIC_API(void) PR_PUBLIC_API(void)
PR_ArenaFinish() PR_ArenaFinish()
{ {
PRArena *a, *next; PRArena *a, *next;
#ifdef JS_THREADSAFE #ifdef JS_THREADSAFE
while (arena_freelist) { PR_Lock(arena_lock);
a = arena_freelist; #endif
next = a->next;
if (js_CompareAndSwap((prword*)&arena_freelist,(prword)a,(prword)next))
free(a);
}
#else
for (a = arena_freelist; a; a = next) { for (a = arena_freelist; a; a = next) {
next = a->next; next = a->next;
free(a); free(a);
} }
arena_freelist = NULL; arena_freelist = NULL;
#ifdef JS_THREADSAFE
PR_Unlock(arena_lock);
PR_DestroyLock(arena_lock);
#endif #endif
} }

Просмотреть файл

@ -187,6 +187,12 @@ PR_FinishArenaPool(PRArenaPool *pool);
extern PR_PUBLIC_API(void) extern PR_PUBLIC_API(void)
PR_CompactArenaPool(PRArenaPool *pool); PR_CompactArenaPool(PRArenaPool *pool);
/*
do arena global initialization
*/
extern PR_PUBLIC_API(void)
PR_ArenaInit(void);
/* /*
* Finish using arenas, freeing all memory associated with them. * Finish using arenas, freeing all memory associated with them.
*/ */