Exemple #1
0
/*-----------------------------------------------------------
 *  Name: 	HASH_FromArray()
 *  Created:	Thu Sep  8 23:53:36 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	converts an array to a hash table
 */
HASH_TABLE *HASH_FromArray(HASH_TABLE *h, DATA_PTR *array, unsigned size)
{
   unsigned index;

#ifdef HASH_DEBUG
   if (!array) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_FromArray()"); }
   }
#endif

   if (!h) {
     h = HASH_Create(size, 0);  /* create default hash table */
   }
   else {
      HASH_ClearFn(h, NULL);
   }

   for (index = 0; index < size; index++) {
      HASH_Insert(h, array[index]);
   }

#ifdef HASH_DEBUG
   if (h->attr & HASH_ReportChange) {
      printf("HASH TABLE: 0x%.8x FromArray(0x%.8x, %u) complete\n", h, array, h->count);
   }
#endif

#ifdef _HASH_INTERNAL_DEBUG
   HASH_Verify(h);
#endif

   return(h);
}
Exemple #2
0
/*!
******************************************************************************

 @Function	PVRSRVTimeTraceBufferCreate

 @Description

 Create a trace buffer.

 Note: We assume that this will only be called once per process.

 @Input ui32PID : PID of the process that is creating the buffer

 @Return none

******************************************************************************/
PVRSRV_ERROR PVRSRVTimeTraceBufferCreate(IMG_UINT32 ui32PID)
{
	sTimeTraceBuffer *psBuffer;
	PVRSRV_ERROR eError = PVRSRV_OK;

	eError = OSAllocMem(PVRSRV_PAGEABLE_SELECT,
					sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE,
					(IMG_VOID **)&psBuffer, IMG_NULL,
					"Time Trace Buffer");
	if (eError != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferCreate: Error allocating trace buffer"));
		return eError;
	}

	OSMemSet(psBuffer, 0, TIME_TRACE_BUFFER_SIZE);

	if (!HASH_Insert(g_psBufferTable, (IMG_UINTPTR_T) ui32PID, (IMG_UINTPTR_T) psBuffer))
	{
		OSFreeMem(PVRSRV_PAGEABLE_SELECT, sizeof(sTimeTraceBuffer) + TIME_TRACE_BUFFER_SIZE,
				psBuffer, NULL);
		PVR_DPF((PVR_DBG_ERROR, "PVRSRVTimeTraceBufferCreate: Error adding trace buffer to hash table"));
		return PVRSRV_ERROR_OUT_OF_MEMORY;
	}

	return eError;
}
Exemple #3
0
hashTable_s* HASH_CloneTable (hashTable_s* source) {
	hashTable_s* t = HASH_NewTable(source->ownsKeys, source->ownsValues, source->duplicateOverwrite, source->hash, source->compare);

	hashItem_s* item = _iterator_first (source);
	while (item) {
		HASH_Insert (t, item->key, item->nkey, item->value, item->nvalue);
		item = _iterator_next (source, item);
	}
	return t;
}
Exemple #4
0
/**
 * @brief Registers a lua callback function with a key.
 * @param key A key for finding the callback function by name, usually the script name.
 * @param fnc A lua function registered in the lua registry index.
*/
void CL_RegisterCallback (const char* key, LUA_FUNCTION fnc) {
	int regvalue = (int) fnc;
	/* store regvalue into the list of handlers */
	int len = strlen (key);
	if (len > 0) {
		HASH_Insert (cl_callback, key, len, &regvalue, sizeof(regvalue));
	}
	else {
		Com_Printf("CL_RegisterCallback: lua callback registration error: script name has zero length!\n");
	}
}
Exemple #5
0
/**
 * @brief Adds a lua based method to the list of available node methods for calling.
 * @param[in] node The node to extend.
 * @param[in] name The name of the new method to add
 * @param[in] fcn The lua based function reference.
 * @note If the method name is already defined, the new method is not added and a warning will be issued
 * in the log.
 * @note The method will be instance based, meaning that if a new node is created of the same behaviour,
 * it will not contain this method unless this node was specified as super.
 */
void UI_AddNodeMethod (uiNode_t* node, const char* name, LUA_METHOD fcn) {
	//Com_Printf ("UI_AddNodeMethod: registering node method [%s] on node [%s]\n", name, UI_GetPath(node));

	/* the first method, so create a method table on this node */
	if (!node->nodeMethods) {
		node->nodeMethods = HASH_NewTable(true, true, false);
	}
	/* add the method */
    if (!HASH_Insert(node->nodeMethods, name, strlen(name), &fcn, sizeof(fcn))) {
		Com_Printf("UI_AddNodeMethod: method [%s] already defined on this behaviour [%s]\n", name, node->name);
    }
}
Exemple #6
0
/*-----------------------------------------------------------
 *  Name: 	HASH_FromLinkedList()
 *  Created:	Fri Sep  9 00:04:37 1994
 *  Author: 	Jonathan DeKock   <dekock@winter>
 *  DESCR:  	converts a linked list into a hash table
 */
HASH_TABLE *HASH_FromLinkedList(HASH_TABLE *h, LINKED_LIST *ll)
{
   DATA_PTR data;

#ifdef HASH_DEBUG
   if (!ll) {
      if (HASH_Handler) { (HASH_Handler)(h, HASH_BadArgument, "HASH_FromLinkedList()"); }
   }
#endif

   if (!h) {
     h = HASH_Create(ll->count, 0);  /* create default hash table */
   }
   else {
      HASH_ClearFn(h, NULL);
   }
   
   LL_Iterate(ll, data) {
      HASH_Insert(h, data);
   }
static inline
enum PVRSRV_ERROR alloc_or_reuse_syncinfo(void *dev_cookie,
		    void *mem_context_handle,
		    struct PVRSRV_KERNEL_SYNC_INFO **syncinfo,
		    struct IMG_SYS_PHYADDR *phys_addr)
{
	enum PVRSRV_ERROR error;
	struct PVRSRV_DEVICE_NODE *dev;

	dev = (struct PVRSRV_DEVICE_NODE *) dev_cookie;

	*syncinfo = (struct PVRSRV_KERNEL_SYNC_INFO *)
					HASH_Retrieve(dev->sync_table,
						      phys_addr->uiAddr);

	if (!*syncinfo) {
		/* Dont' have one so create one */
		error = PVRSRVAllocSyncInfoKM(dev_cookie, mem_context_handle,
					       syncinfo);

		if (error != PVRSRV_OK)
			return error;

		/* Setup our extra data */
		(*syncinfo)->phys_addr.uiAddr = phys_addr->uiAddr;
		(*syncinfo)->dev_cookie = dev_cookie;
		(*syncinfo)->refcount = 1;

		if (!HASH_Insert(dev->sync_table, phys_addr->uiAddr,
			    (u32) *syncinfo)) {
			PVR_DPF(PVR_DBG_ERROR, "alloc_or_reuse_syncinfo: "
				"Failed to add syncobject to hash table");
			return PVRSRV_ERROR_GENERIC;
		}
	} else
		get_syncinfo(*syncinfo);

	return PVRSRV_OK;
}
Exemple #8
0
/*!
******************************************************************************

 @Function	PVRSRVPerProcessDataConnect

 @Description	Allocate per-process data area, or increment refcount if one
 				already exists for this PID.

 @Input		ui32PID - process ID
 			ppsPerProc - Pointer to per-process data area

 @Return	PVRSRV_ERROR

******************************************************************************/
PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags)
{
	PVRSRV_PER_PROCESS_DATA *psPerProc;
	IMG_HANDLE hBlockAlloc;
	PVRSRV_ERROR eError = PVRSRV_OK;

	if (psHashTab == IMG_NULL)
	{
		return PVRSRV_ERROR_INIT_FAILURE;
	}

	/* Look for existing per-process data area */
	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);

	if (psPerProc == IMG_NULL)
	{
		/* Allocate per-process data area */
		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
							sizeof(*psPerProc),
							(IMG_PVOID *)&psPerProc,
							&hBlockAlloc,
							"Per Process Data");
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
			return eError;
		}
		OSMemSet(psPerProc, 0, sizeof(*psPerProc));
		psPerProc->hBlockAlloc = hBlockAlloc;

		if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
			eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
			goto failure;
		}

		psPerProc->ui32PID = ui32PID;
		psPerProc->ui32RefCount = 0;

#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
		if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE)
		{
			psPerProc->bPDumpActive = IMG_TRUE;
		}
#else
		PVR_UNREFERENCED_PARAMETER(ui32Flags);
#endif

		/* Call environment specific per process init function */
		eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
		if (eError != PVRSRV_OK)
		{
			 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
			goto failure;
		}

		/* Allocate a handle for the per-process data area */
		eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
								   &psPerProc->hPerProcData,
								   psPerProc,
								   PVRSRV_HANDLE_TYPE_PERPROC_DATA,
								   PVRSRV_HANDLE_ALLOC_FLAG_NONE);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
			goto failure;
		}

		/* Allocate handle base for this process */
		eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
			goto failure;
		}

		/* Set per-process handle options */
		eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
			goto failure;
		}

		/* Create a resource manager context for the process */
		eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
			goto failure;
		}
#if defined (TTRACE)
		PVRSRVTimeTraceBufferCreate(ui32PID);
#endif
	}

	psPerProc->ui32RefCount++;
	PVR_DPF((PVR_DBG_MESSAGE,
			"PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
			ui32PID, psPerProc->ui32RefCount));

	return eError;

failure:
	(IMG_VOID)FreePerProcessData(psPerProc);
	return eError;
}
Exemple #9
0
/**
 * @brief Unit test function.
 */
bool HASH_test () {
	// return value
	bool result = true;

	/* test 1: create the hash table, delete the hash table */
	hashTable_s* table = HASH_NewTable(true, true, true);
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;

	/* test 2: create the hash table, insert 3 values, delete the hash table */
	table = HASH_NewTable(true, true, true);
	HASH_Insert (table, "AAA", 4, "AAA", 4);
	HASH_Insert (table, "BBB", 4, "BBB", 4);
	HASH_Insert (table, "CCC", 4, "CCC", 4);
	if (HASH_Count(table) != 3) return false;
	HASH_Clear (table);
	if (HASH_Count(table) != 0) return false;
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;

	/* test 3: create the hash table, insert/remove 3 values, delete the hash table */
	table = HASH_NewTable(true, true, true);
	HASH_Insert (table, "AAA", 4, "AAA", 4);
	HASH_Remove (table, "AAA", 4);
	HASH_Insert (table, "BBB", 4, "BBB", 4);
	HASH_Remove (table, "BBB", 4);
	HASH_Insert (table, "CCC", 4, "CCC", 4);
	HASH_Remove (table, "CCC", 4);
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;

	/* test 4: create the hash table, insert/count/search/delete 3 values, delete the hash table */
	table = HASH_NewTable(true, true, true);
	HASH_Insert (table, "AAA", 4, "AAA", 4);
	HASH_Insert (table, "BBB", 4, "BBB", 4);
	HASH_Insert (table, "CCC", 4, "CCC", 4);
	/* check count items */
	if (HASH_Count(table) != 3) return false;
    char* aaa = (char*)HASH_Get(table, "AAA", 4);
    if (strncmp (aaa, "AAA", 4) != 0) return false;
    char* bbb = (char*)HASH_Get(table, "BBB", 4);
    if (strncmp (bbb, "BBB", 4) != 0) return false;
    char* ccc = (char*)HASH_Get(table, "CCC", 4);
    if (strncmp (ccc, "CCC", 4) != 0) return false;
	HASH_Remove (table, "AAA", 4);
	HASH_Remove (table, "BBB", 4);
	HASH_Remove (table, "CCC", 4);
	if (HASH_Count(table) != 0) return false;
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;

	/* test 5: hash function test */
	const char AZ[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
	char buffer[26];
	/* compute the averag of the hash index of 400 random keys */
    int total = 0;
    srand(time(NULL));
    for(int i=0; i < 4000; i++) {
		/* create random key of random length between 4..23 charachters */
		int len = 4 + (rand() % 20);
		memset (buffer, 0, sizeof(buffer));
		for (int j=0; j < len; j++) {
			int v = rand() % sizeof(AZ);
			buffer[j]=AZ[v];
		}
		/* compute the hash index */
		int idx = default_hash (buffer, len);
		/* sum index */
		total += idx;
    }
    /* now compute the average of the indices */
    int avg = (total / 4000);
	/* the average idx should be somewhere halfway, allow a %10 error margin */
	int idx_low = (HASH_TABLE_SIZE/2) - (HASH_TABLE_SIZE/10);
	int idx_high = (HASH_TABLE_SIZE/2) + (HASH_TABLE_SIZE/10);
	if ( !((idx_low <= avg) && (idx_high >= avg)) ) return false;

	/* test 6: hash table without ownership test */
	table = HASH_NewTable(true, false, true);
	char item1[] = "AAA";
	char item2[] = "BBB";
	char item3[] = "CCC";
	HASH_Insert (table, item1, 4, item1, 4);
	HASH_Insert (table, item2, 4, item2, 4);
	HASH_Insert (table, item3, 4, item3, 4);
	/* check if we get the correct value pointers */
	aaa = (char*)HASH_Get(table, "AAA", 4);
	if (aaa != item1) return false;
	bbb = (char*)HASH_Get(table, "BBB", 4);
	if (bbb != item2) return false;
	ccc = (char*)HASH_Get(table, "CCC", 4);
	if (ccc != item3) return false;
	HASH_DeleteTable (&table);
	/* check table pointer is correctly set to nil */
	result = result && (table == NULL);
	if (!result) return false;
	/* check alloc total */
	result = result && (_num_allocs == 0);
	if (!result) return false;


	/* end of unit test, everything OK */
	return true;
}
Exemple #10
0
enum PVRSRV_ERROR PVRSRVPerProcessDataConnect(u32 ui32PID)
{
	struct PVRSRV_PER_PROCESS_DATA *psPerProc;
	void *hBlockAlloc;
	enum PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT(psHashTab != NULL);

	psPerProc = (struct PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab,
						      (u32)ui32PID);
	if (psPerProc == NULL) {
		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
				    sizeof(*psPerProc), (void **)&psPerProc,
				    &hBlockAlloc);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
				"Couldn't allocate per-process data (%d)",
				 eError);
			return eError;
		}
		OSMemSet(psPerProc, 0, sizeof(*psPerProc));
		psPerProc->hBlockAlloc = hBlockAlloc;

		if (!HASH_Insert(psHashTab, (u32) ui32PID, (u32)psPerProc)) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
			   "Couldn't insert per-process data into hash table");
			eError = PVRSRV_ERROR_GENERIC;
			goto failure;
		}

		psPerProc->ui32PID = ui32PID;
		psPerProc->ui32RefCount = 0;

		eError =
		    OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
				"OSPerProcessPrivateDataInit failed (%d)",
				 eError);
			goto failure;
		}

		eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
					   &psPerProc->hPerProcData,
					   psPerProc,
					   PVRSRV_HANDLE_TYPE_PERPROC_DATA,
					   PVRSRV_HANDLE_ALLOC_FLAG_NONE);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
			   "Couldn't allocate handle for per-process data (%d)",
			   eError);
			goto failure;
		}

		eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
			       "Couldn't allocate handle base for process (%d)",
			       eError);
			goto failure;
		}

		eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
					"Couldn't set handle options (%d)",
				 eError);
			goto failure;
		}

		eError =
		    PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
		if (eError != PVRSRV_OK) {
			PVR_DPF(PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: "
				"Couldn't register with the resource manager");
			goto failure;
		}
	}

	psPerProc->ui32RefCount++;
	PVR_DPF(PVR_DBG_MESSAGE,
		 "PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
		 ui32PID, psPerProc->ui32RefCount);

	return eError;

failure:
	(void)FreePerProcessData(psPerProc);
	return eError;
}
Exemple #11
0
PVRSRV_ERROR PVRSRVPerProcessDataConnect(IMG_UINT32	ui32PID, IMG_UINT32 ui32Flags)
{
	PVRSRV_PER_PROCESS_DATA *psPerProc;
	IMG_HANDLE hBlockAlloc;
	PVRSRV_ERROR eError = PVRSRV_OK;

	PVR_ASSERT(psHashTab != IMG_NULL);


	psPerProc = (PVRSRV_PER_PROCESS_DATA *)HASH_Retrieve(psHashTab, (IMG_UINTPTR_T)ui32PID);

	if (psPerProc == IMG_NULL)
	{

		eError = OSAllocMem(PVRSRV_OS_NON_PAGEABLE_HEAP,
							sizeof(*psPerProc),
							(IMG_PVOID *)&psPerProc,
							&hBlockAlloc,
							"Per Process Data");
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate per-process data (%d)", eError));
			return eError;
		}
		OSMemSet(psPerProc, 0, sizeof(*psPerProc));
		psPerProc->hBlockAlloc = hBlockAlloc;

		/*
		 * FIXME: using a hash to retrieve psPerProc makes not much
		 * sense. We always want to have this struct on the IOCTL path
		 * for the current task, so it'd be just a matter of storing
		 * it in the file private object. Until this is resolved and
		 * we get rid of this pid specific lookup make sure the above
		 * assumption holds.
		 */
		WARN_ON(OSGetCurrentProcessIDKM() != ui32PID);
		get_task_comm(psPerProc->name, current);

		if (!HASH_Insert(psHashTab, (IMG_UINTPTR_T)ui32PID, (IMG_UINTPTR_T)psPerProc))
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't insert per-process data into hash table"));
			eError = PVRSRV_ERROR_INSERT_HASH_TABLE_DATA_FAILED;
			goto failure;
		}
		psPerProc->ui32PID = ui32PID;
		psPerProc->ui32RefCount = 0;

#if defined(PERPROC_LIST)
		List_PVRSRV_PER_PROCESS_DATA_Insert(&psPerProcList, psPerProc);
		/*PVR_LOG(("MarkTupsperproc %d\n", ui32PID));*/
#endif

#if defined(SUPPORT_PDUMP_MULTI_PROCESS)
		if (ui32Flags == SRV_FLAGS_PDUMP_ACTIVE)
		{
			psPerProc->bPDumpActive = IMG_TRUE;
		}
#else
		PVR_UNREFERENCED_PARAMETER(ui32Flags);
#endif


		eError = OSPerProcessPrivateDataInit(&psPerProc->hOsPrivateData);
		if (eError != PVRSRV_OK)
		{
			 PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: OSPerProcessPrivateDataInit failed (%d)", eError));
			goto failure;
		}


		eError = PVRSRVAllocHandle(KERNEL_HANDLE_BASE,
								   &psPerProc->hPerProcData,
								   psPerProc,
								   PVRSRV_HANDLE_TYPE_PERPROC_DATA,
								   PVRSRV_HANDLE_ALLOC_FLAG_NONE);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle for per-process data (%d)", eError));
			goto failure;
		}


		eError = PVRSRVAllocHandleBase(&psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't allocate handle base for process (%d)", eError));
			goto failure;
		}


		eError = OSPerProcessSetHandleOptions(psPerProc->psHandleBase);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't set handle options (%d)", eError));
			goto failure;
		}


		eError = PVRSRVResManConnect(psPerProc, &psPerProc->hResManContext);
		if (eError != PVRSRV_OK)
		{
			PVR_DPF((PVR_DBG_ERROR, "PVRSRVPerProcessDataConnect: Couldn't register with the resource manager"));
			goto failure;
		}
	}

	psPerProc->ui32RefCount++;
	PVR_DPF((PVR_DBG_MESSAGE,
			"PVRSRVPerProcessDataConnect: Process 0x%x has ref-count %d",
			ui32PID, psPerProc->ui32RefCount));

	return eError;

failure:
	(IMG_VOID)FreePerProcessData(psPerProc);
	return eError;
}
Exemple #12
0
static int alloc_from_bt(struct RA_ARENA *arena, struct BT *bt, u32 start,
			 size_t size, u32 align,
			 struct BM_MAPPING **new_mapping, u32 *new_base)
{
	_FreeListRemove(arena, bt);
	PVR_ASSERT(bt->type == btt_free);
#ifdef RA_STATS
	arena->sStatistics.uLiveSegmentCount++;
	arena->sStatistics.uFreeSegmentCount--;
	arena->sStatistics.uFreeResourceCount -= bt->uSize;
#endif
	if (start > bt->base) {
		struct BT *next_bt;

		next_bt = _SegmentSplit(arena, bt, start - bt->base);

		if (!next_bt) {
			PVR_DPF(PVR_DBG_ERROR, "_AttemptAllocAligned: "
					"Front split failed");

			_FreeListInsert(arena, bt);
			return -1;
		}

		_FreeListInsert(arena, bt);
#ifdef RA_STATS
		arena->sStatistics.uFreeSegmentCount++;
		arena->sStatistics.uFreeResourceCount += bt->uSize;
#endif
		bt = next_bt;
	}

	if (bt->uSize > size) {
		struct BT *next_bt;
		next_bt = _SegmentSplit(arena, bt, size);

		if (!next_bt) {
			PVR_DPF(PVR_DBG_ERROR, "_AttemptAllocAligned: "
					"Back split failed");

			_FreeListInsert(arena, bt);
			return -1;
		}

		_FreeListInsert(arena, next_bt);
#ifdef RA_STATS
		arena->sStatistics.uFreeSegmentCount++;
		arena->sStatistics.uFreeResourceCount += next_bt->uSize;
#endif
	}

	bt->type = btt_live;

	if (!HASH_Insert(arena->pSegmentHash, bt->base, (u32)bt)) {
		_FreeBT(arena, bt, IMG_FALSE);
		return -1;
	}

	if (new_mapping)
		*new_mapping = bt->psMapping;

	*new_base = bt->base;

	return 0;
}
Exemple #13
0
IMG_BOOL
BM_Wrap (	IMG_HANDLE hDevMemHeap,
			IMG_SIZE_T ui32Size,
			IMG_SIZE_T ui32Offset,
			IMG_BOOL bPhysContig,
			IMG_SYS_PHYADDR *psSysAddr,
			IMG_VOID *pvCPUVAddr,
			IMG_UINT32 *pui32Flags,
			BM_HANDLE *phBuf)
{
	BM_BUF *pBuf;
	BM_CONTEXT *psBMContext;
	BM_HEAP *psBMHeap;
	SYS_DATA *psSysData;
	IMG_SYS_PHYADDR sHashAddress;
	IMG_UINT32 uFlags;

	psBMHeap = (BM_HEAP*)hDevMemHeap;
	psBMContext = psBMHeap->pBMContext;

	uFlags = psBMHeap->ui32Attribs & (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);

	if ((pui32Flags != IMG_NULL) && ((*pui32Flags & PVRSRV_HAP_CACHETYPE_MASK) != 0))
	{
		uFlags &= ~PVRSRV_HAP_CACHETYPE_MASK;
		uFlags |= *pui32Flags & PVRSRV_HAP_CACHETYPE_MASK;
	}

	PVR_DPF ((PVR_DBG_MESSAGE,
		  "BM_Wrap (uSize=0x%x, uOffset=0x%x, bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
			ui32Size, ui32Offset, bPhysContig, (IMG_UINTPTR_T)pvCPUVAddr, uFlags));

	SysAcquireData(&psSysData);

#if defined(PVR_LMA)
	if (bPhysContig)
	{
		if (!ValidSysPAddrRangeForDev(psBMContext->psDeviceNode, *psSysAddr, WRAP_MAPPING_SIZE(ui32Size, ui32Offset)))
		{
			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: System address range invalid for device"));
			return IMG_FALSE;
		}
	}
	else
	{
		IMG_SIZE_T ui32HostPageSize = HOST_PAGESIZE();

		if (!ValidSysPAddrArrayForDev(psBMContext->psDeviceNode, psSysAddr, WRAP_PAGE_COUNT(ui32Size, ui32Offset, ui32HostPageSize), ui32HostPageSize))
		{
			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: Array of system addresses invalid for device"));
			return IMG_FALSE;
		}
	}
#endif
	
	sHashAddress = psSysAddr[0];

	
	sHashAddress.uiAddr += ui32Offset;

	
	pBuf = (BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash, sHashAddress.uiAddr);

	if(pBuf)
	{
		IMG_SIZE_T ui32MappingSize = HOST_PAGEALIGN (ui32Size + ui32Offset);

		
		if(pBuf->pMapping->uSize == ui32MappingSize && (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
														pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr))
		{
			PVR_DPF((PVR_DBG_MESSAGE,
					"BM_Wrap (Matched previous Wrap! uSize=0x%x, uOffset=0x%x, SysAddr=%08X)",
					ui32Size, ui32Offset, sHashAddress.uiAddr));

			pBuf->ui32RefCount++;
			*phBuf = (BM_HANDLE)pBuf;
			if(pui32Flags)
				*pui32Flags = uFlags;

			return IMG_TRUE;
		}
	}

	
	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP,
						sizeof (BM_BUF),
						(IMG_PVOID *)&pBuf, IMG_NULL,
						"Buffer Manager buffer") != PVRSRV_OK)
	{
		PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED"));
		return IMG_FALSE;
	}
	OSMemSet(pBuf, 0, sizeof (BM_BUF));

	
	if (WrapMemory (psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr, pvCPUVAddr, uFlags, pBuf) != IMG_TRUE)
	{
		PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED"));
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof (BM_BUF), pBuf, IMG_NULL);
		
		return IMG_FALSE;
	}

	
	if(pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped || pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr)
	{
		
		PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr == pBuf->CpuPAddr.uiAddr);

		if (!HASH_Insert (psBMContext->pBufferHash, sHashAddress.uiAddr, (IMG_UINTPTR_T)pBuf))
		{
			FreeBuf (pBuf, uFlags, IMG_TRUE);
			PVR_DPF((PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED"));
			return IMG_FALSE;
		}
	}

	PVR_DPF ((PVR_DBG_MESSAGE,
			"BM_Wrap (uSize=0x%x, uFlags=0x%x, devVAddr=%08X)",
			ui32Size, uFlags, pBuf->DevVAddr.uiAddr));

	
	pBuf->ui32RefCount = 1;
	*phBuf = (BM_HANDLE)pBuf;
	if(pui32Flags)
	{
		
		*pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) | PVRSRV_HAP_MULTI_PROCESS;
	}

	return IMG_TRUE;
}
IMG_BOOL BM_Wrap(void *hDevMemHeap, u32 ui32Size, u32 ui32Offset,
		 IMG_BOOL bPhysContig, struct IMG_SYS_PHYADDR *psSysAddr,
		 void *pvCPUVAddr, u32 *pui32Flags, void **phBuf)
{
	struct BM_BUF *pBuf;
	struct BM_CONTEXT *psBMContext;
	struct BM_HEAP *psBMHeap;
	struct SYS_DATA *psSysData;
	struct IMG_SYS_PHYADDR sHashAddress;
	u32 uFlags;

	psBMHeap = (struct BM_HEAP *)hDevMemHeap;
	psBMContext = psBMHeap->pBMContext;

	uFlags = psBMHeap->ui32Attribs &
		 (PVRSRV_HAP_CACHETYPE_MASK | PVRSRV_HAP_MAPTYPE_MASK);

	if (pui32Flags)
		uFlags |= *pui32Flags;

	PVR_DPF(PVR_DBG_MESSAGE, "BM_Wrap (uSize=0x%x, uOffset=0x%x, "
			"bPhysContig=0x%x, pvCPUVAddr=0x%x, uFlags=0x%x)",
			ui32Size, ui32Offset, bPhysContig, pvCPUVAddr, uFlags);

	if (SysAcquireData(&psSysData) != PVRSRV_OK)
		return IMG_FALSE;

	sHashAddress = psSysAddr[0];

	sHashAddress.uiAddr += ui32Offset;

	pBuf = (struct BM_BUF *)HASH_Retrieve(psBMContext->pBufferHash,
				     (u32) sHashAddress.uiAddr);

	if (pBuf) {
		u32 ui32MappingSize =
		    HOST_PAGEALIGN(ui32Size + ui32Offset);

		if (pBuf->pMapping->uSize == ui32MappingSize &&
		    (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
		      pBuf->pMapping->eCpuMemoryOrigin ==
			hm_wrapped_virtaddr)) {
			PVR_DPF(PVR_DBG_MESSAGE, "BM_Wrap "
				"(Matched previous Wrap! uSize=0x%x, "
				"uOffset=0x%x, SysAddr=%08X)",
				 ui32Size, ui32Offset, sHashAddress.uiAddr);

			pBuf->ui32RefCount++;
			*phBuf = (void *)pBuf;
			if (pui32Flags)
				*pui32Flags = uFlags;

			return IMG_TRUE;
		}
	}

	if (OSAllocMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF),
		       (void **)&pBuf, NULL) != PVRSRV_OK) {
		PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: BM_Buf alloc FAILED");
		return IMG_FALSE;
	}
	OSMemSet(pBuf, 0, sizeof(struct BM_BUF));

	if (WrapMemory(psBMHeap, ui32Size, ui32Offset, bPhysContig, psSysAddr,
			pvCPUVAddr, uFlags, pBuf) != IMG_TRUE) {
		PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: WrapMemory FAILED");
		OSFreeMem(PVRSRV_OS_PAGEABLE_HEAP, sizeof(struct BM_BUF), pBuf,
			  NULL);
		return IMG_FALSE;
	}

	if (pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped ||
	    pBuf->pMapping->eCpuMemoryOrigin == hm_wrapped_virtaddr) {

		PVR_ASSERT(SysSysPAddrToCpuPAddr(sHashAddress).uiAddr ==
			   pBuf->CpuPAddr.uiAddr);

		if (!HASH_Insert(psBMContext->pBufferHash,
				 (u32)sHashAddress.uiAddr, (u32) pBuf)) {
			FreeBuf(pBuf, uFlags);
			PVR_DPF(PVR_DBG_ERROR, "BM_Wrap: HASH_Insert FAILED");
			return IMG_FALSE;
		}
	}

	PVR_DPF(PVR_DBG_MESSAGE,
		 "BM_Wrap (uSize=0x%x, uFlags=0x%x)=%08X(devVAddr=%08X)",
		 ui32Size, uFlags, pBuf, pBuf->DevVAddr.uiAddr);

	pBuf->ui32RefCount = 1;
	pvr_get_ctx(psBMContext);
	*phBuf = (void *) pBuf;
	if (pui32Flags)
		*pui32Flags = (uFlags & ~PVRSRV_HAP_MAPTYPE_MASK) |
			      PVRSRV_HAP_MULTI_PROCESS;

	return IMG_TRUE;
}
Exemple #15
0
static IMG_BOOL
_AttemptAllocAligned (RA_ARENA *pArena,
					  IMG_SIZE_T uSize,
					  BM_MAPPING **ppsMapping,
					  IMG_UINT32 uFlags,
					  IMG_UINT32 uAlignment,
					  IMG_UINT32 uAlignmentOffset,
					  IMG_UINTPTR_T *base)
{
	IMG_UINT32 uIndex;
	PVR_ASSERT (pArena!=IMG_NULL);
	if (pArena == IMG_NULL)
	{
		PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: invalid parameter - pArena"));
		return IMG_FALSE;
	}

	if (uAlignment>1)
		uAlignmentOffset %= uAlignment;

	

	uIndex = pvr_log2 (uSize);

#if 0
	
	if (1u<<uIndex < uSize)
		uIndex++;
#endif

	while (uIndex < FREE_TABLE_LIMIT && pArena->aHeadFree[uIndex]==IMG_NULL)
		uIndex++;

	while (uIndex < FREE_TABLE_LIMIT)
	{
		if (pArena->aHeadFree[uIndex]!=IMG_NULL)
		{
			
			BT *pBT;

			pBT = pArena->aHeadFree [uIndex];
			while (pBT!=IMG_NULL)
			{
				IMG_UINTPTR_T aligned_base;

				if (uAlignment>1)
					aligned_base = (pBT->base + uAlignmentOffset + uAlignment - 1) / uAlignment * uAlignment - uAlignmentOffset;
				else
					aligned_base = pBT->base;
				PVR_DPF ((PVR_DBG_MESSAGE,
						  "RA_AttemptAllocAligned: pBT-base=0x%x "
						  "pBT-size=0x%x alignedbase=0x%x size=0x%x",
						pBT->base, pBT->uSize, aligned_base, uSize));

				if (pBT->base + pBT->uSize >= aligned_base + uSize)
				{
					if(!pBT->psMapping || pBT->psMapping->ui32Flags == uFlags)
					{
						_FreeListRemove (pArena, pBT);

						PVR_ASSERT (pBT->type == btt_free);

#ifdef RA_STATS
						pArena->sStatistics.uLiveSegmentCount++;
						pArena->sStatistics.uFreeSegmentCount--;
						pArena->sStatistics.uFreeResourceCount-=pBT->uSize;
#endif

						
						if (aligned_base > pBT->base)
						{
							BT *pNeighbour;
							pNeighbour = _SegmentSplit (pArena, pBT, (IMG_SIZE_T)(aligned_base - pBT->base));
							
							if (pNeighbour==IMG_NULL)
							{
								PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Front split failed"));
								
								_FreeListInsert (pArena, pBT);
								return IMG_FALSE;
							}

							_FreeListInsert (pArena, pBT);
	#ifdef RA_STATS
							pArena->sStatistics.uFreeSegmentCount++;
							pArena->sStatistics.uFreeResourceCount+=pBT->uSize;
	#endif
							pBT = pNeighbour;
						}

						
						if (pBT->uSize > uSize)
						{
							BT *pNeighbour;
							pNeighbour = _SegmentSplit (pArena, pBT, uSize);
							
							if (pNeighbour==IMG_NULL)
							{
								PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned: Back split failed"));
								
								_FreeListInsert (pArena, pBT);
								return IMG_FALSE;
							}

							_FreeListInsert (pArena, pNeighbour);
	#ifdef RA_STATS
							pArena->sStatistics.uFreeSegmentCount++;
							pArena->sStatistics.uFreeResourceCount+=pNeighbour->uSize;
	#endif
						}

						pBT->type = btt_live;

#if defined(VALIDATE_ARENA_TEST)
						if (pBT->eResourceType == IMPORTED_RESOURCE_TYPE)
						{
							pBT->eResourceSpan = IMPORTED_RESOURCE_SPAN_LIVE;
						}
						else if (pBT->eResourceType == NON_IMPORTED_RESOURCE_TYPE)
						{
							pBT->eResourceSpan = RESOURCE_SPAN_LIVE;
						}
						else
						{
							PVR_DPF ((PVR_DBG_ERROR,"_AttemptAllocAligned ERROR: pBT->eResourceType unrecognized"));
							PVR_DBG_BREAK;
						}
#endif
						if (!HASH_Insert (pArena->pSegmentHash, pBT->base, (IMG_UINTPTR_T) pBT))
						{
							_FreeBT (pArena, pBT, IMG_FALSE);
							return IMG_FALSE;
						}

						if (ppsMapping!=IMG_NULL)
							*ppsMapping = pBT->psMapping;

						*base = pBT->base;

						return IMG_TRUE;
					}
					else
					{
						PVR_DPF ((PVR_DBG_MESSAGE,
								"AttemptAllocAligned: mismatch in flags. Import has %x, request was %x", pBT->psMapping->ui32Flags, uFlags));

					}
				}
				pBT = pBT->pNextFree;
			}

		}
		uIndex++;
	}

	return IMG_FALSE;
}