class GC {
public:
- // Critical section functions.
- static void critical_enter(void);
- static void critical_leave(void);
+};
+
+
+/**
+ * Critical section for the GC.
+ */
+class GCCriticalSection {
+public:
+ GCCriticalSection() { enter(); }
+ ~GCCriticalSection() { leave(); }
+
+ inline static void enter ();
+ inline static void leave ();
+ inline static bool inside();
};
* section, because each thread only modifies its own thread local flag
* and the GC reads the flags while the world is stopped.
*/
-inline void GC::critical_enter()
+void GCCriticalSection::enter()
{
#if defined(ENABLE_GC_CACAO)
- threadobject *t;
+ threadobject* t = thread_get_current();
+
+ // Sanity check.
+ assert(t->gc_critical == false);
- t = THREADOBJECT;
- assert(!t->gc_critical);
t->gc_critical = true;
#endif
}
* Leaves a LLNI critical section and allows the GC to move objects
* around on the collected heap again.
*/
-inline void GC::critical_leave()
+void GCCriticalSection::leave()
{
#if defined(ENABLE_GC_CACAO)
- threadobject *t;
+ threadobject* t = thread_get_current();
+
+ // Sanity check.
+ assert(t->gc_critical == true);
- t = THREADOBJECT;
- assert(t->gc_critical);
t->gc_critical = false;
#endif
}
+
+/**
+ * Checks if the calling thread is inside a GC critical section.
+ *
+ * @return true if inside, false otherwise.
+ */
+bool GCCriticalSection::inside()
+{
+#if defined(ENABLE_GC_CACAO)
+ threadobject* t = thread_get_current();
+ return t->gc_critical;
+#else
+ return true;
+#endif
+}
+
#endif
// Includes.
#include "vm/global.h"
-#include "vm/method.h"
+#include "vm/method.hpp"
/* function prototypes ********************************************************/