aboutsummaryrefslogtreecommitdiff
path: root/libgm2/libm2iso/RTco.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libgm2/libm2iso/RTco.cc')
-rw-r--r--libgm2/libm2iso/RTco.cc117
1 files changed, 64 insertions, 53 deletions
diff --git a/libgm2/libm2iso/RTco.cc b/libgm2/libm2iso/RTco.cc
index 8b8a4dc..33da586 100644
--- a/libgm2/libm2iso/RTco.cc
+++ b/libgm2/libm2iso/RTco.cc
@@ -32,8 +32,9 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#include <m2rts.h>
#include <cstdio>
-#define EXPORT(FUNC) RTco_ ## FUNC
-#define M2EXPORT(FUNC) _M2_RTco_ ## FUNC
+#define EXPORT(FUNC) m2iso ## _RTco_ ## FUNC
+#define M2EXPORT(FUNC) m2iso ## _M2_RTco_ ## FUNC
+#define M2LIBNAME "m2iso"
/* This implementation of RTco.cc uses a single lock for mutex across
the whole module. It also forces context switching between threads
@@ -104,12 +105,9 @@ static threadSem **semArray = NULL;
static __gthread_mutex_t lock; /* This is the only mutex for
the whole module. */
static int initialized = FALSE;
-static int currentThread = 0;
-
extern "C" int EXPORT(init) (void);
-
extern "C" void
M2EXPORT(dep) (void)
{
@@ -184,8 +182,8 @@ newSem (void)
= (threadSem *)malloc (sizeof (threadSem));
nSemaphores += 1;
if (nSemaphores == SEM_POOL)
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "too many semaphores created");
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "too many semaphores created");
#else
threadSem *sem
= (threadSem *)malloc (sizeof (threadSem));
@@ -233,6 +231,18 @@ EXPORT(initSemaphore) (int value)
return sid;
}
+static int
+currentThread (void)
+{
+ int tid;
+
+ for (tid = 0; tid < nThreads; tid++)
+ if (pthread_self () == threadArray[tid].p)
+ return tid;
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "failed to find currentThread");
+}
+
extern "C" int
EXPORT(currentThread) (void)
{
@@ -240,7 +250,7 @@ EXPORT(currentThread) (void)
EXPORT(init) ();
__gthread_mutex_lock (&lock);
- tid = currentThread;
+ tid = currentThread ();
tprintf ("currentThread %d\n", tid);
__gthread_mutex_unlock (&lock);
return tid;
@@ -253,9 +263,10 @@ EXPORT(currentInterruptLevel) (void)
{
EXPORT(init) ();
__gthread_mutex_lock (&lock);
+ int current = currentThread ();
tprintf ("currentInterruptLevel %d\n",
- threadArray[currentThread].interruptLevel);
- int level = threadArray[currentThread].interruptLevel;
+ threadArray[current].interruptLevel);
+ int level = threadArray[current].interruptLevel;
__gthread_mutex_unlock (&lock);
return level;
}
@@ -268,9 +279,10 @@ EXPORT(turnInterrupts) (unsigned int newLevel)
{
EXPORT(init) ();
__gthread_mutex_lock (&lock);
- unsigned int old = threadArray[currentThread].interruptLevel;
+ int current = currentThread ();
+ unsigned int old = threadArray[current].interruptLevel;
tprintf ("turnInterrupts from %d to %d\n", old, newLevel);
- threadArray[currentThread].interruptLevel = newLevel;
+ threadArray[current].interruptLevel = newLevel;
__gthread_mutex_unlock (&lock);
return old;
}
@@ -278,8 +290,8 @@ EXPORT(turnInterrupts) (unsigned int newLevel)
static void
never (void)
{
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "the main thread should never call here");
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "the main thread should never call here");
}
static void *
@@ -313,10 +325,10 @@ execThread (void *t)
__gthread_mutex_unlock (&lock);
tp->proc (); /* Now execute user procedure. */
#if 0
- M2RTS_CoroutineException ( __FILE__, __LINE__, __COLUMN__, __FUNCTION__, "coroutine finishing");
+ m2iso_M2RTS_CoroutineException ( __FILE__, __LINE__, __COLUMN__, __FUNCTION__, "coroutine finishing");
#endif
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "execThread should never finish");
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "execThread should never finish");
return NULL;
}
@@ -326,8 +338,8 @@ newThread (void)
#if defined(POOL)
nThreads += 1;
if (nThreads == THREAD_POOL)
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "too many threads created");
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "too many threads created");
return nThreads - 1;
#else
if (nThreads == 0)
@@ -364,15 +376,15 @@ initThread (void (*proc) (void), unsigned int stackSize,
/* Set thread creation attributes. */
result = pthread_attr_init (&attr);
if (result != 0)
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "failed to create thread attribute");
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "failed to create thread attribute");
if (stackSize > 0)
{
result = pthread_attr_setstacksize (&attr, stackSize);
if (result != 0)
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "failed to set stack size attribute");
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "failed to set stack size attribute");
}
tprintf ("initThread [%d] function = 0x%p (arg = 0x%p)\n", tid, proc,
@@ -380,7 +392,7 @@ initThread (void (*proc) (void), unsigned int stackSize,
result = pthread_create (&threadArray[tid].p, &attr, execThread,
(void *)&threadArray[tid]);
if (result != 0)
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__, "thread_create failed");
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__, "thread_create failed");
tprintf (" created thread [%d] function = 0x%p 0x%p\n", tid, proc,
(void *)&threadArray[tid]);
return tid;
@@ -408,62 +420,61 @@ EXPORT(transfer) (int *p1, int p2)
{
__gthread_mutex_lock (&lock);
{
+ int current = currentThread ();
if (!initialized)
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "cannot transfer to a process before the process has been created");
- if (currentThread == p2)
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "cannot transfer to a process before the process has been created");
+ if (current == p2)
{
/* Error. */
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "attempting to transfer to ourself");
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "attempting to transfer to ourself");
}
else
{
- *p1 = currentThread;
- int old = currentThread;
- tprintf ("start, context switching from: %d to %d\n", currentThread, p2);
+ *p1 = current;
+ int old = current;
+ tprintf ("start, context switching from: %d to %d\n", current, p2);
/* Perform signal (p2 sem). Without the mutex lock as we have
already obtained it above. */
if (threadArray[p2].waiting)
{
/* p2 is blocked on the condition variable, release it. */
- tprintf ("p1 = %d cond_signal to p2 (%d)\n", currentThread, p2);
+ tprintf ("p1 = %d cond_signal to p2 (%d)\n", current, p2);
__gthread_cond_signal (&threadArray[p2].run_counter);
- tprintf ("after p1 = %d cond_signal to p2 (%d)\n", currentThread, p2);
+ tprintf ("after p1 = %d cond_signal to p2 (%d)\n", current, p2);
}
else
{
/* p2 hasn't reached the condition variable, so bump value
ready for p2 to test. */
tprintf ("no need for thread %d to cond_signal - bump %d value (pre) = %d\n",
- currentThread, p2, threadArray[p2].value);
+ current, p2, threadArray[p2].value);
threadArray[p2].value++;
}
/* Perform wait (old sem). Again without obtaining mutex as
we've already claimed it. */
if (threadArray[old].value == 0)
{
- currentThread = p2;
/* Record we are about to wait on the condition variable. */
threadArray[old].waiting = true;
__gthread_cond_wait (&threadArray[old].run_counter, &lock);
threadArray[old].waiting = false;
/* We are running again. */
- currentThread = old;
}
else
{
tprintf ("(currentThread = %d) no need for thread %d to cond_wait - taking value (pre) = %d\n",
- currentThread, old, threadArray[old].value);
+ current, old, threadArray[old].value);
/* No need to block as we have been told a signal has
effectively already been recorded. We remove the signal
notification without blocking. */
threadArray[old].value--;
}
- tprintf ("end, context back to %d\n", currentThread);
- if (currentThread != old)
- M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
- "wrong process id");
+ tprintf ("end, context back to %d\n", current);
+ if (current != old)
+ m2iso_M2RTS_HaltC (__FILE__, __LINE__, __FUNCTION__,
+ "wrong process id");
}
}
__gthread_mutex_unlock (&lock);
@@ -494,15 +505,15 @@ EXPORT(init) (void)
semArray = (threadSem **)malloc (sizeof (threadSem *) * SEM_POOL);
#endif
/* Create a thread control block for the main program (or process). */
- currentThread = newThread (); /* For the current initial thread. */
- threadArray[currentThread].p = pthread_self ();
- threadArray[currentThread].tid = currentThread;
- __GTHREAD_COND_INIT_FUNCTION (&threadArray[currentThread].run_counter);
- threadArray[currentThread].interruptLevel = 0;
+ int tid = newThread (); /* For the current initial thread. */
+ threadArray[tid].p = pthread_self ();
+ threadArray[tid].tid = tid;
+ __GTHREAD_COND_INIT_FUNCTION (&threadArray[tid].run_counter);
+ threadArray[tid].interruptLevel = 0;
/* The line below shouldn't be necessary as we are already running. */
- threadArray[currentThread].proc = never;
- threadArray[currentThread].waiting = false; /* We are running. */
- threadArray[currentThread].value = 0; /* No signal from anyone yet. */
+ threadArray[tid].proc = never;
+ threadArray[tid].waiting = false; /* We are running. */
+ threadArray[tid].value = 0; /* No signal from anyone yet. */
tprintf ("RTco initialized completed\n");
__gthread_mutex_unlock (&lock);
}
@@ -512,7 +523,7 @@ EXPORT(init) (void)
extern "C" void __attribute__((__constructor__))
M2EXPORT(ctor) (void)
{
- M2RTS_RegisterModule ("RTco",
- M2EXPORT(init), M2EXPORT(fini),
- M2EXPORT(dep));
+ m2iso_M2RTS_RegisterModule ("RTco", M2LIBNAME,
+ M2EXPORT(init), M2EXPORT(fini),
+ M2EXPORT(dep));
}