Closed Bug 41381 Opened 24 years ago Closed 24 years ago

JSArena arena_freelist thread safety problems

Categories

(Core :: JavaScript Engine, defect, P1)

defect

Tracking

()

VERIFIED FIXED

People

(Reporter: brendan, Assigned: brendan)

References

(Blocks 1 open bug, )

Details

(Keywords: js1.5)

Attachments

(10 files)

Where do I start?  Assuming addresses won't be replayed by malloc across a
compare and swap is one biggie.  Is there any "lock-free" way to maintain this
linked list?  I'm beginning to suspect not.

/be
Mine all mine.

/be
Status: NEW → ASSIGNED
Keywords: js1.5
Target Milestone: --- → M16
I remember we fixed this in NSPR by adding a lock
around arena_freelist.  Is that not thread safe,
or are you going after a lock-free solution?

On Alpha and PowerPC (and MIPS too, I think), you
can use load-locked and store-conditional, which
don't have the "ABA" problem of compare-and-swap.
Unfortunately Intel x86 and Sparc only have
compare-and-swap.
I was hoping for lock-free, but a lock will do.  It should not be contentious,
either (my best guess), but we'll have to measure to be sure.  JS uses arenas
for compiler temporaries and for runtime stacks.  But it uses large enough sizes
that I believe it won't be allocating and freeing frequently.

/be
This'll be fixed soon.

/be
Target Milestone: M16 → M17
Priority: P3 → P1
I reviewed the "final patch" (attachment id=11271).
Note that I only reviewed the portion related to arena_freelist_lock.

1. In jsarena.c, function JS_ArenaShutDown has two problems.
   First, arena_freelist is apparently a typo for arena_freelist_lock.
   Second, arena_freelist_lock is defined only if JS_THREADSAFE is
   defined, so all this code should be ifdef'd with JS_THREADSAFE.

2. jsarena.h: just wondering why you add a new function JS_ArenaShutDown
   rather than just destroying arena_freelist_lock in JS_ArenaFinish.
Thanks, wtc.  Re: 1 -- augh!  I thought I had built this code before attaching
the patch.  I think I built only the JS shell, which is !JS_THREADSAFE, so the
JS_DESTROY_LOCK macro does nothing and there is no compile-time error.

Re: 2, the problem I face with how this old code is used in JS is this:
JS_ArenaFinish is called often, via JS_GC (js_ForceGC).  It wants to free all
arenas cached on the freelist.  Maybe it should be called JS_FlushArenaFreeList
or some such.  There is no JS_ArenaStartUp or JS_ArenaShutDown code in the
current top of trunk, however.  Per-process init has been implicit, and can
continue to be so long as the first thread to call JS_InitArenaPool does not
race with any other thread.

So in order to minimize changes, I'm keeping per-process init (let's call it
"StartUp") implicit.  But I can't destroy the arena_freelit_lock in
JS_ArenaFinish, without opening a race to recreate the lock.  Besides, it
doesn't hurt to keep that lock around while JS is embedded.  But we must free
that lock at "ShutDown" time, hence the new JS_ArenaShutDown.

Thanks again for your comments, keep them coming if you have more.  New patch
coming up.

/be
Attached patch I give upSplinter Review
I reviewed patch id=11308.  I found that we
can write JS_ArenaFinish like this to make
the critical section shorter:

JS_PUBLIC_API(void)
JS_ArenaFinish()
{
    JSArena *a, *next;

    JS_ACQUIRE_LOCK(arena_freelist_lock);
    a = arena_freelist;
    arena_freelist = NULL;
    JS_RELEASE_LOCK(arena_freelist_lock);
    for ( ; a; a = next) {
        next = a->next;
        free(a);
    }
}

You may want to replace the for loop by a while
loop depending on your taste.
I filed bug 45343 on plarena.[ch] in NSPR, for inheriting similar bugs from the
old NSPR1 code.

/be
Last (must be final?) patch checked in.  Thanks especially to troy and wtc.

/be
That crazy for loop in JS_ArenaAllocate got me: I tried to break out of it early
when inverting the if (a->next) {...;continue;} clause and what followed, which
fails to update pool->current = a.  Bad things ensue.  Ultimate Mega Turbo patch
coming up.

/be
Fix checked in.

/be
Status: ASSIGNED → RESOLVED
Closed: 24 years ago
Resolution: --- → FIXED
There's a subtle bug in the jsarena.c change that can bust the JS GC.  Patch for
that regression coming up.

/be
Status: RESOLVED → REOPENED
Resolution: FIXED → ---
Adding jband, who ran into the regression in xpcshell.

/be
Status: REOPENED → ASSIGNED
Looking for r= here, quick, before too many people are hosed.

/be
Jband tested and reviewed, I'm in.  Shoot me now!

/be
Status: ASSIGNED → RESOLVED
Closed: 24 years ago24 years ago
something happened to the resolution...
Status: RESOLVED → REOPENED
marking fixed
Status: REOPENED → RESOLVED
Closed: 24 years ago24 years ago
Resolution: --- → FIXED
Blocks: 45343
Rubber-stamp Verify - 
Status: RESOLVED → VERIFIED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: