#ifndef __monitor_cc #define __monitor_cc /* Monitors for the Cray T3E */ #include "ti_config.h" #include "backend.h" #include "monitor.h" #include "ti-gc.h" #include "eregs.h" #include #include #include #include void monitor_destroy(titanium_monitor_t *m) { } #define BACKOFF_THRESHOLD 10 #define BACKOFF_WAIT_RAND 100 #define BACKOFF_WAIT_BASE 10 #define BACKOFF_WAIT_SHIFT 5 void monitor_enter(titanium_monitor_t *m, int proc) { long lock_held; /* Flush the Eregs so shmem calls can be made safely */ er_global_memory_sync(); /* Get the lock status and grab it if possible. */ lock_held = shmem_long_cswap(&m->lock_owner, NO_LOCK_OWNER, MYPROC, proc); /* Check if lock was not held by this process. */ if (lock_held != MYPROC) { int backoff; /* Wait on the lock if it was owned by another process. */ for (backoff = 0; (backoff < BACKOFF_THRESHOLD) && (lock_held != NO_LOCK_OWNER); backoff++) { /* If the lock was not free, poll the lock. */ lock_held = shmem_long_cswap(&m->lock_owner, NO_LOCK_OWNER, MYPROC, proc); } /* Back off */ while (lock_held != NO_LOCK_OWNER) { static void spin_loop(int); /* Spin for a time. */ spin_loop((BACKOFF_WAIT_BASE + rand() % BACKOFF_WAIT_RAND) << BACKOFF_WAIT_SHIFT); /* If the lock was not free, poll the lock. */ lock_held = shmem_long_cswap(&m->lock_owner, NO_LOCK_OWNER, MYPROC, proc); } } /* assert(shmem_long_cswap(&m->lock_owner,MYPROC,MYPROC,proc) == MYPROC); */ /* Increment nesting */ shmem_short_finc(&m->nesting, proc); /* Flush the Eregs */ er_global_memory_sync(); } void monitor_exit(titanium_monitor_t *m, int proc) { long lock_held; /* Flush the Eregs so shmem calls can be made safely */ er_global_memory_sync(); /* Get the lock status. */ lock_held = shmem_long_cswap(&m->lock_owner, MYPROC, MYPROC, proc); /* Check if the lock was owned by this process */ if (lock_held == MYPROC) { long nesting; /* Decrement the nesting level */ nesting = shmem_short_fadd(&m->nesting, -1, proc); if (nesting == 1) { /* If at the lowest nesting, free the lock. */ shmem_long_swap(&m->lock_owner, NO_LOCK_OWNER, proc); } } else { /* No-op for now. */ /* Error: Tried to exit a monitor that was not owned. */ } /* Flush the Eregs */ er_global_memory_sync(); } void monitor_wait(jGPointer monitor, ti_time_t *tm) { fprintf(stderr, "monitor_wait() is not implemented on the cray-t3e backend\n"); abort(); } void monitor_notify(jGPointer monitor) { fprintf(stderr, "monitor_notify() is not implemented on the cray-t3e backend\n"); abort(); } void monitor_notify_all(jGPointer monitor) { fprintf(stderr, "monitor_notify_all() is not implemented on the cray-t3e backend\n"); abort(); } /* Turn of the optimizer for the spin code. */ #pragma _CRI noopt static void spin_loop(int wait_length) { int wait_index; /* Spin for a while. */ for (wait_index = 0; wait_index < wait_length; wait_index++); } #pragma _CRI opt #endif /* __monitor_cc */