Exemplo n.º 1
0
void
SystemProfiler::_WaitObjectUsed(addr_t object, uint32 type)
{
	// look up the object
	WaitObjectKey key;
	key.object = object;
	key.type = type;
	WaitObject* waitObject = fWaitObjectTable.Lookup(key);

	// If already known, re-queue it as most recently used and be done.
	if (waitObject != NULL) {
		fUsedWaitObjects.Remove(waitObject);
		fUsedWaitObjects.Add(waitObject);
		return;
	}

	// not known yet -- get the info
	const char* name = NULL;
	const void* referencedObject = NULL;

	switch (type) {
		case THREAD_BLOCK_TYPE_SEMAPHORE:
		{
			name = sem_get_name_unsafe((sem_id)object);
			break;
		}

		case THREAD_BLOCK_TYPE_CONDITION_VARIABLE:
		{
			ConditionVariable* variable = (ConditionVariable*)object;
			name = variable->ObjectType();
			referencedObject = variable->Object();
			break;
		}

		case THREAD_BLOCK_TYPE_MUTEX:
		{
			mutex* lock = (mutex*)object;
			name = lock->name;
			break;
		}

		case THREAD_BLOCK_TYPE_RW_LOCK:
		{
			rw_lock* lock = (rw_lock*)object;
			name = lock->name;
			break;
		}

		case THREAD_BLOCK_TYPE_OTHER:
		{
			name = (const char*)(void*)object;
			break;
		}

		case THREAD_BLOCK_TYPE_SNOOZE:
		case THREAD_BLOCK_TYPE_SIGNAL:
		default:
			return;
	}

	// add the event
	size_t nameLen = name != NULL ? strlen(name) : 0;

	system_profiler_wait_object_info* event
		= (system_profiler_wait_object_info*)
			_AllocateBuffer(sizeof(system_profiler_wait_object_info) + nameLen,
				B_SYSTEM_PROFILER_WAIT_OBJECT_INFO, 0, 0);
	if (event == NULL)
		return;

	event->type = type;
	event->object = object;
	event->referenced_object = (addr_t)referencedObject;
	if (name != NULL)
		strcpy(event->name, name);
	else
		event->name[0] = '\0';

	fHeader->size = fBufferSize;

	// add the wait object

	// get a free one or steal the least recently used one
	waitObject = fFreeWaitObjects.RemoveHead();
	if (waitObject == NULL) {
		waitObject = fUsedWaitObjects.RemoveHead();
		fWaitObjectTable.RemoveUnchecked(waitObject);
	}

	waitObject->object = object;
	waitObject->type = type;
	fWaitObjectTable.InsertUnchecked(waitObject);
	fUsedWaitObjects.Add(waitObject);
}