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

📄 natobject.cc

📁 俄罗斯高人Mamaich的Pocket gcc编译器(运行在PocketPC上)的全部源代码。
💻 CC
📖 第 1 页 / 共 3 页
字号:
  address &= ~LOCKED;  if (!compare_and_swap(&(he -> address), address, (address | LOCKED )))    {      wait_unlocked(he);      goto retry;    }  if ((address & ~(HEAVY | REQUEST_CONVERSION)) == 0)    {      // Either was_heavy is true, or something changed out from under us,      // since the initial test for 0 failed.      assert(!(address & REQUEST_CONVERSION));	// Can't convert a nonexistent lightweight lock.      heavy_lock *hl;      hl = (was_heavy? find_heavy(addr, he) : 0);      if (0 == hl)        {	  // It is OK to use the lighweight lock, since either the	  // heavyweight lock does not exist, or none of the	  // heavyweight locks currently exist.  Future threads	  // trying to acquire the lock will see the lightweight	  // one first and use that.	  he -> light_thr_id = self;  // OK, since nobody else can hold				      // light lock or do this at the same time.	  assert(he -> light_count == 0);	  assert(was_heavy == (he -> address & HEAVY));	  release_set(&(he -> address), (addr | was_heavy));        }      else	{	  // Must use heavy lock.	  ++ (he -> heavy_count);	  assert(0 == (address & ~HEAVY));          release_set(&(he -> address), HEAVY);          _Jv_MutexLock(&(hl->si.mutex));	  keep_live(addr);        }      return;    }  // Lightweight lock is held, but does not correspond to this object.  // We hold the lock on the hash entry, and he -> address can't  // change from under us.  Neither can the chain of heavy locks.    {      assert(0 == he -> heavy_count || (address & HEAVY));      heavy_lock *hl = get_heavy(addr, he);      ++ (he -> heavy_count);      release_set(&(he -> address), address | HEAVY);      _Jv_MutexLock(&(hl->si.mutex));      keep_live(addr);    }}void_Jv_MonitorExit (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  _Jv_ThreadId_t self = _Jv_ThreadSelf();  unsigned hash = JV_SYNC_HASH(addr);  hash_entry * he = light_locks + hash;  _Jv_ThreadId_t light_thr_id;  unsigned count;  obj_addr_t address;retry:  light_thr_id = he -> light_thr_id;  // Unfortunately, it turns out we always need to read the address  // first.  Even if we are going to update it with compare_and_swap,  // we need to reset light_thr_id, and that's not safe unless we know  // that we hold the lock.  address = he -> address;  // First the (relatively) fast cases:  if (__builtin_expect(light_thr_id == self, true))    // Above must fail if addr == 0 .    {      count = he -> light_count;      if (__builtin_expect((address & ~HEAVY) == addr, true))	{          if (count != 0)            {	      // We held the lightweight lock all along.  Thus the values	      // we saw for light_thr_id and light_count must have been valid. 	      he -> light_count = count - 1;	      return;            }	  else	    {	      // We hold the lightweight lock once.	      he -> light_thr_id = INVALID_THREAD_ID;              if (compare_and_swap_release(&(he -> address), address,					   address & HEAVY))	        return;	      else		{	          he -> light_thr_id = light_thr_id; // Undo prior damage.	          goto retry;	        }            }        }      // else lock is not for this address, conversion is requested,      // or the lock bit in the address field is set.    }  else    {      if (__builtin_expect(!addr, false))	throw new java::lang::NullPointerException;      if ((address & ~(HEAVY | REQUEST_CONVERSION)) == addr)	{#	  ifdef LOCK_DEBUG	    fprintf(stderr, "Lightweight lock held by other thread\n\t"			    "light_thr_id = 0x%lx, self = 0x%lx, "			    "address = 0x%lx, pid = %d\n",			    light_thr_id, self, address, getpid());	    print_he(he);	    for(;;) {}#	  endif	  // Someone holds the lightweight lock for this object, and	  // it can't be us.	  throw new java::lang::IllegalMonitorStateException(			JvNewStringLatin1("current thread not owner"));        }      else	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;        }      assert(he -> light_thr_id == self);      assert(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);      assert (0 != hl);		// Requestor created it.      he -> light_count = 0;      assert(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);	  	// 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.  assert(!(address & LOCKED));  assert((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      throw new java::lang::IllegalMonitorStateException(			JvNewStringLatin1("current thread not owner"));    }  assert(address & HEAVY);  count = he -> heavy_count;  assert(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));    }  keep_live(addr);}     // 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 does not have the lock bit set.  We 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.	if (address & REQUEST_CONVERSION)	  _Jv_CondNotify (&(hl->si.condition), &(hl->si.mutex));    }  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"));	}      assert(address & HEAVY);    }  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;            }}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 thee 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;    }  result = _Jv_CondNotify(&(hl->si.condition), &(hl->si.mutex));  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));  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 + -