jdk/src/solaris/hpi/native_threads/src/monitor_md.c
changeset 7967 aa85f513e8f2
parent 7816 55a18147b4bf
child 7968 33304964ef5b
--- a/jdk/src/solaris/hpi/native_threads/src/monitor_md.c	Tue Jan 04 17:05:38 2011 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +0,0 @@
-/*
- * Copyright (c) 1994, 1998, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * Monitor implementation for Native Solaris threads
- *
- * Java Monitors are implemented using one solaris mutex and two
- * condition variables. Because solaris mutex is not re-entrant we
- * cannot simply have a monitor map to a mutex as re-entering a monitor
- * would deadlock an application.
- *
- * Monitor is implemented using:
- *   mutex_t             mutex;
- *   condvar_t           cv_monitor;
- *   condvar_t           cv_waiters;
- *
- * mutex protects the monitor state.
- * cv_monitor is the condtion variable used along with mutex for
- *     supporting wait and notify on the monitor.
- * cv_waiters is used for all the threads waiting to acquire the monitor
- *     lock.
- *
- * All of the sysMonitorXXX() functions that are passed a sys_mon_t
- * assume that they get something nonnull, and only check when debugging.
- */
-
-#include "hpi_impl.h"
-
-#include "threads_md.h"
-#include "monitor_md.h"
-
-#include <errno.h>
-#include <limits.h>
-
-static mutex_t contention_count_mutex;
-
-void initializeContentionCountMutex()
-{
-    mutexInit(&contention_count_mutex);
-}
-
-/*
- * Operations on monitors
- */
-/*
- * Return the size of the lib-dependent portion of monitors.  This
- * is done this way so that monitors can be all of one piece,
- * without paying the penalty of an extra level of indirection on
- * each sys_mon reference.  This is not how it is done for threads
- * and it might be a good idea to use a pointer the same way that
- * threads do.
- */
-size_t
-sysMonitorSizeof()
-{
-    return sizeof(struct sys_mon);
-}
-
-int
-sysMonitorInit(sys_mon_t *mid)
-{
-    int ret;
-
-    sysAssert(mid != SYS_MID_NULL);
-    ret = mutexInit(&mid->mutex);
-    ret = (ret == SYS_OK ? condvarInit(&mid->cv_monitor) : ret);
-
-    mid->entry_count = 0;
-    mid->monitor_owner = SYS_THREAD_NULL;
-    mid->contention_count = 0;
-    INIT_MONITOR_WAIT_QUEUE( mid->mwait_queue );
-
-    return ret;
-}
-
-/*
- * Free any system-dependent resources held by monitors.  There is
- * nothing to be done for native Solaris mutexes or condition variables.
- */
-int
-sysMonitorDestroy(sys_mon_t *mid)
-{
-    sysAssert(mid != SYS_MID_NULL);
-
-    return SYS_OK;
-}
-
-static void
-enqueue_me(monitor_waiter_t *mp, monitor_wait_queue_t *queue,
-           sys_thread_t *self)
-{
-    /*
-     * Order does not matter here. It is more convenient to
-     * enqueue ourselves at the head of the list, so we do so.
-     */
-    mp->waiting_thread = self;
-    mp->next = queue->head;
-    mp->prev = &(queue->head);
-    if ( queue->head != NULL ){
-        queue->head->prev = &(mp->next);
-    }
-    queue->head = mp;
-    queue->count++;
-}
-
-static void
-dequeue_me(monitor_waiter_t *mp, monitor_wait_queue_t *queue)
-{
-    queue->count--;
-    *(mp->prev) = mp->next;
-    if (mp->next != NULL ){
-        mp->next->prev = mp->prev;
-    }
-    mp->next = NULL;
-}
-
-int
-sysMonitorEnter(sys_thread_t *self, sys_mon_t *mid)
-{
-    int err;
-
-    sysAssert(mid != SYS_MID_NULL);
-    err = mutex_trylock(&mid->mutex);
-    if (err == 0) { /* no one owns it */
-        mid->monitor_owner = self;
-        mid->entry_count = 1;
-        return SYS_OK;
-    } else if (err == EBUSY) { /* it's already locked */
-        if (mid->monitor_owner == self) {
-            mid->entry_count++;
-            return SYS_OK;
-        } else {
-            self->mon_enter = mid;
-            /* block on it */
-            if (profiler_on) {
-                VM_CALL(monitorContendedEnter)(self, mid);
-                mutexLock(&contention_count_mutex);
-                mid->contention_count++;
-                mutexUnlock(&contention_count_mutex);
-            }
-            mutex_lock(&mid->mutex);
-            mid->monitor_owner = self;
-            mid->entry_count = 1;
-            self->mon_enter = NULL;
-            if (profiler_on) {
-                mutexLock(&contention_count_mutex);
-                mid->contention_count--;
-                mutexUnlock(&contention_count_mutex);
-                VM_CALL(monitorContendedEntered)(self, mid);
-            }
-            return SYS_OK;
-        }
-    } else {
-        sysAssert(err == 0);
-        return SYS_ERR;
-    }
-}
-
-/*
- * Return true if we currently own this monitor (and threads have been
- * initialized.
- */
-bool_t
-sysMonitorEntered(sys_thread_t *self, sys_mon_t *mid)
-{
-    sysAssert(mid != SYS_MID_NULL);
-
-    /* We can only have locked monitors if threads have been initialized */
-    return (mid->monitor_owner == self);
-}
-
-int
-sysMonitorExit(sys_thread_t *self, sys_mon_t *mid)
-{
-    sysAssert(mid != SYS_MID_NULL);
-
-    if (mid->monitor_owner == self) {
-        sysAssert(mid->entry_count > 0);
-        if (--mid->entry_count == 0) {
-            mid->monitor_owner = SYS_THREAD_NULL;
-            if (!mid->contention_count || !profiler_on) {
-                mutex_unlock(&mid->mutex);
-            } else {
-                mutex_unlock(&mid->mutex);
-                VM_CALL(monitorContendedExit)(self, mid);
-            }
-        }
-        return SYS_OK;
-    } else {
-        return SYS_ERR;
-    }
-}
-
-int
-sysMonitorNotify(sys_thread_t *self, sys_mon_t *mid)
-{
-    sysAssert(mid != SYS_MID_NULL);
-    if (self == mid->monitor_owner) {
-        if (ANY_WAITING(mid->mwait_queue)) {
-            /* If there is someone doing a monitor wait */
-            condvarSignal(&(mid->cv_monitor));
-        }
-        return SYS_OK;
-    } else
-        return SYS_ERR;
-}
-
-int
-sysMonitorNotifyAll(sys_thread_t *self, sys_mon_t *mid)
-{
-    sysAssert(mid != SYS_MID_NULL);
-    if (self == mid->monitor_owner) {
-        if (ANY_WAITING(mid->mwait_queue)) {
-            /* If there is someone doing a monitor wait */
-            condvarBroadcast(&(mid->cv_monitor));
-        }
-        return SYS_OK;
-    } else
-        return SYS_ERR;
-}
-
-int
-sysMonitorWait(sys_thread_t *self, sys_mon_t *mid, jlong millis)
-{
-    int ret = SYS_OK;
-    monitor_waiter_t me;
-    sysAssert(mid != SYS_MID_NULL);
-
-    if (self != mid->monitor_owner) {
-        return SYS_ERR;
-    }
-    if (sysThreadIsInterrupted(self, TRUE)) {
-        return SYS_INTRPT;
-    }
-
-    /* Prepare to wait: drop mutex ownership */
-    sysAssert(self->monitor_entry_count == 0);
-    sysAssert(self->mon_wait == 0);
-    self->mon_wait = (sys_mon_t *) mid;
-    self->monitor_entry_count = mid->entry_count;
-    mid->entry_count = 0;
-    mid->monitor_owner = SYS_THREAD_NULL;
-
-    /* Add myself to the monitor waitq */
-    enqueue_me(&me, &mid->mwait_queue, self);
-    if (millis == SYS_TIMEOUT_INFINITY) {
-        ret = condvarWait(&mid->cv_monitor, &mid->mutex, CONDVAR_WAIT);
-    } else {
-        ret = condvarTimedWait(&mid->cv_monitor, &mid->mutex, millis,
-                               CONDVAR_WAIT);
-    }
-    dequeue_me(&me, &mid->mwait_queue);
-
-    sysAssert(mid->monitor_owner == NULL);
-    sysAssert(mid->entry_count == 0);
-    mid->monitor_owner = self;
-    mid->entry_count = self->monitor_entry_count;
-    self->monitor_entry_count = 0;
-    self->mon_wait = 0;
-
-    /* Did we get interrupted in mid-wait?  (IS THIS THE RIGHT PLACE?) */
-    if (sysThreadIsInterrupted(self, TRUE)) {
-        return SYS_INTRPT;
-    }
-
-    return ret;
-}
-
-static int
-dumpWaitingQueue(monitor_wait_queue_t *queue, sys_thread_t **waiters, int sz)
-{
-    int n;
-    monitor_waiter_t * waiter;
-    if (queue == NULL || ( waiter = queue->head ) == NULL ) {
-        return 0;
-    }
-    for (n = 0; waiter != 0; waiter = waiter->next, n++, sz--) {
-        if (sz > 0) {
-            waiters[n] = waiter->waiting_thread;
-        }
-    }
-    return n;
-}
-
-typedef struct {
-    sys_mon_t *mid;
-    sys_thread_t **waiters;
-    int sz;
-    int nwaiters;
-} wait_info;
-
-static int
-findWaitersHelper(sys_thread_t *t, void *arg)
-{
-    wait_info * winfo = (wait_info *) arg;
-    if (t->mon_enter == winfo->mid) {
-        if (winfo->sz > 0) {
-            winfo->waiters[winfo->nwaiters] = t;
-        }
-        winfo->sz--;
-        winfo->nwaiters++;
-    }
-    return SYS_OK;
-}
-
-int
-sysMonitorGetInfo(sys_mon_t *mid, sys_mon_info *info)
-{
-    wait_info winfo;
-
-    sysAssert(mid != SYS_MID_NULL);
-    info->owner = mid->monitor_owner;
-    if (mid->monitor_owner) {
-        info->entry_count = mid->entry_count;
-    }
-
-    winfo.mid = mid;
-    winfo.nwaiters = 0;
-    winfo.waiters = info->monitor_waiters;
-    winfo.sz = info->sz_monitor_waiters;
-    sysThreadEnumerateOver(findWaitersHelper, (void *) &winfo);
-    info->n_monitor_waiters = winfo.nwaiters;
-
-    info->n_condvar_waiters = dumpWaitingQueue(&mid->mwait_queue,
-                                               info->condvar_waiters,
-                                               info->sz_condvar_waiters);
-
-    return SYS_OK;
-}
-
-
-bool_t
-sysMonitorInUse(sys_mon_t * mon)
-{
-    return mon->monitor_owner != 0 ||
-        mon->mwait_queue.count != 0;
-}
-
-sys_thread_t *
-sysMonitorOwner(sys_mon_t *mon)
-{
-    return mon->monitor_owner;
-}