Main Page | Namespace List | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

objectutil.c

Go to the documentation of this file.
00001 /*!
00002  * @file objectutil.c
00003  *
00004  * @brief Utility and glue functions for
00005  * @link jvm/src/class.c class.c@endlink
00006  * and @c @b java.lang.Object
00007  *
00008  * Various functions in this file tend to get moved around between
00009  * @link jvm/src/threadutil.c threadutil.c@endlink and
00010  * @link jvm/src/threadutil.c classutil.c@endlink.
00011  *
00012  *
00013  * @internal Due to the fact that the implementation of the Java object
00014  * and the supporting robject structure is deeply embedded in the core
00015  * of the development of this software, this file has contents
00016  * that come and go during development.  Some functions get
00017  * staged here before deciding where they @e really go; some
00018  * are interim functions for debugging, some were glue that eventually
00019  * went away.  Be careful to remove prototypes to such functions
00020  * from the appropriate header file.
00021  *
00022  *
00023  * @section Control
00024  *
00025  * \$URL: https://svn.apache.org/path/name/objectutil.c $ \$Id: objectutil.c 0 09/28/2005 dlydick $
00026  *
00027  * Copyright 2005 The Apache Software Foundation
00028  * or its licensors, as applicable.
00029  *
00030  * Licensed under the Apache License, Version 2.0 ("the License");
00031  * you may not use this file except in compliance with the License.
00032  * You may obtain a copy of the License at
00033  *
00034  *     http://www.apache.org/licenses/LICENSE-2.0
00035  *
00036  * Unless required by applicable law or agreed to in writing,
00037  * software distributed under the License is distributed on an
00038  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
00039  * either express or implied.
00040  *
00041  * See the License for the specific language governing permissions
00042  * and limitations under the License.
00043  *
00044  * @version \$LastChangedRevision: 0 $
00045  *
00046  * @date \$LastChangedDate: 09/28/2005 $
00047  *
00048  * @author \$LastChangedBy: dlydick $
00049  *         Original code contributed by Daniel Lydick on 09/28/2005.
00050  *
00051  * @section Reference
00052  *
00053  */
00054 
00055 #include "arch.h"
00056 ARCH_COPYRIGHT_APACHE(objectutil, c, "$URL: https://svn.apache.org/path/name/objectutil.c $ $Id: objectutil.c 0 09/28/2005 dlydick $");
00057 
00058 
00059 #include "jvmcfg.h"
00060 #include "classfile.h"
00061 #include "jvm.h"
00062 #include "jvmclass.h"
00063 #include "linkage.h"
00064 
00065 
00066 /*!
00067  * @brief Attempt to @c @b synchronize() on an object's
00068  * monitor lock by contending for it.
00069  *
00070  * If acquired, stay in the @b RUNNING state.  If not, go to the
00071  * @b SYNCHRONIZED state and arbitrate for it in the @b LOCK state.
00072  *
00073  *
00074  * @param  objhashthis  Object table hash of @c @b this object.
00075  *
00076  * @param  thridx       Thread table index of a thread requesting
00077  *                      ownership of this object's monitor lock.
00078  *
00079  *
00080  * @returns @link #rtrue rtrue@endlink if this thread now owns
00081  *          this object's monitor lock,
00082  *          otherwise @link #rfalse rfalse@endlink.
00083  *
00084  *
00085  * @todo Make sure @b IllegalMonitorStateException logic covers all
00086  *       possibilities or needs to be removed.
00087  *
00088  * @todo Make sure thread interruption logic below here is working.
00089  *
00090  * @throws JVMCLASS_JAVA_LANG_NULLPOINTEREXCEPTION
00091  *         @link #JVMCLASS_JAVA_LANG_NULLPOINTEREXCEPTION
00092            if the object hash is the null object@endlink,
00093  *         typically due to bad input parameter.
00094  *
00095  * @throws JVMCLASS_JAVA_LANG_ILLEGALMONITORSTATEEXCEPTION
00096  *         @link #JVMCLASS_JAVA_LANG_ILLEGALMONITORSTATEEXCEPTION
00097 if current thread cannot possibly own the object's monitor lock@endlink,
00098  *         typically due to bad input parameter.
00099  *
00100  */
00101 
00102 rboolean objectutil_synchronize(jvm_object_hash  objhashthis,
00103                                 jvm_thread_index thridx)
00104 {
00105 #if 0
00106     /* If this thread cannot possibly own the object's monitor lock */
00107     if (some_condition)
00108     {
00109         thread_throw_exception(CURRENT_THREAD,
00110                                THREAD_STATUS_THREW_EXCEPTION,
00111                        JVMCLASS_JAVA_LANG_ILLEGALMONITORSTATEEXCEPTION);
00112 /*NOTREACHED*/
00113     }
00114 #endif
00115 
00116     /* Requested object must be in use and not null */
00117     if ((OBJECT_STATUS_INUSE & OBJECT(objhashthis).status)     &&
00118        ((!(OBJECT_STATUS_NULL & OBJECT(objhashthis).status))))
00119     {
00120         /* If nobody has it locked, */
00121         if ((!((OBJECT_STATUS_MLOCK & OBJECT(objhashthis).status))) ||
00122 
00123         /* or if I already own it  */
00124             ((OBJECT_STATUS_MLOCK & OBJECT(objhashthis).status) &&
00125              (OBJECT(objhashthis).mlock_thridx == CURRENT_THREAD)))
00126         {
00127             /*
00128              * Not currently locked, or currently own it anyway,
00129              * so take ownership.
00130              */
00131             OBJECT(objhashthis).status |= OBJECT_STATUS_MLOCK;
00132 
00133             OBJECT(objhashthis).mlock_count++;
00134 
00135             OBJECT(objhashthis).mlock_thridx = CURRENT_THREAD;
00136 
00137             /* No longer needed now that thread has ownership */
00138             THREAD(thridx).locktarget = jvm_object_hash_null;
00139 
00140             return(rtrue);
00141         }
00142         else
00143         {
00144             /*
00145              * If currently locked, tell thread model which object
00146              * is requested and go to @b SYNCHRONIZED to arbitrate
00147              * for the lock.
00148              */
00149             THREAD(thridx).locktarget = objhashthis;
00150 
00151             /*
00152              * This @e present function gets called later from
00153              * this @b SYNCHRONIZED @b REQUEST functino call, but
00154              * not until the state machine reaches the @b PROCESS
00155              * phase of the @b LOCK state (at a later time).  This
00156              * means that either this same @c @b else block
00157              * will get invoked again during lock arbitration in
00158              * the @b LOCK state or the opposite @c @b if
00159              * block will be called to acquire the MLOCK.  In both
00160              * cases, this present function will be invoked at
00161              * least once more before synchronization is complete.
00162              *
00163              */
00164             (rvoid) threadstate_request_synchronized(thridx);
00165 
00166             return(rfalse);
00167         }
00168     }
00169 
00170     /* This thread cannot possibly own the object's monitor lock */
00171     thread_throw_exception(CURRENT_THREAD,
00172                            THREAD_STATUS_THREW_EXCEPTION,
00173                            JVMCLASS_JAVA_LANG_NULLPOINTEREXCEPTION);
00174 /*NOTREACHED*/
00175     return(rfalse); /* Satisfy compiler */
00176 
00177 } /* END of objectutil_synchronize() */
00178 
00179 
00180 /*!
00181  * @brief Release @c @b synchronize from an object monitor lock.
00182  *
00183  *
00184  * @param  objhashthis  Object table hash of @c @b this object.
00185  *
00186  * @param  thridx       Thread table index of a thread requesting
00187  *                      to remove this object's monitor lock.
00188  *
00189  *
00190  * @attention Notice that the @link #rthread.locktarget
00191               locktarget@endlink is @b NOT cleared here!
00192  *            This is so that the value may be retained
00193  *            until the thread successfully arbitrates
00194  *            for ownership again in threadstate_process_lock().
00195  *            Once the MLOCK is reacquired there, the
00196  *            @link #rthread.locktarget locktarget@endlink will
00197  *            have been cleared by objectutil_synchronize().
00198  *            The purpose of objectutil_release() is to provide
00199  *            an avenue in the @b RUNNING state to release an MLOCK
00200  *            and set up @link #rthread.locktarget locktarget@endlink
00201  *            for the @b WAIT, @b NOTIFY, @b LOCK, @b ACQUIRE process.
00202  *
00203  * @returns @link #rvoid rvoid@endlink
00204  *
00205  *
00206  * @todo Make sure thread interruption logic below here is working.
00207  *
00208  *
00209  * @throws JVMCLASS_JAVA_LANG_ILLEGALMONITORSTATEEXCEPTION
00210  *         @link #JVMCLASS_JAVA_LANG_ILLEGALMONITORSTATEEXCEPTION
00211        if current thread does not own the object's monitor lock@endlink.
00212  *
00213  */
00214 rvoid objectutil_unsynchronize(jvm_object_hash  objhashthis,
00215                                jvm_thread_index thridx)
00216 {
00217     /* Requested object must be in use and not null */
00218     if ((!(OBJECT_STATUS_INUSE & OBJECT(objhashthis).status))     ||
00219         (OBJECT_STATUS_NULL & OBJECT(objhashthis).status))
00220     {
00221         /*! @todo Should the not INUSE condition cause INTERNALERROR? */
00222 
00223         thread_throw_exception(CURRENT_THREAD,
00224                                THREAD_STATUS_THREW_EXCEPTION,
00225                                JVMCLASS_JAVA_LANG_NULLPOINTEREXCEPTION);
00226 /*NOTREACHED*/
00227     }
00228 
00229     /* This thread must own the monitor lock in order to unlock it */
00230     if ((OBJECT_STATUS_MLOCK & OBJECT(objhashthis).status)    &&
00231         (thridx == (OBJECT(objhashthis).mlock_thridx)))
00232     {
00233         /* Decrement lock count and release MLOCK if done */
00234         OBJECT(objhashthis).mlock_count--;
00235 
00236         if (0 == OBJECT(objhashthis).mlock_count)
00237         {
00238             OBJECT(objhashthis).status       &= ~OBJECT_STATUS_MLOCK;
00239 
00240             OBJECT(objhashthis).mlock_thridx  = jvm_thread_index_null;
00241         }
00242         return;
00243     }
00244 
00245     /* This thread does not own the object's monitor lock */
00246     thread_throw_exception(CURRENT_THREAD,
00247                            THREAD_STATUS_THREW_EXCEPTION,
00248                        JVMCLASS_JAVA_LANG_ILLEGALMONITORSTATEEXCEPTION);
00249 /*NOTREACHED*/
00250     return; /* Satisfy compiler */
00251 
00252 } /* END of objectutil_unsynchronize() */
00253 
00254 
00255 /*!
00256  * @brief Attempt to @c @b wait() on an object's
00257  * monitor lock by releasing it and requesting @b RELEASE state.
00258  *
00259  * Save the MLOCK to be released for subsequent
00260  * processing by threadstate_request_release().
00261  *
00262  *
00263  * @param  objhashthis  Object table hash of @c @b this object.
00264  *
00265  * @param  thridx       Thread table index of a thread requesting
00266  *                      to release this object's monitor lock.
00267  *
00268  * @returns the result of threadstate_request_release()
00269  *
00270  */
00271 rboolean objectutil_release(jvm_object_hash  objhashthis,
00272                            jvm_thread_index thridx)
00273 {
00274     /* Preserve MLOCK object's hash for transition to next states */
00275     THREAD(thridx).locktarget = objhashthis;
00276 
00277     return(threadstate_request_release(thridx));
00278 
00279 } /* END of objectutil_release() */
00280 
00281 
00282 /* EOF */
00283 

Generated on Fri Sep 30 18:59:33 2005 by  doxygen 1.4.4