⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 natobject.cc

📁 gcc的组建
💻 CC
📖 第 1 页 / 共 4 页
字号:
	count = he -> light_count;    }  if (address & LOCKED)    {      wait_unlocked(he);      goto retry;    }  // Now the unlikely cases.  // We do know that:  // - Address is set, and doesn't contain the LOCKED bit.  // - If address refers to the same object as addr, then he -> light_thr_id  //   refers to this thread, and count is valid.  // - The case in which we held the lightweight lock has been  //   completely handled, except for the REQUEST_CONVERSION case.  //     if ((address & ~FLAGS) == addr)    {      // The lightweight lock is assigned to this object.      // Thus we must be in the REQUEST_CONVERSION case.      if (0 != count)        {	  // Defer conversion until we exit completely.	  he -> light_count = count - 1;	  return;        }      JvAssert(he -> light_thr_id == self);      JvAssert(address & REQUEST_CONVERSION);      // Conversion requested      // Convert now.      if (!compare_and_swap(&(he -> address), address, address | LOCKED))	goto retry;      heavy_lock *hl = find_heavy(addr, he);      JvAssert (0 != hl);		// Requestor created it.      he -> light_count = 0;      JvAssert(he -> heavy_count > 0);	  	// was incremented by requestor.      _Jv_MutexLock(&(hl->si.mutex));	// Release the he lock after acquiring the mutex.	// Otherwise we can accidentally	// notify a thread that has already seen a heavyweight	// lock.      he -> light_thr_id = INVALID_THREAD_ID;      release_set(&(he -> address), HEAVY);      LOG(PROMOTE, address, self);	  	// lightweight lock now unused.      _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));      _Jv_MutexUnlock(&(hl->si.mutex));      // heavy_count was already incremented by original requestor.      keep_live(addr);      return;    }  // lightweight lock not for this object.  JvAssert(!(address & LOCKED));  JvAssert((address & ~FLAGS) != addr);  if (!compare_and_swap(&(he -> address), address, address | LOCKED))	goto retry;  heavy_lock *hl = find_heavy(addr, he);  if (NULL == hl)    {#     ifdef LOCK_DEBUG	fprintf(stderr, "Failed to find heavyweight lock for addr 0x%lx"			" pid = %d\n", addr, getpid());	print_he(he);	for(;;) {}#     endif      release_set(&(he -> address), address);      throw new java::lang::IllegalMonitorStateException(			JvNewStringLatin1("current thread not owner"));    }  JvAssert(address & HEAVY);  count = he -> heavy_count;  JvAssert(count > 0);  --count;  he -> heavy_count = count;  if (0 == count)    {      const unsigned test_freq = 16;  // Power of 2      static volatile unsigned counter = 0;      unsigned my_counter = counter;      counter = my_counter + 1;      if (my_counter%test_freq == 0)	{	  // Randomize the interval length a bit.	    counter = my_counter + (my_counter >> 4) % (test_freq/2);	  // Unlock mutex first, to avoid self-deadlock, or worse.          _Jv_MutexUnlock(&(hl->si.mutex));	  maybe_remove_all_heavy(he, address &~HEAVY);    				// release lock bit, preserving				// REQUEST_CONVERSION    				// and object address.	}      else        {          release_set(&(he -> address), address &~HEAVY);          _Jv_MutexUnlock(&(hl->si.mutex));  			// Unlock after releasing the lock bit, so that  			// we don't switch to another thread prematurely.	}    }   else    {      release_set(&(he -> address), address);      _Jv_MutexUnlock(&(hl->si.mutex));    }  LOG(REL_HEAVY, addr, self);  keep_live(addr);}     // Return false if obj's monitor is held by the current threadbool_Jv_ObjectCheckMonitor (jobject obj){#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS  obj_addr_t addr = (obj_addr_t)obj & ~((obj_addr_t)FLAGS);#else  obj_addr_t addr = (obj_addr_t)obj;#endif  obj_addr_t address;  unsigned hash = JV_SYNC_HASH(addr);  hash_entry * he = light_locks + hash;  JvAssert(!(addr & FLAGS));  address = he -> address;  // Try it the easy way first:    if (address == 0) return true;    _Jv_ThreadId_t self = _Jv_ThreadSelf();    if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)	// Fails if entry is LOCKED.	// I can't asynchronously become or stop being the holder.	return he -> light_thr_id != self;retry:  // Acquire the hash table entry lock  address &= ~LOCKED;  if (!compare_and_swap(&(he -> address), address, address | LOCKED))    {      wait_unlocked(he);      goto retry;    }  bool not_mine;  if ((address & ~FLAGS) == addr)    not_mine = (he -> light_thr_id != self);  else    {      heavy_lock* hl = find_heavy(addr, he);      not_mine = hl ? _Jv_MutexCheckMonitor(&hl->si.mutex) : true;    }  release_set(&(he -> address), address);	// unlock hash entry  return not_mine;}// The rest of these are moderately thin veneers on _Jv_Cond ops.// The current version of Notify might be able to make the pthread// call AFTER releasing the lock, thus saving some context switches??voidjava::lang::Object::wait (jlong timeout, jint nanos){#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS  obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);#else  obj_addr_t addr = (obj_addr_t)this;#endif  _Jv_ThreadId_t self = _Jv_ThreadSelf();  unsigned hash = JV_SYNC_HASH(addr);  hash_entry * he = light_locks + hash;  unsigned count;  obj_addr_t address;  heavy_lock *hl;      if (__builtin_expect (timeout < 0 || nanos < 0 || nanos > 999999, false))    throw new IllegalArgumentException;retry:  address = he -> address;  address &= ~LOCKED;  if (!compare_and_swap(&(he -> address), address, address | LOCKED))    {      wait_unlocked(he);      goto retry;    }  // address did not have the lock bit set.  We now hold the lock on he.  if ((address & ~FLAGS) == addr)    {      // Convert to heavyweight.	if (he -> light_thr_id != self)	  {#	    ifdef LOCK_DEBUG	      fprintf(stderr, "Found wrong lightweight lock owner in wait "			      "address = 0x%lx pid = %d\n", address, getpid());	      print_he(he);	      for(;;) {}#	    endif	    release_set(&(he -> address), address);	    throw new IllegalMonitorStateException (JvNewStringLatin1                           ("current thread not owner"));	  }	count = he -> light_count;	hl = get_heavy(addr, he);	he -> light_count = 0;	he -> heavy_count += count + 1;	for (unsigned i = 0; i <= count; ++i)	  _Jv_MutexLock(&(hl->si.mutex));	// Again release the he lock after acquiring the mutex.        he -> light_thr_id = INVALID_THREAD_ID;	release_set(&(he -> address), HEAVY);  // lightweight lock now unused.	LOG(PROMOTE2, addr, self);	if (address & REQUEST_CONVERSION)	  _Jv_CondNotifyAll (&(hl->si.condition), &(hl->si.mutex));	  // Since we do this before we do a CondWait, we guarantee that	  // threads waiting on requested conversion are awoken before	  // a real wait on the same condition variable.	  // No other notification can occur in the interim, since	  // we hold the heavy lock, and notifications are made	  // without acquiring it.    }  else /* We should hold the heavyweight lock. */    {      hl = find_heavy(addr, he);      release_set(&(he -> address), address);      if (0 == hl)	{#	  ifdef LOCK_DEBUG	    fprintf(stderr, "Couldn't find heavy lock in wait "		 	    "addr = 0x%lx pid = %d\n", addr, getpid());	    print_he(he);	    for(;;) {}#	  endif	  throw new IllegalMonitorStateException (JvNewStringLatin1                           ("current thread not owner"));	}      JvAssert(address & HEAVY);    }  LOG(WAIT_START, addr, self);  switch (_Jv_CondWait (&(hl->si.condition), &(hl->si.mutex), timeout, nanos))    {      case _JV_NOT_OWNER:	throw new IllegalMonitorStateException (JvNewStringLatin1                           ("current thread not owner"));              case _JV_INTERRUPTED:	if (Thread::interrupted ())	  throw new InterruptedException;            }  LOG(WAIT_END, addr, self);}voidjava::lang::Object::notify (void){#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS  obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);#else  obj_addr_t addr = (obj_addr_t)this;#endif  _Jv_ThreadId_t self = _Jv_ThreadSelf();  unsigned hash = JV_SYNC_HASH(addr);  hash_entry * he = light_locks + hash;  heavy_lock *hl;  obj_addr_t address;  int result;retry:  address = ((he -> address) & ~LOCKED);  if (!compare_and_swap(&(he -> address), address, address | LOCKED))    {      wait_unlocked(he);      goto retry;    }  if ((address & ~FLAGS) == addr && he -> light_thr_id == self)    {      // We hold lightweight lock.  Since it has not      // been inflated, there are no waiters.      release_set(&(he -> address), address);	// unlock      return;    }  hl = find_heavy(addr, he);  // Hl can't disappear since we point to the underlying object.  // It's important that we release the lock bit before the notify, since  // otherwise we will try to wake up the target while we still hold the  // bit.  This results in lock bit contention, which we don't handle  // terribly well.  release_set(&(he -> address), address); // unlock  if (0 == hl)    {      throw new IllegalMonitorStateException(JvNewStringLatin1                                               ("current thread not owner"));      return;    }  // We know that we hold the heavyweight lock at this point,  // and the lightweight lock is not in use.  result = _Jv_CondNotify(&(hl->si.condition), &(hl->si.mutex));  LOG(NOTIFY, addr, self);  keep_live(addr);  if (__builtin_expect (result, 0))    throw new IllegalMonitorStateException(JvNewStringLatin1                                               ("current thread not owner"));}voidjava::lang::Object::notifyAll (void){#ifdef JV_LINKER_CANNOT_8BYTE_ALIGN_STATICS  obj_addr_t addr = (obj_addr_t)this & ~((obj_addr_t)FLAGS);#else  obj_addr_t addr = (obj_addr_t)this;#endif  _Jv_ThreadId_t self = _Jv_ThreadSelf();  unsigned hash = JV_SYNC_HASH(addr);  hash_entry * he = light_locks + hash;  heavy_lock *hl;  obj_addr_t address;  int result;retry:  address = (he -> address) & ~LOCKED;  if (!compare_and_swap(&(he -> address), address, address | LOCKED))    {      wait_unlocked(he);      goto retry;    }  hl = find_heavy(addr, he);  if ((address & ~FLAGS) == addr && he -> light_thr_id == self)    {      // We hold lightweight lock.  Since it has not      // been inflated, there are no waiters.      release_set(&(he -> address), address);	// unlock      return;    }  release_set(&(he -> address), address); // unlock  if (0 == hl)    {      throw new IllegalMonitorStateException(JvNewStringLatin1                                               ("current thread not owner"));    }  result = _Jv_CondNotifyAll(&(hl->si.condition), &(hl->si.mutex));  LOG(NOTIFY_ALL, addr, self);  if (__builtin_expect (result, 0))    throw new IllegalMonitorStateException(JvNewStringLatin1                                               ("current thread not owner"));}// This is declared in Java code and in Object.h.// It should never be called with JV_HASH_SYNCHRONIZATIONvoidjava::lang::Object::sync_init (void){  throw new IllegalMonitorStateException(JvNewStringLatin1                                               ("internal error: sync_init"));}// This is called on startup and declared in Object.h.// For now we just make it a no-op.void_Jv_InitializeSyncMutex (void){}#endif /* JV_HASH_SYNCHRONIZATION */

⌨️ 快捷键说明

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