#ifndef __monitor_c #define __monitor_c #include #include #include #include #include #include #if DEBUG_MONITORS #undef NDEBUG #include #define ASSERT(x) assert(x) #else #define ASSERT(x) #endif static ti_lock_t monitor_creation_lock = ti_lock_decl_initializer; void monitor_startup() { TIC_BEGIN_FUNCTION COMM_GetMyProcess()->locked_monitors = NULL; COMM_GetMyProcess()->pmt_freelist = NULL; /* we never currently use these fields for shared-memory, but what the hell.. */ COMM_GetMyProcess()->signal_proc = (Process)-1; COMM_GetMyProcess()->signal_box = (Process)-1; COMM_GetMyProcess()->waiting_for_monitor = 0; } void monitor_destroy(tic_monitor_t *pmon) { tic_monitor_t mon; if (pmon != NULL && (mon = *pmon) != NULL) { ti_lock_destroy(&(mon->lock)); ti_cond_destroy(&(mon->condvar)); ti_free(mon); *pmon = NULL; } } void monitor_enter(jGPointer monitor) { TIC_BEGIN_FUNCTION #ifndef MEMORY_SHARED return; #else tic_monitor_t *pmon = (tic_monitor_t *)TO_LOCAL(monitor); tic_monitor_t mon = *pmon; if (!mon) { /* first use - need to init monitor */ ti_lock(&monitor_creation_lock); mon = *pmon; if (!mon) { mon = (tic_monitor_t)ti_malloc(sizeof(struct tic_monitor_t)); monitor_init_inner(mon); tic_local_wmb(); /* PR809: order matters here */ *pmon = mon; } else tic_local_rmb(); /* PR809: needed when other thread has just created mon */ ti_unlock(&monitor_creation_lock); } else tic_local_rmb(); /* PR809: needed when other thread has just created mon */ /* Do I already own it? */ if (mon->proc == MYPROC) { mon->nesting++; return; } ti_lock(&(mon->lock)); ASSERT(mon->proc == (Process)-1); ASSERT(mon->nesting == 0); mon->proc = MYPROC; mon->nesting = 1; COMM_thread_cons_monitor(myProcess(), monitor); #endif /* NO_SMP */ } void monitor_exit(jGPointer monitor) { TIC_BEGIN_FUNCTION #ifndef MEMORY_SHARED return; #else tic_monitor_t *pmon = (tic_monitor_t *)TO_LOCAL(monitor); tic_monitor_t mon = *pmon; /* Do I own it? */ if (mon->proc == MYPROC) { if (mon->nesting > 1) { mon->nesting--; return; } else { ASSERT(mon->nesting == 1); mon->nesting = 0; mon->proc = (Process)-1; COMM_thread_remove_monitor(myProcess(), monitor); ti_unlock(&(mon->lock)); return; } } else { /* I can't NOT own it, by the matching semantics of monitors */ ASSERT(0); abort(); } #endif /* NO_SMP */ } void monitor_wait(jGPointer monitor, ti_time_t *tm) { TIC_BEGIN_FUNCTION #ifndef MEMORY_SHARED return; #else int oldnesting; tic_monitor_t *pmon = (tic_monitor_t *)TO_LOCAL(monitor); tic_monitor_t mon = *pmon; /* Do I own it? */ if (mon->proc == MYPROC) { /* Therefore, I own the condvarlock too. */ ASSERT(mon->nesting > 0); oldnesting = mon->nesting; mon->nesting = 0; mon->proc = (Process)-1; COMM_thread_remove_monitor(myProcess(), monitor); if (tm == NULL) ti_mon_wait(mon); else ti_mon_timedwait(mon, tm); ASSERT(mon->proc == (Process)-1); ASSERT(mon->nesting == 0); COMM_thread_cons_monitor(myProcess(), monitor); mon->proc = MYPROC; mon->nesting = oldnesting; } else { tossMonitorStateException_str("Tried to wait on a lock you didn't own.\n"); abort(); } #endif /* NO_SMP */ } void notify_waiter(tic_monitor_t mon) { #ifndef MEMORY_SHARED return; #else ASSERT(mon->proc == MYPROC); ASSERT(mon->nesting > 0); ti_mon_signal(mon); #endif /* NO_SMP */ } void notify_waiters(tic_monitor_t mon) { #ifndef MEMORY_SHARED return; #else ASSERT(mon->proc == MYPROC); ASSERT(mon->nesting > 0); ti_mon_broadcast(mon); #endif /* NO_SMP */ } void monitor_notify(jGPointer monitor) { TIC_BEGIN_FUNCTION #ifndef MEMORY_SHARED return; #else tic_monitor_t *pmon = (tic_monitor_t *)TO_LOCAL(monitor); tic_monitor_t mon = *pmon; /* Do I already own it? */ if (mon->proc == MYPROC) { ASSERT(mon->nesting > 0); notify_waiter(mon); return; } else { tossMonitorStateException_str("Tried to notify a lock you didn't own.\n"); abort(); } #endif /* NO_SMP */ } void monitor_notify_all(jGPointer monitor) { TIC_BEGIN_FUNCTION #ifndef MEMORY_SHARED return; #else tic_monitor_t *pmon = (tic_monitor_t *)TO_LOCAL(monitor); tic_monitor_t mon = *pmon; /* Do I already own it? */ if (mon->proc == MYPROC) { ASSERT(mon->nesting > 0); notify_waiters(mon); return; } else { tossMonitorStateException_str("Tried to notify a lock you didn't own.\n"); abort(); } #endif /* NO_SMP */ } #endif /* __monitor_c */