various threading bugfixes

This commit is contained in:
Joel Dice
2007-11-27 15:23:00 -07:00
parent 56a5cf2503
commit 5fa7b074b4
4 changed files with 143 additions and 53 deletions

View File

@ -32,27 +32,79 @@ join(Thread* t, Thread* o)
} }
} }
unsigned
count(Thread* t, Thread* o)
{
unsigned c = 0;
if (t != o) ++ c;
for (Thread* p = t->peer; p; p = p->peer) {
c += count(p, o);
}
if (t->child) c += count(t->child, o);
return c;
}
Thread**
fill(Thread* t, Thread* o, Thread** array)
{
if (t != o) *(array++) = t;
for (Thread* p = t->peer; p; p = p->peer) {
array = fill(p, o, array);
}
if (t->child) array = fill(t->child, o, array);
return array;
}
void void
dispose(Thread* t, Thread* o, bool remove) dispose(Thread* t, Thread* o, bool remove)
{ {
if (remove) { if (remove) {
// debug
expect(t, find(t->m->rootThread, o));
unsigned c = count(t->m->rootThread, o);
Thread* threads[c];
fill(t->m->rootThread, o, threads);
// end debug
if (o->parent) { if (o->parent) {
if (o->child) { Thread* previous;
o->parent->child = o->child; for (Thread* p = o->parent->child; p;) {
if (o->peer) { if (p == o) {
o->peer->peer = o->child->peer; if (p == o->parent->child) {
o->child->peer = o->peer; o->parent->child = p->peer;
}
} else if (o->peer) {
o->parent->child = o->peer;
} else { } else {
o->parent->child = 0; previous->peer = p->peer;
}
break;
} else {
previous = p;
p = p->peer;
}
}
for (Thread* p = o->child; p;) {
Thread* next = p->peer;
p->peer = o->parent->child;
o->parent->child = p;
p->parent = o->parent;
p = next;
} }
} else if (o->child) { } else if (o->child) {
t->m->rootThread = o->child; t->m->rootThread = o->child;
if (o->peer) {
o->peer->peer = o->child->peer; for (Thread* p = o->peer; p;) {
o->child->peer = o->peer; Thread* next = p->peer;
p->peer = t->m->rootThread;
t->m->rootThread = p;
p = next;
} }
} else if (o->peer) { } else if (o->peer) {
t->m->rootThread = o->peer; t->m->rootThread = o->peer;
@ -60,7 +112,13 @@ dispose(Thread* t, Thread* o, bool remove)
abort(t); abort(t);
} }
assert(t, not find(t->m->rootThread, o)); // debug
expect(t, not find(t->m->rootThread, o));
for (unsigned i = 0; i < c; ++i) {
expect(t, find(t->m->rootThread, threads[i]));
}
// end debug
} }
o->dispose(); o->dispose();
@ -1290,12 +1348,17 @@ parseMethodTable(Thread* t, Stream& s, object class_, object pool)
if (declaredVirtualCount == 0 if (declaredVirtualCount == 0
and (classFlags(t, class_) & ACC_INTERFACE) == 0) and (classFlags(t, class_) & ACC_INTERFACE) == 0)
{ {
// inherit interface table and virtual table from superclass // inherit virtual table from superclass
set(t, class_, ClassVirtualTable, superVirtualTable);
if (classInterfaceTable(t, classSuper(t, class_))
and arrayLength(t, classInterfaceTable(t, class_))
== arrayLength(t, classInterfaceTable(t, classSuper(t, class_))))
{
// inherit interface table from superclass
set(t, class_, ClassInterfaceTable, set(t, class_, ClassInterfaceTable,
classInterfaceTable(t, classSuper(t, class_))); classInterfaceTable(t, classSuper(t, class_)));
}
set(t, class_, ClassVirtualTable, superVirtualTable);
} else if (virtualCount) { } else if (virtualCount) {
// generate class vtable // generate class vtable
@ -1892,6 +1955,7 @@ Thread::init()
#include "type-java-initializations.cpp" #include "type-java-initializations.cpp"
} }
} else { } else {
peer = parent->child;
parent->child = this; parent->child = this;
} }
@ -2048,6 +2112,8 @@ enter(Thread* t, Thread::State s)
case Thread::ExclusiveState: { case Thread::ExclusiveState: {
assert(t, t->m->exclusive == t); assert(t, t->m->exclusive == t);
t->m->exclusive = 0; t->m->exclusive = 0;
t->m->stateLock->notifyAll(t->systemThread);
} break; } break;
case Thread::ActiveState: break; case Thread::ActiveState: break;
@ -2632,7 +2698,7 @@ addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object))
} }
System::Monitor* System::Monitor*
objectMonitor(Thread* t, object o) objectMonitor(Thread* t, object o, bool createNew)
{ {
object p = hashMapFind(t, t->m->monitorMap, o, objectHash, objectEqual); object p = hashMapFind(t, t->m->monitorMap, o, objectHash, objectEqual);
@ -2644,7 +2710,7 @@ objectMonitor(Thread* t, object o)
} }
return static_cast<System::Monitor*>(pointerValue(t, p)); return static_cast<System::Monitor*>(pointerValue(t, p));
} else { } else if (createNew) {
PROTECT(t, o); PROTECT(t, o);
ENTER(t, Thread::ExclusiveState); ENTER(t, Thread::ExclusiveState);
@ -2665,6 +2731,8 @@ objectMonitor(Thread* t, object o)
addFinalizer(t, o, removeMonitor); addFinalizer(t, o, removeMonitor);
return m; return m;
} else {
return 0;
} }
} }

View File

@ -1998,12 +1998,12 @@ void
addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object)); addFinalizer(Thread* t, object target, void (*finalize)(Thread*, object));
System::Monitor* System::Monitor*
objectMonitor(Thread* t, object o); objectMonitor(Thread* t, object o, bool createNew);
inline void inline void
acquire(Thread* t, object o) acquire(Thread* t, object o)
{ {
System::Monitor* m = objectMonitor(t, o); System::Monitor* m = objectMonitor(t, o, true);
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "thread %p acquires %p for %x\n", fprintf(stderr, "thread %p acquires %p for %x\n",
@ -2016,7 +2016,7 @@ acquire(Thread* t, object o)
inline void inline void
release(Thread* t, object o) release(Thread* t, object o)
{ {
System::Monitor* m = objectMonitor(t, o); System::Monitor* m = objectMonitor(t, o, false);
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "thread %p releases %p for %x\n", fprintf(stderr, "thread %p releases %p for %x\n",
@ -2029,14 +2029,14 @@ release(Thread* t, object o)
inline void inline void
wait(Thread* t, object o, int64_t milliseconds) wait(Thread* t, object o, int64_t milliseconds)
{ {
System::Monitor* m = objectMonitor(t, o); System::Monitor* m = objectMonitor(t, o, false);
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "thread %p waits %"LLD" millis on %p for %x\n", fprintf(stderr, "thread %p waits %"LLD" millis on %p for %x\n",
t, milliseconds, m, objectHash(t, o)); t, milliseconds, m, objectHash(t, o));
} }
if (m->owner() == t->systemThread) { if (m and m->owner() == t->systemThread) {
ENTER(t, Thread::IdleState); ENTER(t, Thread::IdleState);
bool interrupted = m->wait(t->systemThread, milliseconds); bool interrupted = m->wait(t->systemThread, milliseconds);
@ -2058,14 +2058,14 @@ wait(Thread* t, object o, int64_t milliseconds)
inline void inline void
notify(Thread* t, object o) notify(Thread* t, object o)
{ {
System::Monitor* m = objectMonitor(t, o); System::Monitor* m = objectMonitor(t, o, false);
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "thread %p notifies on %p for %x\n", fprintf(stderr, "thread %p notifies on %p for %x\n",
t, m, objectHash(t, o)); t, m, objectHash(t, o));
} }
if (m->owner() == t->systemThread) { if (m and m->owner() == t->systemThread) {
m->notify(t->systemThread); m->notify(t->systemThread);
} else { } else {
t->exception = makeIllegalMonitorStateException(t); t->exception = makeIllegalMonitorStateException(t);
@ -2075,14 +2075,14 @@ notify(Thread* t, object o)
inline void inline void
notifyAll(Thread* t, object o) notifyAll(Thread* t, object o)
{ {
System::Monitor* m = objectMonitor(t, o); System::Monitor* m = objectMonitor(t, o, false);
if (DebugMonitors) { if (DebugMonitors) {
fprintf(stderr, "thread %p notifies all on %p for %x\n", fprintf(stderr, "thread %p notifies all on %p for %x\n",
t, m, objectHash(t, o)); t, m, objectHash(t, o));
} }
if (m->owner() == t->systemThread) { if (m and m->owner() == t->systemThread) {
m->notifyAll(t->systemThread); m->notifyAll(t->systemThread);
} else { } else {
t->exception = makeIllegalMonitorStateException(t); t->exception = makeIllegalMonitorStateException(t);

View File

@ -80,7 +80,7 @@ class MySystem: public System {
virtual void join() { virtual void join() {
int rv UNUSED = pthread_join(thread, 0); int rv UNUSED = pthread_join(thread, 0);
assert(s, rv == 0); expect(s, rv == 0);
} }
virtual void dispose() { virtual void dispose() {
@ -150,21 +150,32 @@ class MySystem: public System {
void append(Thread* t) { void append(Thread* t) {
if (last) { if (last) {
last->next = t; last->next = t;
last = t;
} else { } else {
first = last = t; first = last = t;
} }
} }
void remove(Thread* t) { void remove(Thread* t) {
for (Thread** p = &first; *p;) { Thread* previous;
if (t == *p) { for (Thread* current = first; current;) {
*p = t->next; if (t == current) {
if (last == t) { if (current == first) {
last = 0; first = t->next;
} else {
previous->next = t->next;
} }
if (current == last) {
last = previous;
}
t->next = 0;
break; break;
} else { } else {
p = &((*p)->next); previous = current;
current = current->next;
} }
} }
} }
@ -194,10 +205,10 @@ class MySystem: public System {
timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 }; timespec ts = { then / 1000, (then % 1000) * 1000 * 1000 };
int rv UNUSED = pthread_cond_timedwait int rv UNUSED = pthread_cond_timedwait
(&(t->condition), &(t->mutex), &ts); (&(t->condition), &(t->mutex), &ts);
assert(s, rv == 0 or rv == ETIMEDOUT or rv == EINTR); expect(s, rv == 0 or rv == ETIMEDOUT or rv == EINTR);
} else { } else {
int rv UNUSED = pthread_cond_wait(&(t->condition), &(t->mutex)); int rv UNUSED = pthread_cond_wait(&(t->condition), &(t->mutex));
assert(s, rv == 0 or rv == EINTR); expect(s, rv == 0 or rv == EINTR);
} }
pthread_mutex_lock(&mutex); pthread_mutex_lock(&mutex);
@ -227,7 +238,7 @@ class MySystem: public System {
t->flags |= Notified; t->flags |= Notified;
int rv UNUSED = pthread_cond_signal(&(t->condition)); int rv UNUSED = pthread_cond_signal(&(t->condition));
assert(s, rv == 0); expect(s, rv == 0);
} }
virtual void notify(System::Thread* context) { virtual void notify(System::Thread* context) {
@ -266,7 +277,7 @@ class MySystem: public System {
} }
virtual void dispose() { virtual void dispose() {
assert(s, owner_ == 0); expect(s, owner_ == 0);
pthread_mutex_destroy(&mutex); pthread_mutex_destroy(&mutex);
s->free(this); s->free(this);
} }
@ -283,7 +294,7 @@ class MySystem: public System {
public: public:
Local(System* s): s(s) { Local(System* s): s(s) {
int r UNUSED = pthread_key_create(&key, 0); int r UNUSED = pthread_key_create(&key, 0);
assert(s, r == 0); expect(s, r == 0);
} }
virtual void* get() { virtual void* get() {
@ -292,12 +303,12 @@ class MySystem: public System {
virtual void set(void* p) { virtual void set(void* p) {
int r UNUSED = pthread_setspecific(key, p); int r UNUSED = pthread_setspecific(key, p);
assert(s, r == 0); expect(s, r == 0);
} }
virtual void dispose() { virtual void dispose() {
int r UNUSED = pthread_key_delete(key); int r UNUSED = pthread_key_delete(key);
assert(s, r == 0); expect(s, r == 0);
s->free(this); s->free(this);
} }
@ -395,7 +406,7 @@ class MySystem: public System {
sa.sa_handler = handleSignal; sa.sa_handler = handleSignal;
int rv UNUSED = sigaction(InterruptSignal, &sa, 0); int rv UNUSED = sigaction(InterruptSignal, &sa, 0);
assert(this, rv == 0); expect(this, rv == 0);
} }
virtual bool success(Status s) { virtual bool success(Status s) {
@ -455,7 +466,7 @@ class MySystem: public System {
Thread* t = new (System::allocate(sizeof(Thread))) Thread(this, r); Thread* t = new (System::allocate(sizeof(Thread))) Thread(this, r);
r->attach(t); r->attach(t);
int rv UNUSED = pthread_create(&(t->thread), 0, run, r); int rv UNUSED = pthread_create(&(t->thread), 0, run, r);
assert(this, rv == 0); expect(this, rv == 0);
return 0; return 0;
} }

View File

@ -151,21 +151,32 @@ class MySystem: public System {
void append(Thread* t) { void append(Thread* t) {
if (last) { if (last) {
last->next = t; last->next = t;
last = t;
} else { } else {
first = last = t; first = last = t;
} }
} }
void remove(Thread* t) { void remove(Thread* t) {
for (Thread** p = &first; *p;) { Thread* previous;
if (t == *p) { for (Thread* current = first; current;) {
*p = t->next; if (t == current) {
if (last == t) { if (current == first) {
last = 0; first = t->next;
} else {
previous->next = t->next;
} }
if (current == last) {
last = previous;
}
t->next = 0;
break; break;
} else { } else {
p = &((*p)->next); previous = current;
current = current->next;
} }
} }
} }