objsync.c

来自「This is a resource based on j2me embedde」· C语言 代码 · 共 1,810 行 · 第 1/5 页

C
1,810
字号
    }    return CVM_TRUE;}static voidCVMmonExit(CVMExecEnv *ee, CVMObjMonitor *mon){#ifdef CVM_THREAD_BOOST    if (mon->boost) {        /* It is implied that we own the monitor since we're trying to exit	   it.  mon->boost being true indicates that another thread had	   inflated this monitor for us i.e. we have not actually claimed	   ownership of the monitor.  Some contender thread could have boosted	   our thread priority while waiting for us to claim ownership of the	   monitor.  So, call CVMunboost() to claim the monitor and unboost	   our thread priority.  If it turns out that we don't own this	   monitor, CVMunboost() will do nothing. */	CVMunboost(ee, mon);    }    CVMassert(!mon->boost);#endif    CVMprofiledMonitorExit(&mon->mon, ee);}/* Purpose: Attaches the specified CVMObjMonitor to a free CVMOwnedMonitor. */static void CVMmonitorAttachObjMonitor2OwnedMonitor(CVMExecEnv *ee,                                                    CVMObjMonitor *mon){    CVMOwnedMonitor *o = ee->objLocksFreeOwned;    /* Remove the CVMOwnedMonitor from the ee's free list: */    ee->objLocksFreeOwned = o->next;    /* Attach the CVMOwnedMonitor to the CVMObjMonitor: */    CVMassert(o != NULL);    CVMassert(mon->state == CVM_OBJMON_BOUND);    mon->state = CVM_OBJMON_OWNED;    o->type = CVM_OWNEDMON_HEAVY;#ifdef CVM_DEBUG    o->state = CVM_OWNEDMON_OWNED;    mon->owner = o;#endif    o->object = mon->obj;    o->u.heavy.mon = mon;    /* Add the CVMOwnedMonitor to the ee's owned list: */    o->next = ee->objLocksOwned;    ee->objLocksOwned = o;}/* Pointer to the microlock so asm code can easily locate it */CVMMicroLock* const CVMobjGlobalMicroLockPtr = &CVMglobals.objGlobalMicroLock;/* * The fast lockers. * All functions are called while gc-unsafe, but Lock is * allowed to become safe because it can block. */CVMBoolCVMfastTryLock(CVMExecEnv* ee, CVMObject* obj){    CVMOwnedMonitor *o = ee->objLocksFreeOwned;    /* return FALSE on:     * - exception     * - contention     * - monitor not allocated     */    /* %comment l005 */    CVMtraceFastLock(("fastTryLock(%x,%x)\n", ee, obj));    if (o == NULL) {	return CVM_FALSE;    }#ifdef CVM_JVMTI    if (CVMjvmtiIsInDebugMode()) {        /* just check for an available lockinfo */        if (!CVMjvmtiCheckLockInfo(ee)) {            return CVM_FALSE;        }    }#endif    /* %comment l006 */#ifdef CVM_DEBUG    CVMassert(o->state == CVM_OWNEDMON_FREE);#endif    CVMassert(o->type == CVM_OWNEDMON_FAST);    o->object = obj;#if CVM_FASTLOCK_TYPE != CVM_FASTLOCK_NONE    o->count = 1;#ifdef CVM_DEBUG    o->state = CVM_OWNEDMON_OWNED;#endif    {	/* 	 * nbits can hold a native pointer 	 * therefore the cast has to be CVMAddr which is 4 byte on	 * 32 bit platforms and 8 byte on 64 bit platforms	 */	CVMAddr nbits = (CVMAddr)(o) | CVM_LOCKSTATE_LOCKED;	CVMassert(o->owner == ee);#if CVM_FASTLOCK_TYPE == CVM_FASTLOCK_ATOMICOPS	{	    /*	     * obits can hold a native pointer 	     * therefore the cast has to be CVMAddr which is 4 byte on	     * 32 bit platforms and 8 byte on 64 bit platforms	     */	    CVMAddr obits0;	    CVMAddr obits =		CVMhdrBitsPtr(obj->hdr.various32) | CVM_LOCKSTATE_UNLOCKED;	    o->u.fast.bits = obits; /* be optimistic */	    /* 	     * The address of the various32 field has to be 8 byte aligned on	     * 64 bit platforms.	     */	    CVMassert((CVMAddr)CVMalignAddrUp(&obj->hdr.various32) == 		      (CVMAddr)&obj->hdr.various32);	    obits0 = CVMatomicCompareAndSwap(&obj->hdr.various32,		nbits, obits);	    if (obits0 != obits) {		goto fast_failed;	    }	}#elif CVM_FASTLOCK_TYPE == CVM_FASTLOCK_MICROLOCK	/* NOTE: All changes to bits must be made under micro lock */	CVMobjectMicroLock(ee, obj);	{	    /*	     * obits can hold a native pointer 	     * therefore the cast has to be CVMAddr which is 4 byte on	     * 32 bit platforms and 8 byte on 64 bit platforms	     */	    CVMAddr obits = obj->hdr.various32;	    if (CVMhdrBitsSync(obits) == CVM_LOCKSTATE_UNLOCKED) {		o->u.fast.bits = obits;		obj->hdr.various32 = nbits;	    } else {		CVMobjectMicroUnlock(ee, obj);		goto fast_failed;	    }	}	CVMobjectMicroUnlock(ee, obj);#else#error Unknown value for CVM_FASTLOCK_TYPE#endif	/*	 * After this point, the monitor could have been inflated	 * by another thread...	 */	CVMassert(ee->objLocksFreeOwned == o);	/* remove from free list */	ee->objLocksFreeOwned = o->next;	o->next = ee->objLocksOwned;	ee->objLocksOwned = o;#ifdef CVM_JVMTI	if (CVMjvmtiIsInDebugMode()) {	    CVMjvmtiAddLockInfo(ee, NULL, o, CVM_FALSE);	}#endif	return CVM_TRUE;    }fast_failed:#ifdef CVM_DEBUG    o->count = 0;    o->state = CVM_OWNEDMON_FREE;#endif    /* If we're already in a fast lock, then try to reenter it: */    if (CVMhdrBitsSync(CVMobjectVariousWord(obj)) == CVM_LOCKSTATE_LOCKED) {        CVMBool success = CVMfastReentryTryLock(ee, obj);        if (!success) {            goto fast_reentry_failed;        } else {            return success;        }    }fast_reentry_failed:#endif    /* If we're here, then we've failed to put a fast lock on this object: */    if (CVMobjMonitorState(obj) == CVM_LOCKSTATE_MONITOR) {	CVMObjMonitor *mon = CVMobjMonitor(obj);#ifdef CVM_DEBUG	CVMassert(mon->magic == CVM_OBJMON_MAGIC);#endif	CVMassert(mon->obj == obj);        if (!CVMmonTryEnter(ee, mon)) {	    return CVM_FALSE;	}        if (CVMprofiledMonitorGetCount(&mon->mon) == 1) {	    CVMassert(ee->objLocksFreeOwned == o);            CVMmonitorAttachObjMonitor2OwnedMonitor(ee, mon);	}#ifdef CVM_JVMTI	if (CVMjvmtiIsInDebugMode()) {	    CVMjvmtiAddLockInfo(ee, mon, NULL, CVM_FALSE);	}#endif	return CVM_TRUE;    }    return CVM_FALSE;}#if CVM_FASTLOCK_TYPE != CVM_FASTLOCK_NONE/* Purpose: Performs a TryLock on an object that already has a fast lock. */static CVMBoolCVMfastReentryTryLock(CVMExecEnv *ee, CVMObject *obj){    /*     * obits can hold a native pointer (see CVMobjectVariousWord())     * therefore the type has to be CVMAddr which is 4 byte on     * 32 bit platforms and 8 byte on 64 bit platforms     */    CVMAddr obits;    CVMOwnedMonitor *o;    /* %comment l005 */    CVMtraceFastLock(("fastReentryTryLock(%x,%x)\n", ee, obj));    /* Sample the bits needed to get the CVMOwnedMonitor for this fast lock: */    obits = CVMobjectVariousWord(obj);    /* The bits will contain the address of the CVMOwnedMonitor if and only if       the SYNC bits equals CVM_LOCKSTATE_LOCKED and the ptr value is not       NULL: */    if (CVMhdrBitsSync(obits) != CVM_LOCKSTATE_LOCKED) {        return CVM_FALSE;    }    o = (CVMOwnedMonitor *) CVMhdrBitsPtr(obits);    if (o == NULL) {        return CVM_FALSE;    }    /* Fail if this thread does not own this monitor: */    if (o->owner != ee) {        return CVM_FALSE;    }    /* If we get here then we know that we have a valid CVMOwnedMonitor. */    {#if CVM_FASTLOCK_TYPE == CVM_FASTLOCK_ATOMICOPS        {	    /*	     * expectedOldCount, newCount and oldCount are used in	     * conjunction with CVMatomicCompareAndSwap() and can 	     * therefore hold a native pointer.	     * therefore the cast has to be CVMAddr which is 4 byte on	     * 32 bit platforms and 8 byte on 64 bit platforms	     */            CVMAddr expectedOldCount = o->count;            CVMAddr newCount;            CVMAddr oldCount;            /* If the count is CVM_INVALID_REENTRY_COUNT after we've acquired               a fast lock, then it must mean that another thread is currently               inflating this monitor: */            if (expectedOldCount == CVM_INVALID_REENTRY_COUNT) {                goto reentry_failed;            }            newCount = expectedOldCount + 1;            oldCount = CVMatomicCompareAndSwap(&o->count, newCount,                                               expectedOldCount);            /* We either succeed in incrementing the count or not.  If not,               then the CompareAndSwap will fail which means that another               thread must be trying to inflate this monitor: */            if (oldCount != expectedOldCount) {                goto reentry_failed;            }        }#elif CVM_FASTLOCK_TYPE == CVM_FASTLOCK_MICROLOCK        /* NOTE: All changes to bits must be made under micro lock */        CVMobjectMicroLock(ee, obj);	{	    /*	     * obits can hold a native pointer 	     * therefore the cast has to be CVMAddr which is 4 byte on	     * 32 bit platforms and 8 byte on 64 bit platforms	     */	    CVMAddr obits0 = CVMobjectVariousWord(obj);            /* Make sure that the monitor hasn't been inflated yet: */            if (obits0 != obits) {		CVMobjectMicroUnlock(ee, obj);		return CVM_FALSE;	    }	    CVMassert(o->count < CVM_MAX_REENTRY_COUNT);	    o->count++;	}	CVMobjectMicroUnlock(ee, obj);#else#error Unknown value for CVM_FASTLOCK_TYPE#endif    }#ifdef CVM_JVMTI    if (CVMjvmtiIsInDebugMode()) {	CVMjvmtiAddLockInfo(ee, NULL, o, CVM_FALSE);    }#endif    return CVM_TRUE;#if CVM_FASTLOCK_TYPE == CVM_FASTLOCK_ATOMICOPSreentry_failed:    return CVM_FALSE;#endif}#endif  /* CVM_FASTLOCK_TYPE != CVM_FASTLOCK_NONE *//* Purpose: Replenish the thread specific free list of CVMObjMonitors by            tapping into the global free list. */static voidCVMreplenishFreeListsNonBlocking(CVMExecEnv *ee){    CVMObjMonitor *f = ee->objLocksFreeUnlocked;    /*     * Grab a free lock from the global pool, if available     * CVMglobals.objLocksFree is protected by syncLock     */    if (f == NULL) {	CVMObjMonitor *m = CVMglobals.objLocksFree;	if (m != NULL) {	    CVMassert(m->state == CVM_OBJMON_FREE);            if (CVMprofiledMonitorGetOwner(&m->mon) == NULL) {		CVMglobals.objLocksFree = m->next;		m->next = ee->objLocksFreeUnlocked;		ee->objLocksFreeUnlocked = f = m;	    }	}	if (f == NULL && ee->threadExiting) {	    CVMObjMonitor *o = ee->objLocksReservedUnlocked;	    /* If this fails, increase CVM_RESERVED_OBJMON_COUNT below */	    CVMassert(o != NULL);	    ee->objLocksReservedUnlocked = o->next;	    ee->objLocksFreeUnlocked = o;	    o->next = NULL;	}    }}/* Purpose: Replenish the thread specific free list of CVMObjMonitors by            scavenging for unused CVMObjMonitors or creating a new one. */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?