Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
- $Id: threads.c 4903 2006-05-11 12:48:43Z edwin $
-
*/
#include "config.h"
#include <stddef.h>
+#include <stdint.h>
#include "vm/types.h"
#include "toolbox/avl.h"
-#include "vm/jit/asmpart.h"
-
/* the AVL tree containing the critical sections */
/* prototypes *****************************************************************/
-static s4 critical_compare(const void *pa, const void *pb);
-static void critical_register_asm_critical_sections(void);
+static int critical_comparator(const void *treenode, const void *node);
/* critical_init ***************************************************************
void critical_init(void)
{
- criticaltree = avl_create(&critical_compare);
-
- critical_register_asm_critical_sections();
+ criticaltree = avl_create(&critical_comparator);
}
-/* critical_compare ************************************************************
+/* critical_comparator *********************************************************
Comparison function for AVL tree of critical section.
IN:
- pa...............first node
- pb...............second node
+ treenode....node in the tree
+ node........node to compare with tree-node
RETURN VALUE:
-1, 0, +1 for (pa <, ==, > pb)
*******************************************************************************/
-static s4 critical_compare(const void *pa, const void *pb)
+static int critical_comparator(const void *treenode, const void *node)
{
- const critical_section_node_t *na = pa;
- const critical_section_node_t *nb = pb;
+ const critical_section_node_t *treecsn;
+ const critical_section_node_t *csn;
- if (na->mcodebegin < nb->mcodebegin)
- return -1;
- if (na->mcodebegin > nb->mcodebegin)
- return 1;
- return 0;
-}
+ treecsn = treenode;
+ csn = node;
+#ifdef __S390__
+# define ADDR_MASK(x) ((u1 *)((s4)(x) & 0x7FFFFFFF))
+#else
+# define ADDR_MASK(x) (x)
+#endif
-/* critical_find ***************************************************************
-
- Find the critical region the given pc is in.
+ /* compare for avl_find if we have found an entry */
- IN:
- mcodeptr.........PC
+ if (
+ (ADDR_MASK(treecsn->start) <= ADDR_MASK(csn->start)) &&
+ (ADDR_MASK(csn->start) < ADDR_MASK(treecsn->end))
+ )
+ return 0;
- OUT:
- pointer to critical region node, or
- NULL if critical region was not found.
-
-*******************************************************************************/
+ /* these are for walking the tree */
-static const critical_section_node_t *critical_find(u1 *mcodeptr)
-{
- avl_node_t *n;
- const critical_section_node_t *m;
-
- n = criticaltree->root;
- m = NULL;
-
- if (!n)
- return NULL;
-
- for (;;) {
- const critical_section_node_t *d = n->data;
-
- if (mcodeptr == d->mcodebegin)
- return d;
-
- if (mcodeptr < d->mcodebegin) {
- if (n->childs[0]) {
- n = n->childs[0];
- }
- else {
- return m;
- }
- }
- else {
- if (n->childs[1]) {
- m = n->data;
- n = n->childs[1];
- }
- else {
- return n->data;
- }
- }
- }
+ if (ADDR_MASK(treecsn->start) < ADDR_MASK(csn->start))
+ return -1;
+ else
+ return 1;
+
+#undef ADDR_MASK
}
-/* critical_register_critical_section ******************************************
+/* critical_section_register ***************************************************
Register a critical section.
IN:
- n................node for the critical section
+ csn....node for the critical section
*******************************************************************************/
-void critical_register_critical_section(critical_section_node_t *n)
+void critical_section_register(critical_section_node_t *csn)
{
- (void) avl_insert(criticaltree, n);
+ (void) avl_insert(criticaltree, csn);
}
u1 *critical_find_restart_point(u1 *pc)
{
- const critical_section_node_t *n;
+ critical_section_node_t csnpc;
+ const critical_section_node_t *csn;
- n = critical_find(pc);
+ /* fill the temporary node for comparison */
- /* XXX should we check >= n->mcodebegin */
-
- if (n != NULL) {
- if ((pc > n->mcodebegin) && (pc < n->mcodeend))
- return n->mcoderestart;
- }
-
- return NULL;
-}
+ csnpc.start = pc;
+ /* see if there's an entry for that PC */
-/* critical_register_asm_critical_sections *************************************
+ csn = avl_find(criticaltree, &csnpc);
- Register critical sections defined in the array asm_criticalsections.
+ if (csn == NULL)
+ return NULL;
-*******************************************************************************/
-
-static void critical_register_asm_critical_sections(void)
-{
- /* XXX TWISTI: this is just a quick hack */
-#if defined(ENABLE_JIT) && defined(ENABLE_THREADS)
- critical_section_node_t *n = &asm_criticalsections;
-
- while (n->mcodebegin)
- critical_register_critical_section(n++);
-#endif
+ return csn->restart;
}