home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Geek Gadgets 1
/
ADE-1.bin
/
ade-dist
/
kaffe-0.5p4-src.tgz
/
tar.out
/
contrib
/
kaffe
/
kaffevm
/
locks.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-09-28
|
3KB
|
191 lines
/*
* locks.c
* Manage locking system
* This include the mutex's and cv's.
*
* Copyright (c) 1996 Systems Architecture Research Centre,
* City University, London, UK.
*
* See the file "license.terms" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
* Written by Tim Wilkinson <tim@sarc.city.ac.uk>, February 1996.
*/
#include <assert.h>
#include "object.h"
#include "baseClasses.h"
#include "thread.h"
#include "locks.h"
#include "errors.h"
#include "exception.h"
#include "md.h"
extern thread* currentThread;
#if defined(HAVE_NATIVE_INT64)
jlong waitforever = -1;
#else
jlong waitforever = { -1, -1 };
#endif
#if defined(USE_INTERNAL_THREADS)
/*
* Lock a mutex.
*/
void
internalLockMutex(iMux* mux)
{
intsDisable();
if (mux->holder == 0) {
mux->holder = currentThread;
mux->count = 1;
}
else if (mux->holder == currentThread) {
mux->count++;
}
else {
while (mux->holder != 0) {
suspendOnQThread(currentThread, &mux->muxWaiters);
}
mux->holder = currentThread;
mux->count = 1;
}
intsRestore();
}
/*
* Release a mutex.
*/
void
internalUnlockMutex(iMux* mux)
{
thread* tid;
intsDisable();
assert(mux->holder == currentThread);
mux->count--;
if (mux->count == 0) {
mux->holder = 0;
if (mux->muxWaiters != 0) {
tid = mux->muxWaiters;
mux->muxWaiters = tid->next;
resumeThread(tid);
}
}
intsRestore();
}
/*
* Wait on a conditional variable.
* (timeout currently ignored)
*/
void
internalWaitCond(iMux* mux, iCv* cv, jlong timeout)
{
int count;
thread* tid;
if (mux->holder != currentThread) {
throwException(IllegalMonitorStateException);
}
intsDisable();
count = mux->count;
mux->holder = 0;
mux->count = 0;
cv->mux = mux;
/* If there's anyone waiting here, wake them up */
if (mux->muxWaiters != 0) {
tid = mux->muxWaiters;
mux->muxWaiters = tid->next;
resumeThread(tid);
}
/* Suspend, and keep suspended until I re-get the lock */
suspendOnQThread(currentThread, &cv->cvWaiters);
while (mux->holder != 0) {
suspendOnQThread(currentThread, &mux->muxWaiters);
}
mux->holder = currentThread;
mux->count = count;
intsRestore();
}
/*
* Wake one thread on a conditional variable.
*/
void
internalSignalCond(iCv* cv)
{
thread* tid;
/* If 'mux' isn't set then we've never waited on this object. */
if (cv->mux == 0) {
return;
}
if (cv->mux->holder != currentThread) {
throwException(IllegalMonitorStateException);
}
intsDisable();
/* Remove one thread from cv list */
if (cv->cvWaiters != 0) {
tid = cv->cvWaiters;
cv->cvWaiters = tid->next;
/* Place it on mux list */
tid->next = cv->mux->muxWaiters;
cv->mux->muxWaiters = tid;
}
intsRestore();
}
/*
* Wake all threads on a conditional variable.
*/
void
internalBroadcastCond(iCv* cv)
{
thread** tidp;
/* If 'mux' isn't set then we've never waited on this object. */
if (cv->mux == 0) {
return;
}
if (cv->mux->holder != currentThread) {
throwException(IllegalMonitorStateException);
}
intsDisable();
/* Find the end of the cv list */
if (cv->cvWaiters) {
for (tidp = &cv->cvWaiters; *tidp != 0; tidp = &(*tidp)->next)
;
/* Place entire cv list on mux list */
(*tidp) = cv->mux->muxWaiters;
cv->mux->muxWaiters = cv->cvWaiters;
cv->cvWaiters = 0;
}
intsRestore();
}
#endif