Beispiel #1
0
void
MM_MasterGCThread::masterThreadEntryPoint()
{
	OMR_VMThread *omrVMThread = NULL;
	Assert_MM_true(NULL != _collectorControlMutex);
	Assert_MM_true(NULL == _masterGCThread);

	/* Attach the thread as a system daemon thread */	
	/* You need a VM thread so that the stack walker can work */
	omrVMThread = MM_EnvironmentBase::attachVMThread(_extensions->getOmrVM(), "Dedicated GC Master", MM_EnvironmentBase::ATTACH_GC_MASTER_THREAD);
	if (NULL == omrVMThread) {
		/* we failed to attach so notify the creating thread that we should fail to start up */
		omrthread_monitor_enter(_collectorControlMutex);
		_masterThreadState = STATE_ERROR;
		omrthread_monitor_notify(_collectorControlMutex);
		omrthread_exit(_collectorControlMutex);
	} else {
		/* thread attached successfully */
		MM_EnvironmentBase *env = MM_EnvironmentBase::getEnvironment(omrVMThread);

		/* attachVMThread could allocate an execute a barrier (since it that point, this thread acted as a mutator thread.
		 * Flush GC chaches (like barrier buffers) before turning into the master thread */
		env->flushGCCaches();

		env->setThreadType(GC_MASTER_THREAD);

		/* Begin running the thread */
		omrthread_monitor_enter(_collectorControlMutex);
		
		_collector->preMasterGCThreadInitialize(env);
		
		_masterThreadState = STATE_WAITING;
		_masterGCThread = omrthread_self();
		omrthread_monitor_notify(_collectorControlMutex);
		do {
			if (STATE_GC_REQUESTED == _masterThreadState) {
				if (_runAsImplicit) {
					handleConcurrent(env);
				} else {
					handleSTW(env);
				}
			}

			if (STATE_WAITING == _masterThreadState) {
				if (_runAsImplicit || !handleConcurrent(env)) {
					omrthread_monitor_wait(_collectorControlMutex);
				}
			}
		} while (STATE_TERMINATION_REQUESTED != _masterThreadState);
		/* notify the other side that we are active so that they can continue running */
		_masterThreadState = STATE_TERMINATED;
		_masterGCThread = NULL;
		omrthread_monitor_notify(_collectorControlMutex);
		MM_EnvironmentBase::detachVMThread(_extensions->getOmrVM(), omrVMThread, MM_EnvironmentBase::ATTACH_GC_MASTER_THREAD);
		omrthread_exit(_collectorControlMutex);
	}
}
Beispiel #2
0
/**
 * This method is called to push the concurrent thread to run the next function
 */
void
triggerNextStepWithStatus(SupportThreadInfo *info, BOOLEAN done)
{
	omrthread_monitor_enter(info->synchronization);
	info->done = done;
	omrthread_monitor_notify(info->synchronization);
	omrthread_monitor_wait_interruptable(info->synchronization, MILLI_TIMEOUT, NANO_TIMEOUT);
	omrthread_monitor_exit(info->synchronization);
}
/**
 * Send a event and optionally event data to the waiting thread.
 *
 * @param info The pointer to SigMaskTestInfo object
 * @param event The event
 * @param value The pointer to event data
 * @param size The size of the event data
 */
static void
sendEvent(SigMaskTestInfo *info, SignalEvent event, void *value, size_t size)
{
	omrthread_monitor_enter(info->monitor);
	info->bulletinBoard.event = event;
	if ((NULL != value) && (size > 0)) {
		memcpy(&info->bulletinBoard.data, value, size);
	}
	omrthread_monitor_notify(info->monitor);
	omrthread_monitor_exit(info->monitor);
}
Beispiel #4
0
intptr_t
sem_post_zos(j9sem_t s)
{
	zos_sem_t *zs = (zos_sem_t *) s;

	omrthread_monitor_enter(zs->monitor);
	zs->count++;
	omrthread_monitor_notify(zs->monitor);
	omrthread_monitor_exit(zs->monitor);

	return 0;
}
Beispiel #5
0
void
MM_MasterGCThread::shutdown()
{
	Assert_MM_true(NULL != _collectorControlMutex);
	if ((STATE_ERROR != _masterThreadState) && (STATE_DISABLED != _masterThreadState)) {
		/* tell the background thread to shut down and then wait for it to exit */
		omrthread_monitor_enter(_collectorControlMutex);
		while(STATE_TERMINATED != _masterThreadState) {
			_masterThreadState = STATE_TERMINATION_REQUESTED;
			omrthread_monitor_notify(_collectorControlMutex);
			omrthread_monitor_wait(_collectorControlMutex);
		}
		omrthread_monitor_exit(_collectorControlMutex);
		
		/* don't NULL _collector as RAS could still trigger a collection after we've started shutting down */
	}
}
Beispiel #6
0
void
MM_MasterGCThread::handleSTW(MM_EnvironmentBase *env)
{
	Assert_MM_true(NULL != _incomingCycleState);
	env->_cycleState = _incomingCycleState;

	/* this thread effectively inherits exclusive access from the mutator thread -- set its state to indicate this */
	env->assumeExclusiveVMAccess(1);

	_collector->masterThreadGarbageCollect(env, _allocDesc);

	uintptr_t exclusiveCount = env->relinquishExclusiveVMAccess();
	Assert_MM_true(1 == exclusiveCount);

	env->_cycleState = NULL;
	_incomingCycleState = NULL;
	_masterThreadState = STATE_WAITING;
	omrthread_monitor_notify(_collectorControlMutex);
}
Beispiel #7
0
/**
 * This method is called to run the set of steps that will be run on a thread
 * @param info SupportThreadInfo structure that contains the information for the steps and other parameters
 *        that are used
 */
static intptr_t J9THREAD_PROC
runRequest(SupportThreadInfo *info)
{
	intptr_t result = 0;
	uintptr_t i = 0;

	omrthread_monitor_enter(info->synchronization);
	omrthread_monitor_exit(info->synchronization);
	for (i = 0; i < info->numberFunctions; i++) {
		result = info->functionsToRun[i]((void *)info);
		omrthread_monitor_enter(info->synchronization);
		omrthread_monitor_notify(info->synchronization);
		if (info->done == TRUE) {
			omrthread_monitor_exit(info->synchronization);
			break;
		}
		omrthread_monitor_wait_interruptable(info->synchronization,
											STEP_MILLI_TIMEOUT, STEP_NANO_TIMEOUT);
		omrthread_monitor_exit(info->synchronization);
	}

	return result;
}
Beispiel #8
0
void
CMonitor::Notify(void)
{
	omrthread_monitor_notify(m_monitor);
}
Beispiel #9
0
bool
MM_MasterGCThread::garbageCollect(MM_EnvironmentBase *env, MM_AllocateDescription *allocDescription)
{
	Assert_MM_mustHaveExclusiveVMAccess(env->getOmrVMThread());
	bool didAttemptCollect = false;
	
	if (NULL != _collector) {
		/* the collector has started up so try to run */
		/* once the master thread has stored itself in the _masterGCThread, it should never need to collect - this would hang */
		Assert_MM_true(omrthread_self() != _masterGCThread);
		if (_runAsImplicit || (NULL == _masterGCThread)) {
			/* We might not have _masterGCThread in the startup phase or late in the shutdown phase.
			 * For example, there may be a native out-of-memory during startup or RAS may 
			 * trigger a GC after we've shutdown the master thread.
			 */
			Assert_MM_true(0 == env->getSlaveID());
			_collector->preMasterGCThreadInitialize(env);
			_collector->masterThreadGarbageCollect(env, allocDescription);

			if (_runAsImplicit && _collector->isConcurrentWorkAvailable(env)) {
				omrthread_monitor_enter(_collectorControlMutex);

				if (STATE_WAITING == _masterThreadState) {
					_masterThreadState = STATE_GC_REQUESTED;
					omrthread_monitor_notify(_collectorControlMutex);
				}

				omrthread_monitor_exit(_collectorControlMutex);
			}
		} else {
			/* this is the general case, when the master thread is running internally */
			omrthread_monitor_enter(_collectorControlMutex);
			/* The variable assignments below are safe because we hold Xaccess.  Otherwise, it is possible (based on the wait/notify mechanism here)
			 * that another thread could come in under this mutex and stomp on the "parameters" while another thread is waiting.
			 */
			_allocDesc = allocDescription;
			_incomingCycleState = env->_cycleState;
			MasterGCThreadState previousState = _masterThreadState;
			_masterThreadState = STATE_GC_REQUESTED;
			if (STATE_WAITING == previousState) {
				omrthread_monitor_notify(_collectorControlMutex);
			} else if (STATE_RUNNING_CONCURRENT == previousState) {
				_collector->forceConcurrentFinish();
			} else {
				Assert_MM_unreachable();
			}
			
			/* The master thread will claim exclusive VM access. Artificially give it up in this thread so that tools like -Xcheck:vm continue to work. */
			uintptr_t savedExclusiveCount = env->relinquishExclusiveVMAccess();
			while (STATE_GC_REQUESTED == _masterThreadState) {
				omrthread_monitor_wait(_collectorControlMutex);
			}
			env->assumeExclusiveVMAccess(savedExclusiveCount);

			Assert_MM_true(NULL == _incomingCycleState);
			omrthread_monitor_exit(_collectorControlMutex);
		}
		
		didAttemptCollect = true;
	}
	return didAttemptCollect;
}