summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 4139506)
raw | patch | inline | side by side (parent: 4139506)
author | Justin Sobota <jsobota@ti.com> | |
Fri, 18 Jan 2013 23:30:24 +0000 (18:30 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Fri, 18 Jan 2013 23:30:24 +0000 (18:30 -0500) |
12 files changed:
index 84528859981a7f52ea9fb735be736e48537df0e9..223377076142030a681dfe7583131a653f68176b 100644 (file)
Binary files a/device/tci6614-server-policy.dtb and b/device/tci6614-server-policy.dtb differ
Binary files a/device/tci6614-server-policy.dtb and b/device/tci6614-server-policy.dtb differ
diff --git a/include/rm_loc.h b/include/rm_loc.h
index efb5f07aef10dbee4e03a84594a73a96190115cc..843a1d94c9e4b4edfcae22e3f2b00bdfc2e5e795 100644 (file)
--- a/include/rm_loc.h
+++ b/include/rm_loc.h
/* AVL BBST includes */
#include <ti/drv/rm/include/tree.h>
-/** String stored for resource elements that are not currently allocated to anyone. If the
- * resource is allocated the allocatedTo field will be populated with the RM instance
- * name it was allocated to. */
-#define RM_NOT_ALLOCATED_STRING "\0"
-/** String stored for resource elements that are reserved by the Linux kernel. These
- * resources will be in use for the lifetime of the system */
-#define RM_ALLOCATED_TO_LINUX "Linux-Kernel"
-
/** Maximum size of a transmittable RM policy in bytes */
#define RM_MAX_POLICY_SIZE_BYTES (64) // Placeholder: This will change
// during development
/** Pointer to the RM instance's policy information */
typedef void *Rm_Policy;
+/** Pointer to the RM instance's valid policy instances */
+typedef void *Rm_PolicyValidInstances;
+
+
/**
* @brief RM protocol packet resource information
*/
typedef struct {
/** Resource name of resource affected by command */
- char name[RM_RESOURCE_NAME_MAX_CHARS];
+ char name[RM_RESOURCE_NAME_MAX_CHARS];
/** If applicable, start of resource range affected by command. If
* RM_RESOURCE_UNSPECIFIED is assigned the higher level RM agent*/
- int32_t base;
+ int32_t base;
/** If applicable, number of specified resource, starting from base, affected by command */
uint32_t length;
/** If applicable, the alignment of the resource affected by the command */
- int32_t alignment;
+ int32_t alignment;
/** If applicable, the NameServer name assigned to the specified
* resource. Used for commands centering on RM NameServer actions */
- char nsName[RM_RESOURCE_NAME_MAX_CHARS];
+ char nsName[RM_RESOURCE_NAME_MAX_CHARS];
} Rm_ResourceInfo;
/**
typedef struct {
const void *rangeData;
- int32_t rangeLen;
+ int32_t rangeLen;
const void *nsAssignData;
- int32_t nsAssignLen;
+ int32_t nsAssignLen;
const void *linuxAliasData;
- int32_t linuxAliasLen;
+ int32_t linuxAliasLen;
} Rm_ResourceProperties;
typedef enum {
Rm_allocatorOp_ALLOCATE = 0,
- Rm_allocatorOp_FREE = 1,
- Rm_allocatorOp_PRE_ALLOCATE = 2,
+ Rm_allocatorOp_FREE,
+ Rm_allocatorOp_PRE_ALLOCATE
} Rm_AllocatorOp;
typedef struct {
- char *serviceSrcInstName;
- Rm_AllocatorOp operation;
- /* Will contain the actual allocation/free values */
+ void *serviceSrcInstNode;
+ Rm_AllocatorOp operation;
Rm_ResourceInfo *resourceInfo;
} Rm_AllocatorOpInfo;
-typedef struct {
+typedef struct Rm_Allocator_s {
char resourceName[RM_RESOURCE_NAME_MAX_CHARS];
/** Pointer to the first resource entry in the allocator */
void *allocatorRootEntry;
/** Pointer to next resource allocator */
- void *nextAllocator;
+ struct Rm_Allocator_s *nextAllocator;
} Rm_Allocator;
typedef struct {
Rm_InstType instType;
bool registeredWithDelegateOrServer;
Rm_Policy policy;
+ Rm_PolicyValidInstances validInstances;
Rm_Allocators allocators;
Rm_NameServer nameServer;
/* RM instance transport parameters */
/* Declare the tree structure nodes */
typedef struct Rm_AllocatedTo_s {
- char instName[RM_INSTANCE_NAME_MAX_CHARS];
+ void *instNameNode;
struct Rm_AllocatedTo_s *nextAllocatedTo;
} Rm_AllocatedTo;
typedef struct _Rm_ResourceNode {
- RB_ENTRY(_Rm_ResourceNode) linkage;
- uint32_t base;
- uint32_t length;
- Rm_AllocatedTo *allocatedTo;
+ RB_ENTRY(_Rm_ResourceNode) linkage;
+ uint32_t base;
+ uint32_t length;
+ uint16_t allocationCount;
+ Rm_AllocatedTo *allocatedTo;
} Rm_ResourceNode;
/* Declare the tree head structure. A structure of type Rm_ResourceTree will need to be
* malloc'd for each tree that is to be created. */
typedef RB_HEAD(_Rm_ResourceTree, _Rm_ResourceNode) Rm_ResourceTree;
-Rm_ResourceNode *Rm_newResourceNode(uint32_t resourceBase, uint32_t resourceLength,
- char *allocatedTo);
+Rm_ResourceNode *Rm_newResourceNode(uint32_t resourceBase, uint32_t resourceLength);
void Rm_freeResourceNode(Rm_ResourceNode *node);
/* Prototype for tree node comparison function
* element1 < element2 --> return < 0
diff --git a/include/rm_policyloc.h b/include/rm_policyloc.h
index b51e746803764a55c99c49ea8c80869d953cc2af..44edff05c701aa70ccb5ca9163b340ca9f0cc320 100644 (file)
--- a/include/rm_policyloc.h
+++ b/include/rm_policyloc.h
/* RM internal API includes */
#include <ti/drv/rm/include/rm_loc.h>
+/* AVL BBST includes */
+#include <ti/drv/rm/include/tree.h>
+
+/** String stored for resource elements that are reserved by the Linux kernel. These
+ * resources will be in use for the lifetime of the system
+ *
+ * TODO: MOVE TO policy.h LATER SO INTEGRATORS KNOW NOT TO NAME RM INSTANCES THIS NAME*/
+#define RM_ALLOCATED_TO_LINUX "Linux-Kernel"
+
/* Bit : Description
*-----------------------------
* 0 : Init (iI) - RM instance has initialization permission for resource
*/
typedef uint16_t Rm_PermissionBits;
-#define RM_POLICY_PERM_INIT_LOWER 'i'
-#define RM_POLICY_PERM_INIT_UPPER 'I'
-#define RM_POLICY_PERM_INIT_SHIFT 0
-#define RM_POLICY_PERM_USE_LOWER 'u'
-#define RM_POLICY_PERM_USE_UPPER 'U'
-#define RM_POLICY_PERM_USE_SHIFT 1
-#define RM_POLICY_PERM_EXCLUSIVE_LOWER 'x'
-#define RM_POLICY_PERM_EXCLUSIVE_UPPER 'X'
-#define RM_POLICY_PERM_EXCLUSIVE_SHIFT 2
+#define RM_POLICY_PERM_INIT_LOWER 'i'
+#define RM_POLICY_PERM_INIT_UPPER 'I'
+#define RM_POLICY_PERM_INIT_SHIFT 0
+#define RM_POLICY_PERM_USE_LOWER 'u'
+#define RM_POLICY_PERM_USE_UPPER 'U'
+#define RM_POLICY_PERM_USE_SHIFT 1
+#define RM_POLICY_PERM_EXCLUSIVE_LOWER 'x'
+#define RM_POLICY_PERM_EXCLUSIVE_UPPER 'X'
+#define RM_POLICY_PERM_EXCLUSIVE_SHIFT 2
#define RM_POLICY_PERM_SHARED_LINUX_LOWER 's'
#define RM_POLICY_PERM_SHARED_LINUX_UPPER 'S'
-#define RM_POLICY_PERM_SHARED_LINUX_SHIFT 3
+#define RM_POLICY_PERM_SHARED_LINUX_SHIFT 3
-#define RM_POLICY_PERM_SUBGROUP_START '('
-#define RM_POLICY_PERM_SUBGROUP_END ')'
-#define RM_POLICY_PERM_TERMINATOR '&'
-#define RM_POLICY_PERM_ASSIGNMENT '='
+#define RM_POLICY_PERM_SUBGROUP_START '('
+#define RM_POLICY_PERM_SUBGROUP_END ')'
+#define RM_POLICY_PERM_TERMINATOR '&'
+#define RM_POLICY_PERM_ASSIGNMENT '='
#define RM_POLICY_SET_PERM(permBits, permTypeShift, val) \
permBits = ((permBits & (~(((Rm_PermissionBits) 0x1) << permTypeShift))) | \
((permBits >> permTypeShift) & 0x1)
typedef struct Rm_Permission_s {
- char instName[RM_INSTANCE_NAME_MAX_CHARS];
- Rm_PermissionBits permissionBits;
+ char instName[RM_INSTANCE_NAME_MAX_CHARS];
+ Rm_PermissionBits permissionBits;
struct Rm_Permission_s *nextPermission;
} Rm_PolicyPermission;
typedef struct {
const void *assignmentData;
- int32_t assignmentLen;
+ int32_t assignmentLen;
const void *allocationSizeData;
- int32_t allocationSizeLen;
+ int32_t allocationSizeLen;
const void *alignmentData;
- int32_t alignmentLen;
+ int32_t alignmentLen;
} Rm_PolicyNodeProperties;
-int32_t Rm_policyInit(Rm_Inst *rmInst, void *policyDtb);
+void Rm_policyIncrementValidInstAllocationCount(void *validInstNameNode);
+void Rm_policyDecrementValidInstAllocationCount(void *validInstNameNode);
+void *Rm_policyGetValidInstNode(void *validInstTree, char *instName);
+char *Rm_policyGetValidInstNodeName(void *validInstNode);
+void *Rm_policyGetLinuxInstNode(void *validInstTree);
+int32_t Rm_policyValidatePolicy(Rm_Inst *rmInst, void *policyDtb);
+void *Rm_policyCreateValidInstTree(void *policyDtb, int32_t *result);
+
+/**********************************************************************
+ ******************* Red-Black Tree BBST Defines **********************
+ **********************************************************************/
+
+/* Declare the tree structure nodes */
+typedef struct _Rm_ValidInstNode {
+ RB_ENTRY(_Rm_ValidInstNode) linkage;
+ char name[RM_INSTANCE_NAME_MAX_CHARS];
+ uint32_t allocRefCount;
+ bool deletePending;
+} Rm_ValidInstNode;
+
+/* Declare the tree head structure. */
+typedef RB_HEAD(_Rm_ValidInstTree, _Rm_ValidInstNode) Rm_ValidInstTree;
+
+Rm_ValidInstNode *Rm_newValidInstNode(char *instName);
+void Rm_freeValidInstNode(Rm_ValidInstNode *node);
+/* Prototype for Valid Instance node comparison function
+ * element1 < element2 --> return < 0
+ * element1 = element2 --> return 0
+ * element1 > element2 --> return > 0 */
+int Rm_ValidInstNodeCompare(Rm_ValidInstNode *element1, Rm_ValidInstNode *element2);
+
+/* Generate the tree prototypes */
+RB_PROTOTYPE(_Rm_ValidInstTree, _Rm_ValidInstNode, linkage, Rm_ValidInstNodeCompare);
#ifdef __cplusplus
}
index fa6154cc7f488501e25763bb1685d7b02d8e0f34..db97dec161e08396d5bda3508e083a8c30e64ef6 100644 (file)
* @brief Resource Request Packet Types
*/
typedef enum {
- /** Resource allocation request */
- Rm_resReqPktType_ALLOCATE = 0,
+ /** Resource allocate for init request */
+ Rm_resReqPktType_ALLOCATE_INIT = 0,
+ /** Resource allocate for use request */
+ Rm_resReqPktType_ALLOCATE_USE,
/** Free resource */
- Rm_resReqPktType_FREE = 1,
+ Rm_resReqPktType_FREE,
/** Get name resource */
- Rm_resReqPktType_GET_NAMED = 2
+ Rm_resReqPktType_GET_NAMED
} Rm_ResourceReqPktType;
/**
index d5f2cb23c62f92cbc37d36ae57f93555090a3e6c..c8967039fda9053cdb0f8883ee83bc3bf168fc4f 100644 (file)
--- a/rm.h
+++ b/rm.h
#define RM_INIT_ERROR_POLICY_UNKNOWN_INSTANCE -258
#define RM_INIT_ERROR_POLICY_PERMISSION_SYNTAX_ERROR -259
#define RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE -260
-#define RM_INIT_ERROR_POLICY_SYNTAX_ERROR - 261
+#define RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_INSTANCE_GROUP -261
+#define RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR -262
+#define RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_PERM_CHAR -263
+#define RM_INIT_ERROR_POLICY_SYNTAX_ERROR_PERM_CHAR_WITHOUT_ASSIGN_CHAR -264
+#define RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_CHAR_ON_RIGHT_WITH_ASSINMENT_ON_LEFT -265
/**
* @brief Maximum number of characters in a RM instance name
*/
-#define RM_INSTANCE_NAME_MAX_CHARS (24)
+#define RM_INSTANCE_NAME_MAX_CHARS (32)
/**
* @brief RM Handle provided to application. The RM Handle is used by the
diff --git a/rm_services.h b/rm_services.h
index ce45ff1528fe359db733a50879ba6251178f63a2..abdf555128db250c50bd72aa4d3e0406596196cf 100644 (file)
--- a/rm_services.h
+++ b/rm_services.h
/** No valid ranges were specified for the resource within the RM instance's node within the policy.
* By default all resource requests for this resource are denied */
#define RM_SERVICE_DENIED_POLICY_DENIAL_NO_RANGES_SPECIFIED (RM_SERVICE_DENIED_BEGIN+16)
+/** The instance name of the service requesting instance is not in the policy valid instance list */
+#define RM_SERVICE_DENIED_ORIGINATING_INSTANCE_NAME_NOT_VALID (RM_SERVICE_DENIED_BEGIN+17)
/** End of resource denied reasons */
-#define RM_SERVICE_DENIED_END (RM_SERVICE_DENIED_BEGIN+16)
+#define RM_SERVICE_DENIED_END (RM_SERVICE_DENIED_BEGIN+17)
/** RM Service Request Error Code Base */
#define RM_SERVICE_ERROR_BASE (-64)
#define RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR (RM_SERVICE_ERROR_BASE-7)
/** RM service response from higher level agent did not match any requests made
* by the provided RM instance */
-#define RM_SERVICE_ERROR_TRANSACTION_DOES_NOT_EXST_FOR_THIS_RM_INSTANCE (RM_SERVICE_ERROR_BASE-8)
+#define RM_SERVICE_ERROR_TRANSACTION_DOES_NOT_EXIST_FOR_THIS_RM_INSTANCE (RM_SERVICE_ERROR_BASE-8)
/** RM failed to allocate memory for new service transaction */
#define RM_SERVICE_ERROR_TRANSACTION_FAILED_TO_ALLOCATE (RM_SERVICE_ERROR_BASE-9)
/** RM could not find the service transaction in the RM instance's transaction queue */
* @brief RM service types
*/
typedef enum {
- /** RM resource allocate service */
- Rm_service_RESOURCE_ALLOCATE = 0,
+ /** RM resource allocate for initialization service */
+ Rm_service_RESOURCE_ALLOCATE_INIT = 0,
+ /** RM resource allocate for use service */
+ Rm_service_RESOURCE_ALLOCATE_USE,
/** RM resource free service */
- Rm_service_RESOURCE_FREE = 1,
+ Rm_service_RESOURCE_FREE,
/** RM resource mapping to name service */
- Rm_service_RESOURCE_MAP_TO_NAME = 2,
+ Rm_service_RESOURCE_MAP_TO_NAME,
/** RM resource get by name service */
- Rm_service_RESOURCE_GET_BY_NAME = 3,
+ Rm_service_RESOURCE_GET_BY_NAME,
/** RM resource name unmapping service */
- Rm_service_RESOURCE_UNMAP_NAME = 4
+ Rm_service_RESOURCE_UNMAP_NAME
} Rm_ServiceType;
/**
diff --git a/src/rm.c b/src/rm.c
index 64d79f07d8891390a6cbb90442fbcd24805e460a..7851b655797e677e38d03ae43ed82281eafab051 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
************** Red-Black BBST Tree Allocator Functions ***************\r
**********************************************************************/\r
\r
-/* Prototype for function that allocates new tree nodes */\r
-Rm_ResourceNode *Rm_newResourceNode(uint32_t resourceBase, uint32_t resourceLength, \r
- char *allocatedTo)\r
+\r
+Rm_ResourceNode *Rm_newResourceNode(uint32_t resourceBase, uint32_t resourceLength)\r
{\r
Rm_ResourceNode *newNode = NULL;\r
\r
newNode = Rm_osalMalloc(sizeof(Rm_ResourceNode));\r
+ memset((void *)newNode, 0, sizeof(Rm_ResourceNode));\r
\r
- /* Populate the RM relevant fields */\r
newNode->base = resourceBase;\r
newNode->length = resourceLength;\r
- newNode->allocatedTo = Rm_osalMalloc(sizeof(Rm_AllocatedTo);\r
- strcpy(newNode->allocatedTo->instName, allocatedTo);\r
- newNode->allocatedTo->nextAllocatedTo = NULL;\r
+ newNode->allocationCount = 0;\r
+ newNode->allocatedTo = NULL;\r
\r
return(newNode);\r
}\r
\r
-/* Prototype for function that frees new tree nodes */\r
void Rm_freeResourceNode(Rm_ResourceNode *node)\r
{\r
- /* Free the memory associated with the tree node. */\r
- Rm_osalFree((void *)node, sizeof(Rm_ResourceNode));\r
+ if (node->allocationCount == 0) {\r
+ Rm_osalFree((void *)node, sizeof(Rm_ResourceNode));\r
+ }\r
}\r
\r
/* Prototype for tree node comparison function\r
@@ -111,19 +109,16 @@ int Rm_ResourceNodeCompare(Rm_ResourceNode *element1, Rm_ResourceNode *element2)
uint32_t element1End = element1->base + element1->length - 1;\r
uint32_t element2End = element2->base + element2->length - 1;\r
\r
- if (element1End < element2->base)\r
- {\r
+ if (element1End < element2->base) {\r
/* End of element1 range is less than the start of element2's range. Return a negative\r
* value */\r
return (-1);\r
}\r
- else if (element1->base > element2End)\r
- {\r
+ else if (element1->base > element2End) {\r
/* Start of element1 range is after end of element2's range. Return a positive value */\r
return (1);\r
}\r
- else\r
- {\r
+ else {\r
/* If neither of the latter conditions were satisfied there is some overlap between\r
* element1 and element2. Return 0 since the application must handle this overlap. */\r
return (0);\r
@@ -140,8 +135,8 @@ RB_GENERATE(_Rm_ResourceTree, _Rm_ResourceNode, linkage, Rm_ResourceNodeCompare)
Rm_Transaction *Rm_transactionQueueAdd(Rm_Inst *rmInst)\r
{\r
Rm_Transaction *transactionQueue = (Rm_Transaction *)rmInst->transactionQueue;\r
- Rm_Transaction *newTransaction = NULL;\r
- void *key;\r
+ Rm_Transaction *newTransaction = NULL;\r
+ void *key;\r
\r
/* Lock access to the RM instance's transaction queue */\r
key = Rm_osalMtCsEnter();\r
newTransaction = Rm_osalMalloc(sizeof(Rm_Transaction));\r
\r
/* Return if the memory allocated for the transaction entry is NULL */\r
- if (newTransaction != NULL)\r
- {\r
+ if (newTransaction != NULL) {\r
/* Clear the transaction */\r
memset((void *)newTransaction, 0, sizeof(Rm_Transaction));\r
\r
newTransaction->nextTransaction = NULL; \r
\r
/* Check if there are any transactions in the transaction queue */\r
- if (transactionQueue)\r
- {\r
+ if (transactionQueue) {\r
/* At least one transaction in the transaction queue. Add the new entry to the \r
* end of the transaction queue */\r
- while (transactionQueue->nextTransaction != NULL)\r
- {\r
+ while (transactionQueue->nextTransaction != NULL) {\r
/* Traverse the list until arriving at the last transaction */\r
transactionQueue = transactionQueue->nextTransaction;\r
}\r
/* Add the new transaction to the end of the queue */\r
transactionQueue->nextTransaction = newTransaction;\r
}\r
- else\r
- {\r
+ else {\r
/* The transaction queue does not currently exist. The new transaction is the \r
* first transaction */\r
rmInst->transactionQueue = newTransaction;\r
@@ -193,42 +184,30 @@ Rm_Transaction *Rm_transactionQueueFind(Rm_Inst *rmInst, uint32_t transactionId)
{\r
Rm_Transaction *transaction = (Rm_Transaction *)rmInst->transactionQueue;\r
\r
- /* Make sure there is at least one transaction in the transaction queue */\r
- if (transaction != NULL)\r
- {\r
- /* Find the transaction ID within the specified RM instance's transaction queue.\r
- * If the end of the transaction queue is reached without finding the transaction the \r
- * transaction pointer will be NULL */\r
- while (transaction != NULL)\r
- {\r
- if (transaction->localId == transactionId)\r
- {\r
- /* Match: break out of loop and return the transaction */\r
+ if (transaction != NULL) {\r
+ while (transaction != NULL) {\r
+ if (transaction->localId == transactionId) {\r
break; \r
}\r
transaction = transaction->nextTransaction;\r
}\r
}\r
-\r
return (transaction);\r
}\r
\r
int32_t Rm_transactionQueueDelete(Rm_Inst *rmInst, uint32_t transactionId)\r
{\r
- Rm_Transaction *transaction = (Rm_Transaction *) rmInst->transactionQueue;\r
+ Rm_Transaction *transaction = (Rm_Transaction *) rmInst->transactionQueue;\r
Rm_Transaction *prevTransaction = NULL;\r
- int32_t retVal = RM_SERVICE_STATE_OKAY;\r
- void *key;\r
+ int32_t retVal = RM_SERVICE_STATE_OKAY;\r
+ void *key;\r
\r
- /* Lock access to the RM instance's transaction queue */\r
+ /* Lock access to the instance */\r
key = Rm_osalMtCsEnter();\r
\r
- /* Find the transaction ID within the specified RM instance's transaction queue. */\r
- while (transaction != NULL)\r
- {\r
- if (transaction->localId == transactionId)\r
- {\r
- /* Match: break out of loop and delete the transaction */\r
+ /* Find transaction ID within transaction queue. */\r
+ while (transaction) {\r
+ if (transaction->localId == transactionId) {\r
break; \r
}\r
\r
transaction = transaction->nextTransaction;\r
}\r
\r
- /* Traversed entire queue but did not find transaction */\r
- if (transaction == NULL)\r
- {\r
- retVal = RM_SERVICE_ERROR_SERVICE_TRANSACTION_DOES_NOT_EXIST;\r
- }\r
- else\r
- {\r
- /* Delete the transaction */\r
- if (prevTransaction == NULL)\r
- {\r
- /* Transaction to be deleted exists at start of transaction queue. Map second\r
- * transaction to be start of transaction queue as long as there are more than\r
- * one transactions. */\r
+ if (transaction) {\r
+ if (prevTransaction == NULL) {\r
+ /* Transaction at start of queue. Map second transaction to start of queue \r
+ * as long as more than one transactions. */\r
rmInst->transactionQueue = transaction->nextTransaction;\r
}\r
- else\r
- {\r
- /* Transaction to be deleted is in the middle or at end of the queue. Adjust \r
- * adjacent transaction pointers. This covers the case where the transaction to be \r
- * removed is at the end of the queue. */\r
+ else {\r
+ /* Transaction in middle or end of queue. */\r
prevTransaction->nextTransaction = transaction->nextTransaction;\r
}\r
-\r
- /* Free the memory associated with the transaction. */\r
Rm_osalFree((void *)transaction, sizeof(Rm_Transaction));\r
}\r
+ else {\r
+ retVal = RM_SERVICE_ERROR_SERVICE_TRANSACTION_DOES_NOT_EXIST;\r
+ } \r
\r
Rm_osalMtCsExit(key);\r
return (retVal);\r
\r
uint32_t Rm_transactionInitSequenceNum(void)\r
{\r
- /* Sequence number can never have a value of zero so that there are no conflicts\r
- * with transactions that have a remoteOriginatingId of zero */\r
+ /* Sequence number can never have value of 0. Avoids conflicts\r
+ * with non-response transactions that have remoteOriginatingId of 0 */\r
return (1);\r
}\r
\r
{\r
uint32_t sequenceNum = 0;\r
\r
- /* Get the next sequence number and then increment. If there's an overflow\r
- * assign the initial value instead of incrementing. */\r
- if (rmInst->transactionSeqNum + 1 < rmInst->transactionSeqNum)\r
- {\r
+ if (rmInst->transactionSeqNum + 1 < rmInst->transactionSeqNum) {\r
/* Overflow */\r
sequenceNum = rmInst->transactionSeqNum;\r
rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
}\r
- else\r
- {\r
+ else {\r
sequenceNum = rmInst->transactionSeqNum++;\r
} \r
-\r
return (sequenceNum);\r
}\r
\r
Rm_Allocator *Rm_allocatorAdd(Rm_Inst *rmInst, const char *resourceName)\r
{\r
- Rm_Allocator *allocators = (Rm_Allocator *)rmInst->allocators;\r
+ Rm_Allocator *allocators = (Rm_Allocator *)rmInst->allocators;\r
Rm_Allocator *newAllocator = NULL;\r
- void *key;\r
+ void *key;\r
\r
- /* Lock access to the RM instance's allocator list */\r
+ /* Lock access to the instance */\r
key = Rm_osalMtCsEnter();\r
\r
- /* Get memory for a new allocator from local memory */\r
newAllocator = Rm_osalMalloc(sizeof(Rm_Allocator));\r
\r
- /* Return if the memory allocated for the allocator is NULL */\r
- if (newAllocator != NULL)\r
- {\r
- /* Clear the allocator */\r
+ if (newAllocator) {\r
memset((void *)newAllocator, 0, sizeof(Rm_Allocator));\r
-\r
- /* Populate the allocator */\r
strcpy(newAllocator->resourceName, resourceName);\r
- /* allocator's root entry will be created by the invoking function */\r
newAllocator->allocatorRootEntry = NULL;\r
- /* New allocator's nextAllocator pointer will always be NULL */\r
newAllocator->nextAllocator = NULL; \r
\r
- /* Check if there are any allocators in the allocator list */\r
- if (allocators)\r
- {\r
- /* At least one allocator in the allocator list. Add the new allocator to the \r
- * end of the allocator list */\r
- while (allocators->nextAllocator != NULL)\r
- {\r
- /* Traverse the list until arriving at the last allocator */\r
+ /* Add allocator to end of list */\r
+ if (allocators) {\r
+ while (allocators->nextAllocator != NULL) {\r
allocators = allocators->nextAllocator;\r
}\r
-\r
- /* Add the new allocator to the end of the list */\r
allocators->nextAllocator = newAllocator;\r
}\r
- else\r
- {\r
- /* The allocator list does not currently exist. The new allocator is the \r
- * first allocator */\r
+ else {\r
rmInst->allocators = newAllocator;\r
}\r
}\r
{\r
Rm_Allocator *allocator = (Rm_Allocator *)rmInst->allocators;\r
\r
- /* Make sure there is at least one allocator in the allocator list */\r
- if (allocator != NULL)\r
- {\r
- /* Find the resource name within the allocator list. If the end of the\r
- * allocator list is reached without finding the resource name the \r
- * allocator pointer will be NULL */\r
- while (allocator != NULL)\r
- {\r
- if (strcmp(allocator->resourceName, resourceName) == 0)\r
- {\r
- /* Match: break out of loop and return the allocator */\r
- break; \r
- }\r
- allocator = allocator->nextAllocator;\r
+ while (allocator) {\r
+ if (strcmp(allocator->resourceName, resourceName) == 0) {\r
+ break; \r
}\r
+ allocator = allocator->nextAllocator;\r
}\r
\r
return (allocator);\r
{\r
Rm_Allocator *allocator = (Rm_Allocator *) rmInst->allocators;\r
Rm_Allocator *prevAllocator = NULL;\r
- int32_t retVal = RM_SERVICE_STATE_OKAY;\r
- void *key;\r
+ int32_t retVal = RM_SERVICE_STATE_OKAY;\r
+ void *key;\r
\r
- /* Lock access to the RM instance's allocator list */\r
+ /* Lock access to instance */\r
key = Rm_osalMtCsEnter();\r
\r
- /* Find the resource within the specified RM instance's allocator list. */\r
- while (allocator != NULL)\r
- {\r
- if (strcmp(allocator->resourceName, resourceName) == 0)\r
- {\r
- /* Match: break out of loop and delete the transaction */\r
+ while (allocator) {\r
+ if (strcmp(allocator->resourceName, resourceName) == 0) {\r
break; \r
}\r
-\r
prevAllocator = allocator;\r
allocator = allocator->nextAllocator;\r
}\r
\r
- /* Traversed entire list but did not find allocator. */\r
- if (allocator == NULL)\r
- {\r
- retVal = -22; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
- }\r
- else\r
- {\r
- /* Delete the allocator */\r
- if (prevAllocator == NULL)\r
- {\r
- /* Allocator to be deleted exists at start of allocator list. Map second\r
- * allocator to be start of allocator list as long as there are more than\r
- * one allocators. */\r
+ if (allocator) {\r
+ if (prevAllocator == NULL) {\r
+ /* Allocator at start of list. Map second allocator to start of list \r
+ * as long as more than one allocators. */\r
rmInst->allocators = allocator->nextAllocator;\r
}\r
- else\r
- {\r
- /* Allocator to be deleted is in the middle or at end of the list. Adjust \r
- * adjacent allocator pointers. This covers the case where the allocator to be \r
- * removed is at the end of the list. */\r
+ else {\r
+ /* Allocator in middle or end of list. */\r
prevAllocator->nextAllocator = allocator->nextAllocator;\r
}\r
-\r
- /* Free the memory associated with the allocator. */\r
Rm_osalFree((void *)allocator, sizeof(Rm_Allocator));\r
}\r
+ else {\r
+ retVal = -22; /* TEMP ERROR: Can't conflict with LIBFDT errors */\r
+ }\r
\r
Rm_osalMtCsExit(key);\r
return (retVal);\r
}\r
\r
+void Rm_addAllocatedTo(Rm_ResourceNode *node, void *serviceInstNode)\r
+{\r
+ Rm_AllocatedTo *allocatedToList = node->allocatedTo;\r
+ Rm_AllocatedTo *newAllocatedTo = NULL;\r
+\r
+ newAllocatedTo = Rm_osalMalloc(sizeof(Rm_AllocatedTo));\r
+\r
+ if (newAllocatedTo) {\r
+ newAllocatedTo->instNameNode = serviceInstNode;\r
+ newAllocatedTo->nextAllocatedTo = NULL; \r
+\r
+ /* Add allocatedTo entry to end of list */\r
+ if (allocatedToList) {\r
+ while (allocatedToList->nextAllocatedTo) {\r
+ allocatedToList = allocatedToList->nextAllocatedTo;\r
+ }\r
+ allocatedToList->nextAllocatedTo = newAllocatedTo;\r
+ }\r
+ else {\r
+ node->allocatedTo = newAllocatedTo;\r
+ }\r
+\r
+ node->allocationCount++;\r
+ Rm_policyIncrementValidInstAllocationCount(newAllocatedTo->instNameNode);\r
+ }\r
+}\r
+\r
+bool Rm_isAllocatedTo(Rm_ResourceNode *node, void *serviceInstNode)\r
+{\r
+ Rm_AllocatedTo *allocatedTo = node->allocatedTo;\r
+\r
+ while (allocatedTo) {\r
+ if (allocatedTo->instNameNode == serviceInstNode) {\r
+ return(TRUE); \r
+ }\r
+ allocatedTo = allocatedTo->nextAllocatedTo;\r
+ }\r
+ return(FALSE);\r
+}\r
+\r
+bool Rm_compareResourceNodeAllocations(Rm_ResourceNode *nodeOne, Rm_ResourceNode *nodeTwo)\r
+{\r
+ if (nodeOne->allocationCount == nodeTwo->allocationCount) {\r
+ \r
+ }\r
+ return(FALSE);\r
+}\r
+\r
+void Rm_deleteAllocatedTo(Rm_ResourceNode *node, void *serviceInstNode)\r
+{\r
+ Rm_AllocatedTo *allocatedTo = node->allocatedTo;\r
+ Rm_AllocatedTo *prevAllocatedTo = NULL;\r
+\r
+ while (allocatedTo) {\r
+ if (allocatedTo->instNameNode == serviceInstNode) {\r
+ break; \r
+ }\r
+ prevAllocatedTo = allocatedTo;\r
+ allocatedTo = allocatedTo->nextAllocatedTo;\r
+ }\r
+\r
+ if (prevAllocatedTo == NULL) {\r
+ /* AllocatedTo entry at start of list. Map second allocatedTo entry to start of list \r
+ * as long as more than one allocatedTo entries. */\r
+ node->allocatedTo = allocatedTo->nextAllocatedTo;\r
+ }\r
+ else {\r
+ /* AllocatedTo entry in middle or end of list. */\r
+ prevAllocatedTo->nextAllocatedTo = allocatedTo->nextAllocatedTo;\r
+ }\r
+ \r
+ node->allocationCount--;\r
+ Rm_policyDecrementValidInstAllocationCount(allocatedTo->instNameNode);\r
+ Rm_osalFree((void *)allocatedTo, sizeof(Rm_AllocatedTo));\r
+}\r
+\r
int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_ResourceRange *range)\r
{\r
- Rm_Allocator *allocator = NULL;\r
+ Rm_Allocator *allocator = NULL;\r
Rm_ResourceTree *treeRootEntry = NULL;\r
Rm_ResourceNode *treeNode = NULL;\r
Rm_ResourceNode *collidingNode = NULL;\r
\r
- /* Create the new base integer allocator */\r
allocator = Rm_allocatorAdd(rmInst, resourceName);\r
-\r
- /* Create the tree root entry and initialize it */\r
treeRootEntry = Rm_osalMalloc(sizeof(Rm_ResourceTree));\r
RB_INIT(treeRootEntry);\r
\r
- /* Create a node in the tree for resource range and insert them into the tree. */\r
- while (range != NULL)\r
- {\r
- treeNode = Rm_newResourceNode(range->base, range->length, RM_NOT_ALLOCATED_STRING);\r
-\r
- /* Insert the node into the tree */\r
+ while (range != NULL) {\r
+ treeNode = Rm_newResourceNode(range->base, range->length);\r
collidingNode = RB_INSERT(_Rm_ResourceTree, treeRootEntry, treeNode);\r
\r
- if (collidingNode)\r
- {\r
+ if (collidingNode) {\r
Rm_ResourceNode *nextNode = NULL;\r
\r
- /* Node that was inserted colliding with an existing node. Clean up the tree\r
- * that's been allocated thus far and return an error since there should be no\r
- * collisions */\r
- for (treeNode = RB_MIN(_Rm_ResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode)\r
- {\r
+ /* Node that was inserted collides with existing node. Destroy tree and return error */\r
+ for (treeNode = RB_MIN(_Rm_ResourceTree, treeRootEntry); treeNode != NULL; treeNode = nextNode) {\r
nextNode = RB_NEXT(_Rm_ResourceTree, treeRootEntry, treeNode);\r
RB_REMOVE(_Rm_ResourceTree, treeRootEntry, nextNode);\r
Rm_freeResourceNode(treeNode);\r
}\r
- /* Delete the tree root entry and the allocator */\r
Rm_osalFree((void *)treeRootEntry, sizeof(Rm_ResourceTree));\r
Rm_allocatorDelete(rmInst, allocator->resourceName);\r
return (-24); /* TODO FIX RETURN */\r
}\r
-\r
range = range->nextRange;\r
}\r
-\r
- /* Assign the tree's root to the allocator */\r
+ \r
allocator->allocatorRootEntry = treeRootEntry;\r
-\r
return(0); /* TODO: FIX THIS RETURN */\r
}\r
\r
@@ -480,65 +460,53 @@ int32_t Rm_createTreeAllocator(Rm_Inst *rmInst, const char *resourceName, Rm_Res
* for the rm instance for the specified resource. */\r
int32_t Rm_treePreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
{\r
- Rm_ResourceNode findNode;\r
+ Rm_ResourceNode findNode;\r
Rm_ResourceNode *matchingNode = NULL;\r
- uint32_t matchingEnd;\r
- uint32_t rangeIndex;\r
- bool resourceFound = FALSE;\r
- int32_t retVal = RM_SERVICE_PROCESSING;\r
+ uint32_t matchingEnd;\r
+ uint32_t rangeIndex;\r
+ bool resourceFound = FALSE;\r
+ int32_t retVal = RM_SERVICE_PROCESSING;\r
\r
- /* Initialize the findNode parameters to the starting preallocation parameters */\r
- if (opInfo->resourceInfo->base)\r
- {\r
+ memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
+ if (opInfo->resourceInfo->base) {\r
findNode.base = opInfo->resourceInfo->base;\r
}\r
- else\r
- {\r
- /* Otherwise use the first resource value in the tree */\r
+ else {\r
+ /* Use first resource value in tree */\r
matchingNode = RB_MIN(_Rm_ResourceTree, allocator->allocatorRootEntry);\r
findNode.base = matchingNode->base;\r
}\r
+ /* Length always provided */\r
findNode.length = opInfo->resourceInfo->length;\r
\r
- do\r
- {\r
+ do {\r
matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
\r
- if (matchingNode != NULL)\r
- {\r
- /* Is the matchingNode free? */\r
- if (strcmp(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
+ if (matchingNode != NULL) {\r
+ if (matchingNode->allocationCount == 0)\r
{\r
matchingEnd = matchingNode->base + matchingNode->length - 1;\r
- /* Initialize the indexer to be the first resource base value that \r
- * satisfies the alignment property */\r
+ /* Initialize indexer to be first resource value that alignment */\r
rangeIndex = findNode.base;\r
- if (rangeIndex % opInfo->resourceInfo->alignment)\r
- {\r
+ if (rangeIndex % opInfo->resourceInfo->alignment) {\r
rangeIndex += (opInfo->resourceInfo->alignment -\r
- (rangeIndex % opInfo->resourceInfo->alignment));\r
+ (rangeIndex % opInfo->resourceInfo->alignment));\r
}\r
\r
- /*Is there a block of unallocated resources within the matchingNode\r
- * that satisfies the allocate properties? */\r
- if ((rangeIndex + opInfo->resourceInfo->length - 1) <= matchingEnd)\r
- {\r
+ if ((rangeIndex + opInfo->resourceInfo->length - 1) <= matchingEnd) {\r
+ /* Block of unallocated resources within matchingNode that satisfies\r
+ * allocate requirements */\r
opInfo->resourceInfo->base = rangeIndex;\r
resourceFound = TRUE;\r
}\r
}\r
\r
- if (!resourceFound)\r
- {\r
- /* If the matchingNode does not satisfy allocate requirements update the resource base \r
- * to the first resource value after the end of the current matchingNode */\r
+ if (!resourceFound) {\r
+ /* Check next resource node for available resources */\r
findNode.base = matchingNode->base + matchingNode->length;\r
}\r
}\r
- else\r
- {\r
- /* If not matchingNode has been found the end of the tree has been reached and there\r
- * is not resource range available that meets the needs of the request */\r
+ else {\r
retVal = RM_SERVICE_DENIED_RESOURCE_ALLOCATION_REQUIREMENTS_COULD_NOT_BE_SATISFIED;\r
}\r
} while ((!resourceFound) && \r
@@ -547,494 +515,341 @@ int32_t Rm_treePreAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
return(retVal); \r
}\r
\r
-/* Assume the policy has already approved of the allocation */\r
int32_t Rm_treeAllocate(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
{\r
- Rm_ResourceNode findNode;\r
+ Rm_ResourceNode findNode;\r
Rm_ResourceNode *matchingNode = NULL;\r
Rm_ResourceNode *leftNode = NULL;\r
Rm_ResourceNode *rightNode = NULL; \r
- uint32_t findEnd, matchingEnd;\r
- int32_t retVal;\r
+ uint32_t findEnd;\r
+ uint32_t matchingEnd;\r
+ int32_t retVal;\r
\r
- /* Find the tree node that contains the specified resource range */\r
+ memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
findNode.base = opInfo->resourceInfo->base;\r
findNode.length = opInfo->resourceInfo->length;\r
matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
\r
- if (matchingNode != NULL)\r
- {\r
+ if (matchingNode) {\r
findEnd = findNode.base + findNode.length - 1;\r
matchingEnd = matchingNode->base + matchingNode->length - 1;\r
\r
- /* Does the request range fit within the matching nodes entire range? */\r
- if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd))\r
- {\r
- /* Handle node create, combine, deletion based on the request range if\r
- * resources are available. */\r
- if (strcmp(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
- {\r
- /* Handle case where the findNode range matches the matchingNode\r
- * range exactly.\r
- *\r
- * base0 base0+length0-1\r
- * |<---------------length0------------------->| => existing node\r
- * |<---------------length1------------------->| => requested resources\r
- * base1 base1+length1-1\r
- */ \r
- if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))\r
- {\r
- /* Can reserve matchingNode's resources in-place */\r
- strcpy(matchingNode->allocatedTo, opInfo->serviceSrcInstName);\r
- }\r
- /* Handle case where the findNode range is a subset of the matchingNode\r
- * range and neither of the boundaries of the two ranges are equivalent.\r
- *\r
- * base0 base0+length0-1\r
- * |<---------------length0------------------->| => existing node\r
- * |<---------length1---------->| => requested resources\r
- * base1 base1+length1-1\r
- */ \r
- else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd))\r
- {\r
- /* Split the matching node into three nodes:\r
- * left node - free resources to left of newly allocated resources\r
- * middle node - newly allocated resources that satisfy the request\r
- * right node - free resources to the right of newly allocated resources */\r
-\r
- /* Remove the matching node from the tree for modification. */\r
+ if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {\r
+ if (matchingNode->allocationCount == 0) { \r
+ if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd)) {\r
+ /* findNode range matches the matchingNode range\r
+ *\r
+ * base0 base0+length0-1\r
+ * |<---------------length0------------------->| => existing node\r
+ * |<---------------length1------------------->| => requested resources\r
+ * base1 base1+length1-1\r
+ */ \r
+ Rm_addAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
+ } \r
+ else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {\r
+ /* findNode range is subset of matchingNode range and neither boundary is\r
+ * equivalent.\r
+ *\r
+ * base0 base0+length0-1\r
+ * |<---------------length0------------------->| => existing node\r
+ * |<---------length1---------->| => requested resources\r
+ * base1 base1+length1-1\r
+ */ \r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
+ leftNode = Rm_newResourceNode(matchingNode->base, findNode.base - matchingNode->base);\r
+ rightNode = Rm_newResourceNode(findNode.base + findNode.length, matchingEnd - findEnd);\r
\r
- /* New left node attributes:\r
- * base: base of the matching node\r
- * length: base of requested resources - base of matching node */\r
- leftNode = Rm_newResourceNode(matchingNode->base, findNode.base - matchingNode->base,\r
- RM_NOT_ALLOCATED_STRING);\r
- /* New right node attributes:\r
- * base: base of the requested resources + length of requested resources\r
- * length: right bound of matching node - right bound of request resources */\r
- rightNode = Rm_newResourceNode(findNode.base + findNode.length,\r
- matchingEnd - findEnd, RM_NOT_ALLOCATED_STRING);\r
-\r
- /* Base and length of matching node become the base and length of the\r
- * requested resources */\r
matchingNode->base = findNode.base; \r
matchingNode->length = findNode.length;\r
- /* Reserve the resources */\r
- strcpy(matchingNode->allocatedTo, opInfo->serviceSrcInstName);\r
+ Rm_addAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
\r
/* Insert all the nodes */\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
- }\r
- /* Handle cases where one of findNode range boundaries is equivalent to\r
- * one of the matchingNode range boundaries.\r
- *\r
- * base0 base0+length0-1\r
- * |<---------------length0------------------->| => existing node\r
- * |<---------length1---------->| => requested resources\r
- * base1 base1+length1-1\r
- *\r
- * OR\r
- *\r
- * base0 base0+length0-1\r
- * |<---------------length0------------------->| => existing node\r
- * |<---------length1---------->| => requested resources\r
- * base1 base1+length1-1 \r
- */ \r
- else\r
- { \r
- if (findNode.base == matchingNode->base)\r
- {\r
- /* There may be a combine possibility to the left. Extract leftNode to check */\r
+ } \r
+ else { \r
+ if (findNode.base == matchingNode->base) {\r
+ /* findNode base and matchingNode base are equivalent. May be combine\r
+ * possibilities to the left\r
+ *\r
+ * base0 base0+length0-1\r
+ * |<---------------length0------------------->| => existing node\r
+ * |<---------length1---------->| => requested resources\r
+ * base1 base1+length1-1\r
+ */ \r
leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
- /* Remove the matchingNode from the tree since it will be edited */\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); \r
\r
- /* Can the node to the left of the matchingNode be combined with the \r
- * findNode's range? */\r
- if (leftNode && (strcmp(leftNode->allocatedTo, opInfo->serviceSrcInstName) == 0))\r
- {\r
- /* Remove the leftNode from the tree for editing */\r
+ if (leftNode && (leftNode->allocationCount == 1) && \r
+ (leftNode->allocatedTo->instNameNode == opInfo->serviceSrcInstNode)) {\r
+ \r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-\r
- /* Combine the leftNode and the findNode */\r
+ /* Combine leftNode and findNode */\r
leftNode->length += findNode.length;\r
}\r
- else\r
- {\r
- /* Allocate a new leftNode that will take the place of the findNode\r
- * range in tree. */\r
- leftNode = Rm_newResourceNode(findNode.base, findNode.length,\r
- opInfo->serviceSrcInstName);\r
+ else {\r
+ leftNode = Rm_newResourceNode(findNode.base, findNode.length);\r
+ Rm_addAllocatedTo(leftNode, opInfo->serviceSrcInstNode);\r
}\r
\r
- /* Account for the leftNode in the matchingNode */\r
+ /* Account for leftNode in matchingNode */\r
matchingNode->base = findNode.base + findNode.length;\r
matchingNode->length = matchingEnd - findEnd; \r
\r
- /* Insert the left node */\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
}\r
- else if (findEnd == matchingEnd)\r
- {\r
- /* There may be a combine possibility to the right. Extract rightNode to check */\r
+ else if (findEnd == matchingEnd) {\r
+ /* findNode end and matchingNode end are equivalent. May be combine\r
+ * possibilities to the right\r
+ *\r
+ * base0 base0+length0-1\r
+ * |<---------------length0------------------->| => existing node\r
+ * |<---------length1---------->| => requested resources\r
+ * base1 base1+length1-1 \r
+ */ \r
rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
- /* Remove the matchingNode from the tree since it will be edited */\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
\r
- /* Can the node to the right of the matchingNode be combined with the \r
- * findNode's range? */\r
- if (rightNode && (strcmp(rightNode->allocatedTo, opInfo->serviceSrcInstName) == 0))\r
- {\r
- /* Remove the rightNode from the tree for editing */\r
+ if (rightNode && (rightNode->allocationCount == 1) && \r
+ (rightNode->allocatedTo->instNameNode == opInfo->serviceSrcInstNode)) {\r
+\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
\r
- /* Combine the rightNode and the findNode */\r
+ /* Combine rightNode and findNode */\r
rightNode->base = findNode.base;\r
rightNode->length += findNode.length;\r
}\r
- else\r
- {\r
- /* Allocate a new rightNode that will take the place of the findNode\r
- * range in tree. */\r
- rightNode = Rm_newResourceNode(findNode.base, findNode.length,\r
- opInfo->serviceSrcInstName);\r
+ else {\r
+ rightNode = Rm_newResourceNode(findNode.base, findNode.length);\r
+ Rm_addAllocatedTo(rightNode, opInfo->serviceSrcInstNode);\r
}\r
\r
- /* Account for the rightNode in the matchingNode */\r
+ /* Account for rightNode in matchingNode */\r
matchingNode->length -= findNode.length; \r
\r
- /* Insert the right node */\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
}\r
-\r
- /* Reinsert the edited matching node */\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
}\r
- \r
retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
}\r
- else\r
- {\r
- /* A resource superset containing the requested range has\r
- * already been allocated. */\r
+ else {\r
retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
}\r
}\r
- else\r
- {\r
- /* Request ranges that span multiple nodes signify resources are\r
- * not available because nodes are combined into larger contiguous ranges\r
- * on resource free operations. */\r
+ else {\r
retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_ALLOCATED;\r
}\r
}\r
- else\r
- {\r
- /* The requested resources could not be found in the allocator */\r
+ else {\r
retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
}\r
\r
return(retVal); \r
}\r
\r
-/* Assume policy has already approved of the free */\r
int32_t Rm_treeFree(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)\r
{\r
- Rm_ResourceNode findNode;\r
+ Rm_ResourceNode findNode;\r
Rm_ResourceNode *matchingNode = NULL;\r
Rm_ResourceNode *leftNode = NULL;\r
Rm_ResourceNode *rightNode = NULL;\r
- bool combineLeft = FALSE;\r
- bool combineRight = FALSE;\r
- uint32_t findEnd, matchingEnd;\r
- int32_t retVal;\r
+ bool combineLeft = FALSE;\r
+ bool combineRight = FALSE;\r
+ uint32_t findEnd;\r
+ uint32_t matchingEnd;\r
+ int32_t retVal;\r
\r
- /* Find the tree node that contains the specified resource range */\r
+ memset((void *)&findNode, 0, sizeof(Rm_ResourceNode));\r
findNode.base = opInfo->resourceInfo->base;\r
findNode.length = opInfo->resourceInfo->length;\r
matchingNode = RB_FIND(_Rm_ResourceTree, allocator->allocatorRootEntry, &findNode);\r
\r
- if (matchingNode != NULL)\r
- {\r
+ if (matchingNode) {\r
findEnd = findNode.base + findNode.length - 1;\r
matchingEnd = matchingNode->base + matchingNode->length - 1;\r
\r
- /* Does the free range fit within the matching nodes entire range? It should\r
- * either be the entire range or a subset set of the found range. (the latter\r
- * satisfies the case where an entity allocated a contiguous block of resources\r
- * then attempts to free a contiguous subset of the allocated block. */\r
- if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd))\r
- { \r
- if (strcmp(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING))\r
- {\r
- if (strcmp(matchingNode->allocatedTo, opInfo->serviceSrcInstName) == 0)\r
- {\r
- /* Resources can be freed */\r
-\r
+ if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) { \r
+ if (matchingNode->allocationCount) {\r
+ if (Rm_isAllocatedTo(matchingNode, opInfo->serviceSrcInstNode)) {\r
if ((findNode.base == matchingNode->base) && (findEnd == matchingEnd))\r
{\r
- /* Case 1: free range equals allocated matched node exactly. Attempt to combine \r
- * the range to be freed with the resource nodes to the left and\r
- * right of the free range.\r
+ /* Case 1: Free range equals allocated matched node exactly. Attempt to combine \r
+ * freed node with nodes to left and right.\r
*\r
* |<--left node-->||<---matched node--->||<--right node-->|\r
* |<---free request--->|\r
*/ \r
-\r
leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
- /* Remove the matching node from the tree and the nodes to the left and\r
- * right of the matching node. Removing from tree will not\r
- * wipe any of the base+length data in the node. Can reuse since they won't\r
- * be freed */\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
\r
- /* See if the left or right or both nodes can be combined with the matching\r
- * node that will be freed. */\r
- if (leftNode && (strcmp(leftNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
- {\r
- /* Combine the left node and the matching node */\r
+ if (leftNode && (leftNode->allocationCount == 0)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
combineLeft = TRUE;\r
}\r
- if (rightNode && (strcmp(rightNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
- {\r
- /* Combine the right node and the matching node */\r
+ if (rightNode && (rightNode->allocationCount == 0)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
combineRight = TRUE;\r
}\r
\r
- /* Perform any combines, insert the leftover nodes, and free any memory associated\r
- * with any nodes that weren't reinserted into the tree */\r
- if (combineLeft && combineRight)\r
- {\r
- /* Combine all three nodes into the matchingNode. Insert the freed cumulative\r
- * matching node and delete the memory for the old left and right nodes */\r
+ if (combineLeft && combineRight) {\r
+ /* Combine all three nodes into matchingNode */\r
matchingNode->base = leftNode->base;\r
matchingNode->length = leftNode->length + matchingNode->length + rightNode->length;\r
\r
Rm_freeResourceNode(leftNode);\r
Rm_freeResourceNode(rightNode); \r
}\r
- else if (combineLeft)\r
- {\r
- /* Combine the left and matching nodes. Reinsert the right. */\r
+ else if (combineLeft) {\r
+ /* Combine left and matching nodes. Reinsert right. */\r
matchingNode->base = leftNode->base;\r
matchingNode->length += leftNode->length;\r
\r
Rm_freeResourceNode(leftNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode); \r
}\r
- else if (combineRight)\r
- {\r
- /* Combine the right and matching nodes. Reinsert the left. */\r
+ else if (combineRight) {\r
+ /* Combine right and matching nodes. Reinsert left. */\r
matchingNode->length += rightNode->length;\r
\r
Rm_freeResourceNode(rightNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
}\r
- else\r
- {\r
- /* Combine cannot be performed. Reinsert the left and right nodes then\r
- * free the matching node and reinsert it */\r
+ else {\r
+ /* No combine. */\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
}\r
\r
- /* No matter the combine route taken the matching node will always be declared\r
- * free and reinserted */\r
- strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING);\r
+ /* Always reinsert matchingNode */\r
+ Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); \r
}\r
- else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd))\r
- {\r
- /* Case 2: free range is less than range in matched node. Need to split\r
- * the matched node into three nodes.\r
+ else if ((findNode.base > matchingNode->base) && (findEnd < matchingEnd)) {\r
+ /* Case 2: Free range is less than range in matched node. Split\r
+ * matched node into three nodes.\r
*\r
* |<----------matched node---------->|\r
* |<---free request--->|\r
*/ \r
\r
- /* Remove matching node for editing. */\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
- /* New left node attributes:\r
- * base: base of the matching node\r
- * length: base of requested resources - base of matching node */\r
- leftNode = Rm_newResourceNode(matchingNode->base, findNode.base - matchingNode->base,\r
- matchingNode->allocatedTo); \r
- /* New right node attributes:\r
- * base: base of the requested resources + length of requested resources\r
- * length: right bound of matching node - right bound of request resources */\r
- rightNode = Rm_newResourceNode(findNode.base + findNode.length,\r
- matchingEnd - findEnd, matchingNode->allocatedTo);\r
-\r
- /* Insert the left and right nodes into the tree. */\r
+ \r
+ leftNode = Rm_newResourceNode(matchingNode->base, findNode.base - matchingNode->base);\r
+ Rm_addAllocatedTo(leftNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
+ \r
+ rightNode = Rm_newResourceNode(findNode.base + findNode.length, matchingEnd - findEnd);\r
+ Rm_addAllocatedTo(rightNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
\r
- /* Base and length of matching node become the base and length of the freed resources */\r
matchingNode->base = findNode.base; \r
matchingNode->length = findNode.length;\r
- /* Free the resources and insert them into the tree */\r
- strcpy(matchingNode->allocatedTo, RM_NOT_ALLOCATED_STRING);\r
+ Rm_deleteAllocatedTo(matchingNode, opInfo->serviceSrcInstNode);\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
}\r
- else\r
- { \r
- if (findNode.base == matchingNode->base)\r
- {\r
+ else { \r
+ if (findNode.base == matchingNode->base) {\r
/* Case 3: Free range is on left boundary of matched node. Try to \r
- * combine the free range with the left node if free.\r
+ * combine free range with left node.\r
*\r
* |<---left node (free)--->||<----------matched node---------->|\r
* |<---findNode (free req)--->|\r
*/ \r
- \r
- /* There may be a combine possibility to the left. Extract leftNode to check */\r
+\r
leftNode = RB_PREV(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
- \r
- /* Remove the matchingNode from the tree since it will be edited */\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
\r
- /* Can the node to the left of the matchingNode be combined with the \r
- * findNode's range? */\r
- if (leftNode && (strcmp(leftNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
- {\r
- /* Remove the leftNode from the tree for editing */\r
+ if (leftNode && (leftNode->allocationCount == 0)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
-\r
- /* Combine the leftNode and the findNode */\r
+ /* Combine leftNode and findNode */\r
leftNode->length += findNode.length;\r
}\r
- else\r
- {\r
- /* Allocate a new leftNode that will take the place of the findNode\r
- * range in tree. */\r
- leftNode = Rm_newResourceNode(findNode.base, findNode.length,\r
- RM_NOT_ALLOCATED_STRING);\r
+ else {\r
+ leftNode = Rm_newResourceNode(findNode.base, findNode.length);\r
}\r
\r
- /* Account for the leftNode in the matchingNode */\r
+ /* Remove leftNode range from matchingNode */\r
matchingNode->base = findNode.base + findNode.length;\r
matchingNode->length = matchingEnd - findEnd; \r
\r
- /* Insert the left node */\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, leftNode);\r
}\r
- else if (findEnd == matchingEnd)\r
- {\r
+ else if (findEnd == matchingEnd) {\r
/* Case 4: Free range is on right boundary of matched node. Try to \r
- * combine the free range with the right node if free.\r
+ * combine free range with right node.\r
*\r
* |<----------matched node---------->||<---right node (free)--->|\r
* |<---findNode (free req)--->|\r
*/ \r
\r
- /* There may be a combine possibility to the right. Extract rightNode to check */\r
rightNode = RB_NEXT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
-\r
- /* Remove the matchingNode from the tree since it will be edited */\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode); \r
\r
- /* Can the node to the right of the matchingNode be combined with the \r
- * findNode's range? */\r
- if (rightNode && (strcmp(rightNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0))\r
- {\r
- /* Remove the rightNode from the tree for editing */\r
+ if (rightNode && (rightNode->allocationCount == 0)) {\r
RB_REMOVE(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
-\r
- /* Combine the rightNode and the findNode */\r
+ /* Combine rightNode and findNode */\r
rightNode->base = findNode.base;\r
rightNode->length += findNode.length;\r
}\r
- else\r
- {\r
- /* Allocate a new rightNode that will take the place of the findNode\r
- * range in tree. */\r
- rightNode = Rm_newResourceNode(findNode.base, findNode.length,\r
- RM_NOT_ALLOCATED_STRING);\r
+ else {\r
+ rightNode = Rm_newResourceNode(findNode.base, findNode.length);\r
}\r
\r
- /* Account for the rightNode in the matchingNode */\r
+ /* Remove rightNode range from matchingNode */\r
matchingNode->length -= findNode.length; \r
\r
- /* Insert the right node */\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, rightNode);\r
}\r
\r
- /* Reinsert the edited matching node */\r
RB_INSERT(_Rm_ResourceTree, allocator->allocatorRootEntry, matchingNode);\r
}\r
\r
retVal = RM_SERVICE_APPROVED_AND_COMPLETED;\r
}\r
- else\r
- {\r
- /* The matching allocated range to be freed was allocated to a different instance. */\r
+ else {\r
retVal = RM_SERVICE_DENIED_RESOURCE_NOT_ALLOCATED_TO_INSTANCE_REQUESTING_THE_SERVICE;\r
}\r
}\r
- else\r
- {\r
- /* Resources are already free */\r
+ else {\r
retVal = RM_SERVICE_DENIED_RESOURCE_ALREADY_FREE;\r
}\r
}\r
- else\r
- {\r
- /* Free resource range crosses over node boundaries. This signifies a\r
- * free of both allocated and unallocated resources since nodes are combined\r
- * on allocate and free operations if possible. */\r
+ else {\r
retVal = RM_SERVICE_DENIED_INVALID_RESOURCE_RANGE;\r
}\r
}\r
- else\r
- {\r
- /* The free resources could not be found in the allocator */\r
+ else {\r
retVal = RM_SERVICE_DENIED_RESOURCE_VALUE_RANGE_DOES_NOT_EXIST;\r
}\r
-\r
return(retVal); \r
}\r
\r
int32_t Rm_allocatorOperation(Rm_Inst *rmInst, Rm_AllocatorOpInfo *opInfo)\r
{\r
Rm_Allocator *allocator = NULL;\r
- int32_t retVal;\r
- void *key;\r
+ int32_t retVal;\r
+ void *key;\r
\r
/* Lock access to the RM instance's transaction queue */\r
key = Rm_osalMtCsEnter();\r
\r
- /* Get the specified resource's allocator */\r
allocator = Rm_allocatorFind(rmInst, opInfo->resourceInfo->name);\r
-\r
- if (allocator)\r
- {\r
- /* Call the allocator's function */\r
- if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE)\r
- {\r
+ if (allocator) {\r
+ if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE) {\r
retVal = Rm_treePreAllocate(allocator, opInfo);\r
} \r
- else if (opInfo->operation == Rm_allocatorOp_ALLOCATE)\r
- {\r
+ else if (opInfo->operation == Rm_allocatorOp_ALLOCATE) {\r
retVal = Rm_treeAllocate(allocator, opInfo);\r
}\r
- else if (opInfo->operation == Rm_allocatorOp_FREE)\r
- {\r
+ else if (opInfo->operation == Rm_allocatorOp_FREE) {\r
retVal = Rm_treeFree(allocator, opInfo);\r
} \r
}\r
- else\r
- {\r
- /* Allocator could not be found for resource */\r
+ else {\r
+ /* Resource allocator could not be found */\r
retVal = RM_SERVICE_DENIED_RESOURCE_DOES_NOT_EXIST;\r
}\r
\r
return(retVal);\r
}\r
\r
-void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+void Rm_allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode)\r
{\r
Rm_AllocatorOpInfo opInfo;\r
- Rm_PolicyNodeProperties policyNodeProps;\r
- int32_t retVal = transaction->state;\r
+ int32_t retVal = transaction->state;\r
\r
- /* Initialize the opInfo structure */\r
memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
\r
- if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
- {\r
+ if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {\r
/* TEMP: For now forward all allocations to the RM Server */\r
Rm_transactionForwarder(rmInst, transaction);\r
- \r
-#if 0 /* Policy psuedo-code. Will be implemented after basic allocate functionality is ready and tested */ \r
- if (resourceBase is unspecified)\r
- {\r
- while (policy does not approve)\r
- {\r
- Rm_policy check get allowed base as starting point for prealloc\r
- preallocate resource based on the range and alignment\r
- Rm_policy...check\r
- }\r
- }\r
- else\r
- {\r
- /* Check local policy to see if the request can be satisfied with the\r
- * resources stored locally */\r
- Rm_policy...API()\r
-\r
- if (policy check approves the resource)\r
- {\r
- /* call the allocator to allocate the resource */\r
- if (allocator returns resource)\r
- {\r
- /* Populate the transaction with the allocated resources and the result */\r
- transaction->state = approve reason;\r
- return ...\r
- }\r
- else\r
- {\r
- /* allocator ran out of resources, need to contact Server for more\r
- * resources */\r
- Rm_resourcePoolModRequest(...);\r
- }\r
- }\r
- else if (policy check denies resource)\r
- {\r
- /* Policy check denied resource. */\r
- transaction->state= deny reason;\r
- return ...\r
- }\r
- else if (policy check says forward to Server for validation)\r
- {\r
- /* Forward the transaction to the Server */\r
- Rm_transactionForwarder(rmInst, transaction);\r
- }\r
- }\r
-#endif \r
+ \r
}\r
- else if (rmInst->instType == Rm_instType_SERVER)\r
- {\r
- /* TEMP: If resource properties are unspecified allocate the next available.\r
- * If resource properties are specified allocate if they are available. */\r
-\r
- /* Fill out the allocator operation general information */\r
+ else if (rmInst->instType == Rm_instType_SERVER) {\r
opInfo.resourceInfo = &transaction->resourceInfo;\r
- opInfo.serviceSrcInstName = transaction->serviceSrcInstName;\r
+ opInfo.serviceSrcInstNode = validInstNode;\r
\r
- if (strlen(transaction->resourceInfo.nsName) > 0)\r
- {\r
- /* See if a NameServer name is being used to allocate a resource */\r
- if (transaction->resourceInfo.base != 0)\r
- {\r
- /* A name and a value cannot be specified for the request. It's one\r
- * or the other. */\r
+ if (strlen(transaction->resourceInfo.nsName) > 0) {\r
+ if (transaction->resourceInfo.base != 0) {\r
+ /* Both a name and a value cannot be specified for the request */\r
retVal = RM_SERVICE_ERROR_NAMESERVER_NAME_AND_RESOURCE_RANGE_BOTH_DEFINED;\r
}\r
- else\r
- {\r
- /* Get the resource information from the NameServer */\r
+ else {\r
retVal = Rm_nsFindObject(rmInst, opInfo.resourceInfo);\r
}\r
}\r
\r
- /* Get the policy data for the specified resource and attempt to service the request */\r
- if (retVal == RM_SERVICE_PROCESSING)\r
- {\r
-#if 0 \r
- if((retVal = Rm_policyGetResourceData(rmInst, opInfo.serviceSrcInstName, \r
- opInfo.resourceInfo->name, &policyNodeProps)) == \r
- RM_SERVICE_PROCESSING)\r
- {\r
- if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED)\r
- {\r
- /* Check the alignment against the policy. If the resource alignment is \r
- * unspecified the alignment will be retrieved from the policy. If no alignment\r
- * is specified in the policy it will be set to the global default as specified\r
- * in rm_policyloc.h */\r
- retVal = Rm_policyValidateAlignment(rmInst, opInfo, &policyNodeProps);\r
- \r
- /* TODO: set the resourceInfo->base value to be the base of the resource range\r
- * allowed for the RM instance */\r
- // opInfo.resourceInfo->base = policy_get_instance_base(...);\r
- opInfo.resourceInfo->base = 0;\r
- \r
- /* Execute the allocator pre-allocate operation to get the next available resources.\r
- * NORMALLY CHECKED AGAINST THE POLICY */\r
- opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;\r
- \r
- /* If the pre-allocate operation succeeds the resourceInfo field pointed to\r
- * by opInfo will contain the next available resources that satisfy the\r
- * resource properties */\r
- retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
- }\r
- else\r
- {\r
- /* Validate the resource against the policy if it is fully specifed in the request */\r
- retVal = Rm_policyValidateResource(rmInst, opInfo, &policyNodeProps);\r
- }\r
- \r
- /* Call allocator as long as an error or denial hasn't occurred */\r
- if (retVal == RM_SERVICE_PROCESSING)\r
- {\r
- opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
- retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
+ if (retVal == RM_SERVICE_PROCESSING) { \r
+ if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {\r
+ if ((transaction->resourceInfo.alignment == RM_RESOURCE_ALIGNMENT_UNSPECIFIED) ||\r
+ (transaction->resourceInfo.alignment == 0)) { \r
+ /* TEMP: Default resource alignment of 1 if the resource alignment is not\r
+ * specified */\r
+ opInfo.resourceInfo->alignment = 1;\r
}\r
+ \r
+ /* TODO: set the resourceInfo->base value to be the base of the resource range\r
+ * allowed for the RM instance */\r
+ // opInfo.resourceInfo->base = policy_get_instance_base(...);\r
+ opInfo.resourceInfo->base = 0;\r
+ \r
+ /* Execute the allocator pre-allocate operation to get the next available resources.\r
+ * NORMALLY CHECKED AGAINST THE POLICY */\r
+ opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE;\r
+ \r
+ /* If the pre-allocate operation succeeds the resourceInfo field pointed to\r
+ * by opInfo will contain the next available resources that satisfy the\r
+ * resource properties */\r
+ retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
}\r
-#endif \r
+ \r
+ if (retVal == RM_SERVICE_PROCESSING) {\r
+ opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
+ retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
+ } \r
}\r
\r
transaction->state = retVal;\r
\r
- if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
- {\r
+ if (strcmp(transaction->serviceSrcInstName, rmInst->name)) {\r
/* Source of allocation was not the server instance, provide the transaction\r
* to the transaction responder */\r
Rm_transactionResponder(rmInst, transaction);\r
}\r
- /* Otherwise let the return stack return the transaction to the serviceHandler */ \r
-\r
-#if 0 /* Policy psuedo-code. Will be implemented after basic allocate functionality is ready and tested */ \r
- if (resourceBase is unspecified)\r
- {\r
- while (policy does not approve)\r
- {\r
- Rm_policy check get allowed base as starting point for prealloc\r
- preallocate resource based on the range and alignment\r
- Rm_policy...check\r
- }\r
- }\r
- else\r
- {\r
- /* Check global policy to see if resource can be allocated. return result\r
- * no matter what */\r
- Rm_policy...API()\r
-\r
- if (policy approves)\r
- {\r
- /* call allocator to allocate resource */\r
- }\r
-\r
- transaction->state = approve or deny reason;\r
- transaction->resourceInfo.base = ...;\r
- transaction->resourceInfo.length = ...;\r
-\r
- /* If source instance name does not match the current instance\r
- * name the allocation request came from a Client. The result\r
- * must be sent back to the Client */\r
- if (strcmp(transaction->sourceInstName, rmInst->name))\r
- {\r
- /* Names don't match. Send the transaction back to the Client */\r
- Rm_transactionResponder(rmInst, transaction);\r
- }\r
- else\r
- {\r
- /* Resource allocation request originated locally on the active\r
- * instance. Send the response via the service responder. */ \r
- Rm_serviceResponder(rmInst, transaction); \r
- }\r
- }\r
-#endif \r
+ /* Otherwise let the return stack return the transaction to the serviceHandler */ \r
} \r
}\r
\r
-void Rm_freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
+void Rm_freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction, void *validInstNode)\r
{\r
- Rm_AllocatorOpInfo opInfo;\r
- Rm_PolicyNodeProperties policyNodeProps; \r
- int32_t retVal = transaction->state;\r
+ Rm_AllocatorOpInfo opInfo; \r
+ int32_t retVal = transaction->state;\r
\r
- /* Initialize the opInfo structure */\r
memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
\r
- if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
- {\r
+ if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {\r
/* TEMP: Forward all free requests to the Server */\r
- Rm_transactionForwarder(rmInst, transaction);\r
- \r
-#if 0 /* Policy psuedo-code. Will be implemented after basic allocate functionality is ready and tested */ \r
- /* Check local policy to see if the request can be satisfied with the\r
- * resources stored locally */\r
- Rm_policy...API()\r
-\r
- if (policy check approves the free)\r
- {\r
- /* call the allocator to free the resource */\r
- /* Run a resource pool check to see if the free combined a resource block\r
- * that can be returned to the server */\r
- if (resource block has been combined)\r
- {\r
- /* allocator ran out of resources, need to contact Server for more\r
- * resources */\r
- Rm_resourcePoolModRequest(free pool block to server...);\r
- }\r
- else\r
- {\r
- /* Populate the receipt with the freed resources and the result */\r
- transaction->state = approve reason;\r
- return ...\r
- }\r
- }\r
- else if (policy check denies resource free)\r
- {\r
- /* Policy check denied resource. */\r
- transaction->state = deny reason;\r
- return ...\r
- }\r
- else if (policy check says forward to Server for validation)\r
- {\r
- /* Forward the transaction to the Server */\r
- Rm_transactionForwarder(rmInst, transaction);\r
- }\r
-#endif \r
+ Rm_transactionForwarder(rmInst, transaction); \r
}\r
- else if (rmInst->instType == Rm_instType_SERVER)\r
- {\r
- /* TEMP: Free the resources if resources are allocated to the source instance. */\r
-\r
- /* Fill out the allocator operation general information */\r
+ else if (rmInst->instType == Rm_instType_SERVER) {\r
opInfo.resourceInfo = &transaction->resourceInfo;\r
- opInfo.serviceSrcInstName = transaction->serviceSrcInstName;\r
+ opInfo.serviceSrcInstNode = validInstNode;\r
\r
- if (strlen(transaction->resourceInfo.nsName) > 0)\r
- {\r
- /* See if a NameServer name is being used to allocate a resource */\r
- if (transaction->resourceInfo.base != 0)\r
- {\r
- /* A name and a value cannot be specified for the request. It's one\r
- * or the other. */\r
+ if (strlen(transaction->resourceInfo.nsName) > 0) {\r
+ if (transaction->resourceInfo.base != 0) {\r
+ /* Both a name and a value cannot be specified for the request */\r
retVal = RM_SERVICE_ERROR_NAMESERVER_NAME_AND_RESOURCE_RANGE_BOTH_DEFINED;\r
}\r
- else\r
- {\r
- /* Get the resource information from the NameServer */\r
+ else {\r
retVal = Rm_nsFindObject(rmInst, opInfo.resourceInfo);\r
}\r
}\r
-#if 0 \r
- if((retVal = Rm_policyGetResourceData(rmInst, opInfo.serviceSrcInstName, \r
- opInfo.resourceInfo->name, &policyNodeProps)) == \r
- RM_SERVICE_PROCESSING)\r
- {\r
- /* Validate the resource against the policy if it is fully specifed in the request */\r
- if((retVal = Rm_policyValidateResource(rmInst, opInfo, &policyNodeProps) ==\r
- RM_SERVICE_PROCESSING)\r
- { \r
- /* Call allocator as long as an error or denial hasn't occurred */\r
- opInfo.operation = Rm_allocatorOp_FREE;\r
- retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
- }\r
- }\r
-#endif \r
+ \r
+ if(retVal == RM_SERVICE_PROCESSING) { \r
+ opInfo.operation = Rm_allocatorOp_FREE;\r
+ retVal = Rm_allocatorOperation(rmInst, &opInfo);\r
+ } \r
\r
transaction->state = retVal;\r
\r
- if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
- {\r
+ if (strcmp(transaction->serviceSrcInstName, rmInst->name)) {\r
/* Source of allocation was not the server instance, provide the transaction\r
* to the transaction responder */\r
Rm_transactionResponder(rmInst, transaction);\r
}\r
- /* Otherwise let the return stack return the transaction to the serviceHandler */ \r
- \r
-#if 0 /* Policy psuedo-code. Will be implemented after basic allocate functionality is ready and tested */ \r
- /* Check global policy to see if resource can be freed. return result\r
- * no matter what */\r
- Rm_policy...API()\r
- if (policy approves)\r
- {\r
- /* call allocator to free resources */\r
- }\r
- \r
- transaction->state = approve or deny reason;\r
- transaction->resourceInfo.base = ...;\r
- transaction->resourceInfo.length = ...;\r
-\r
- /* If source instance name does not match the current instance\r
- * name the allocation request came from a client. The result\r
- * must be sent back to the Client */\r
- if (strcmp(transaction->sourceInstName, rmInst->name))\r
- {\r
- /* Names don't match. Send the transaction back to the Client Delegate or Client */\r
- Rm_transactionResponder(rmInst, transaction);\r
- }\r
- else\r
- {\r
- /* Resource allocation request originated locally on the active\r
- * instance. Send the response via the service responder. */\r
- Rm_serviceResponder(rmInst, transaction); \r
- }\r
-#endif \r
+ /* Otherwise let the return stack return the transaction to the serviceHandler */ \r
} \r
}\r
\r
dstTransportNode = Rm_transportNodeFindRemoteName(rmInst, transaction->pktSrcInstName);\r
\r
/* Create a RM packet using the service information */\r
- switch (transaction->type)\r
- {\r
- case Rm_service_RESOURCE_ALLOCATE:\r
+ switch (transaction->type) {\r
+ case Rm_service_RESOURCE_ALLOCATE_INIT:\r
+ case Rm_service_RESOURCE_ALLOCATE_USE:\r
case Rm_service_RESOURCE_FREE:\r
case Rm_service_RESOURCE_GET_BY_NAME:\r
rmPkt = Rm_transportCreateResourceResponsePkt(rmInst, dstTransportNode, \r
break;\r
}\r
\r
- if (transaction->state <= RM_SERVICE_ERROR_BASE)\r
- {\r
+ if (transaction->state <= RM_SERVICE_ERROR_BASE) {\r
/* Delete the transaction and return immediately because an error occurred \r
* allocating the packet */\r
Rm_transactionQueueDelete(rmInst, transaction->localId);\r
}\r
\r
/* Send the RM packet to the application transport */\r
- if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt) < RM_TRANSPORT_SUCCESSFUL)\r
- {\r
+ if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt) < RM_TRANSPORT_SUCCESSFUL) {\r
/* Negative value returned by transport send. An error occurred\r
* in the transport while attempting to send the packet.*/\r
transaction->state = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
/* Clean up the packet */\r
- if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
- {\r
+ if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt)) {\r
/* Non-NULL value returned by transport packet free. Flag the\r
* error */\r
transaction->state = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
Rm_Packet *rmPkt = NULL;\r
\r
/* Make sure the RM instance has a transport registered with a higher level agent */\r
- if (rmInst->registeredWithDelegateOrServer == false)\r
- {\r
+ if (rmInst->registeredWithDelegateOrServer == false) {\r
transaction->state = RM_SERVICE_ERROR_NOT_REGISTERED_WITH_DEL_OR_SERVER;\r
return;\r
}\r
/* Find the transport for the higher level agent. Check for a connection to a Client Delegate\r
* or a Server. Clients will be connected to either a Client Delegate or a Server. Client\r
* Delegates will be connected to a Server. */\r
- if (rmInst->instType == Rm_instType_CLIENT)\r
- {\r
+ if (rmInst->instType == Rm_instType_CLIENT) {\r
dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_CLIENT_DELEGATE);\r
\r
- if (!dstTransportNode)\r
- {\r
+ if (!dstTransportNode) {\r
/* No Client Delegate connection found. Check for a Server connection */\r
dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_SERVER);\r
}\r
} \r
- else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE)\r
- {\r
+ else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {\r
dstTransportNode = Rm_transportNodeFindRemoteInstType(rmInst, Rm_instType_SERVER);\r
}\r
\r
/* Create a RM packet using the service information */\r
- switch (transaction->type)\r
- {\r
- case Rm_service_RESOURCE_ALLOCATE:\r
+ switch (transaction->type) {\r
+ case Rm_service_RESOURCE_ALLOCATE_INIT:\r
+ case Rm_service_RESOURCE_ALLOCATE_USE:\r
case Rm_service_RESOURCE_FREE:\r
case Rm_service_RESOURCE_GET_BY_NAME:\r
rmPkt = Rm_transportCreateResourceReqPkt(rmInst, dstTransportNode, \r
break;\r
}\r
\r
- if (transaction->state <= RM_SERVICE_ERROR_BASE)\r
- {\r
+ if (transaction->state <= RM_SERVICE_ERROR_BASE) {\r
/* Return immediately because an error occurred allocating the packet */\r
return;\r
}\r
\r
/* Send the RM packet to the application transport */\r
- if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt) < RM_TRANSPORT_SUCCESSFUL)\r
- {\r
+ if (rmInst->transport.rmSend((Rm_TransportHandle) dstTransportNode, rmPkt) < RM_TRANSPORT_SUCCESSFUL) {\r
/* Negative value returned by transport send. An error occurred\r
* in the transport while attempting to send the packet.*/\r
transaction->state = RM_SERVICE_ERROR_TRANPSPORT_SEND_ERROR;\r
/* Clean up the packet */\r
- if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt))\r
- {\r
+ if (rmInst->transport.rmFreePkt((Rm_TransportHandle) dstTransportNode, rmPkt)) {\r
/* Non-NULL value returned by transport packet free. Flag the\r
* error */\r
transaction->state = RM_SERVICE_ERROR_TRANSPORT_FREE_PKT_ERROR;\r
\r
void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)\r
{\r
+ void *validInstNode;\r
+ \r
/* Handle auto-forwarded transactions. These transactions include:\r
* - All request transactions received on Clients are forwarded to the Client Delegate\r
* - NameServer requests received on the Client Delegate are forwarded to the Server */\r
@@ -1504,116 +1104,86 @@ void Rm_transactionProcessor (Rm_Inst *rmInst, Rm_Transaction *transaction)
((rmInst->instType == Rm_instType_CLIENT_DELEGATE) &&\r
((transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) ||\r
(transaction->type == Rm_service_RESOURCE_GET_BY_NAME) ||\r
- (transaction->type == Rm_service_RESOURCE_UNMAP_NAME))))\r
- { \r
- /* Check if the transaction is a transaction that received a response to its\r
- * request. */\r
- if (transaction->state != RM_SERVICE_PROCESSING)\r
- {\r
-\r
- /* A transaction has received a response. Send the response to either the \r
- * transaction or service responder based on the source instance */\r
- if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
- {\r
- /* Transaction originated from another instance. Use the \r
- * transaction responder to send the result to the source instance. This\r
- * is not possible on RM Clients since they can't forward RM services */\r
+ (transaction->type == Rm_service_RESOURCE_UNMAP_NAME)))) {\r
+ \r
+ if (transaction->state != RM_SERVICE_PROCESSING) {\r
+ if (strcmp(transaction->serviceSrcInstName, rmInst->name)) {\r
+ /* Transaction did not originate on this instance */\r
Rm_transactionResponder(rmInst, transaction);\r
}\r
- else\r
- {\r
- /* Transaction originated on this instance. Send to the\r
- * service responder */\r
+ else {\r
+ /* Transaction originated on this instance */\r
Rm_serviceResponder(rmInst, transaction);\r
}\r
}\r
- else\r
- {\r
- /* This is a new transaction that must be forwarded to a higher level RM instance. */\r
+ else {\r
+ /* Forward new transaction */\r
Rm_transactionForwarder(rmInst, transaction);\r
}\r
}\r
- else\r
- {\r
- /* Client Delegate and Server transaction processors. */\r
- switch (transaction->type)\r
- {\r
- case Rm_service_RESOURCE_ALLOCATE:\r
+ else {\r
+ /* Validate service's originating instance name */\r
+ if (rmInst->instType == Rm_instType_SERVER) {\r
+ validInstNode = Rm_policyGetValidInstNode(rmInst->validInstances, transaction->serviceSrcInstName);\r
+ if (validInstNode == NULL) {\r
+ transaction->state = RM_SERVICE_DENIED_ORIGINATING_INSTANCE_NAME_NOT_VALID;\r
+\r
+ /* Send result via responder if transaction did not originate from this instance */\r
+ if (strcmp(transaction->serviceSrcInstName, rmInst->name)) {\r
+ Rm_transactionResponder(rmInst, transaction);\r
+ }\r
+ }\r
+ }\r
+\r
+ switch (transaction->type) {\r
+ case Rm_service_RESOURCE_ALLOCATE_INIT:\r
+ case Rm_service_RESOURCE_ALLOCATE_USE:\r
case Rm_service_RESOURCE_FREE: \r
- /* Check if the transaction is fulfilled request */\r
- if (transaction->state != RM_SERVICE_PROCESSING)\r
- {\r
- /* If source instance name does not match the current instance\r
- * name the allocation request came from a client. The result\r
- * must be sent back to the Client */\r
- if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
- {\r
+ if (transaction->state != RM_SERVICE_PROCESSING) {\r
+ /* Transaction complete */\r
+ if (strcmp(transaction->serviceSrcInstName, rmInst->name)) {\r
+ /* Transaction result not destined for this instance */\r
Rm_transactionResponder(rmInst, transaction);\r
}\r
- else\r
- {\r
- /* Resource allocation request originated locally. Send the response\r
- * via the service responder. */\r
+ else {\r
+ /* Transaction result destined for this instance */\r
Rm_serviceResponder(rmInst, transaction); \r
}\r
}\r
- else\r
- {\r
- /* This is a new transaction request originating from an RM instance with fewer\r
- * allocate/free privileges. Run the allocation or free handler to see if the resource\r
- * request can be handled locally or if it needs to be forwarded to a higher level\r
- * agent */\r
- if (transaction->type == Rm_service_RESOURCE_ALLOCATE)\r
- {\r
- Rm_allocationHandler(rmInst, transaction);\r
+ else {\r
+ /* Try to complete the allocation/free request */\r
+ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||\r
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {\r
+ Rm_allocationHandler(rmInst, transaction, validInstNode);\r
}\r
- else\r
- {\r
- Rm_freeHandler(rmInst, transaction);\r
+ else {\r
+ Rm_freeHandler(rmInst, transaction, validInstNode);\r
}\r
}\r
break;\r
case Rm_service_RESOURCE_MAP_TO_NAME:\r
case Rm_service_RESOURCE_GET_BY_NAME:\r
case Rm_service_RESOURCE_UNMAP_NAME: \r
- /* Server is the only RM instance capable of adding NameServer objects */\r
- if (rmInst->instType == Rm_instType_SERVER)\r
- {\r
- if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME)\r
- {\r
- /* Create a new NameServer object with the request transaction information.\r
- * Transaction will contain the state result of the NameServer addition. */\r
+ /* NameServer resides on server */\r
+ if (rmInst->instType == Rm_instType_SERVER) {\r
+ if (transaction->type == Rm_service_RESOURCE_MAP_TO_NAME) {\r
transaction->state = Rm_nsAddObject(rmInst, &transaction->resourceInfo);\r
}\r
- else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME)\r
- {\r
- /* Find the object tied to the specified name in the NameServer */\r
- if (Rm_nsFindObject(rmInst, &transaction->resourceInfo) == RM_SERVICE_PROCESSING)\r
- {\r
- /* NameServer found the object if it returned "PROCESSING". Map this to\r
- * approved and completed for the transaction state information */\r
+ else if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {\r
+ if (Rm_nsFindObject(rmInst, &transaction->resourceInfo) == RM_SERVICE_PROCESSING) {\r
transaction->state = RM_SERVICE_APPROVED_AND_COMPLETED;\r
}\r
}\r
- else\r
- {\r
- /* Delete an existing NameServer object with the request transaction information\r
- * Transaction will contain the state result of the NameServer addition. */\r
+ else if (transaction->type == Rm_service_RESOURCE_UNMAP_NAME) {\r
transaction->state = Rm_nsDeleteObject(rmInst, &transaction->resourceInfo);\r
}\r
\r
- /* If source instance name does not match the local instance\r
- * name the NameServer request came from a Client or Client Delegate. The \r
- * result must be sent back to the Client or Client Delegate. Just return if it does\r
- * match since the NameServer transaction result can be returned immediately by the\r
- * Rm_serviceHandler. */\r
- if (strcmp(transaction->serviceSrcInstName, rmInst->name))\r
- {\r
+ /* Send result via responder if transaction did not originate from this instance */\r
+ if (strcmp(transaction->serviceSrcInstName, rmInst->name)) {\r
Rm_transactionResponder(rmInst, transaction);\r
}\r
}\r
- else\r
- {\r
+ else {\r
transaction->state = RM_SERVICE_ERROR_NAMESERVER_OBJECT_MOD_ON_INVALID_INSTANCE;\r
}\r
break;\r
int32_t Rm_reserveLinuxResource(Rm_Inst *rmInst, Rm_LinuxAlias *linuxAlias, \r
Rm_LinuxValueRange *linuxValues, Rm_AllocatorOpInfo *opInfo)\r
{\r
- int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
- bool baseFound = FALSE;\r
- bool lengthFound = FALSE;\r
+ int32_t retVal = RM_DTB_UTIL_RESULT_OKAY;\r
+ bool baseFound = FALSE;\r
+ bool lengthFound = FALSE;\r
uint32_t valueIndex = 0;\r
\r
- while ((linuxValues != NULL) && (!baseFound || !lengthFound))\r
- {\r
- if (linuxAlias->baseOffset == valueIndex)\r
- {\r
- /* Found the resource base. Store it in the operation info structure */\r
+ while ((linuxValues != NULL) && (!baseFound || !lengthFound)) {\r
+ if (linuxAlias->baseOffset == valueIndex) {\r
opInfo->resourceInfo->base = linuxValues->value;\r
baseFound = TRUE;\r
\r
- /* length will always be 1 if there is no length specified in the Linux DTB */\r
- if (linuxAlias->lengthOffset == RM_DTB_LINUX_ALIAS_OFFSET_NOT_SET)\r
- {\r
+ if (linuxAlias->lengthOffset == RM_DTB_LINUX_ALIAS_OFFSET_NOT_SET) {\r
opInfo->resourceInfo->length = 1;\r
lengthFound = TRUE;\r
}\r
}\r
- else if (linuxAlias->lengthOffset == valueIndex)\r
- {\r
- /* Found the resource length. Store it in the operation info structure */\r
+ else if (linuxAlias->lengthOffset == valueIndex) {\r
opInfo->resourceInfo->length = linuxValues->value;\r
lengthFound = TRUE;\r
}\r
valueIndex++;\r
}\r
\r
- if (!baseFound || !lengthFound)\r
- {\r
+ if (!baseFound || !lengthFound) {\r
retVal = -33; /* TODO: ERROR BASE OR LENGTH OFFSET IN LINUX DTB WAS INCORRECT */\r
}\r
- else\r
- {\r
- /* Allocate the resource to Linux */\r
+ else {\r
+ /* Allocate resource to Linux */\r
retVal = Rm_allocatorOperation(rmInst, opInfo);\r
}\r
-\r
return (retVal);\r
}\r
\r
int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName, void *linuxDtb, \r
Rm_LinuxAlias *linuxAlias)\r
{\r
- Rm_AllocatorOpInfo opInfo;\r
- Rm_ResourceInfo resourceInfo;\r
- uint32_t pathOffset;\r
- uint32_t pathSize;\r
- char *spacePtr;\r
- int32_t propOffset;\r
- int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
- int32_t prevDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
- int32_t depth;\r
- int32_t propertyLen;\r
- const char *propertyName;\r
- const void *propertyData; \r
+ Rm_AllocatorOpInfo opInfo;\r
+ Rm_ResourceInfo resourceInfo;\r
+ uint32_t pathOffset;\r
+ uint32_t pathSize;\r
+ char *spacePtr;\r
+ int32_t propOffset;\r
+ int32_t nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
+ int32_t prevDepth = RM_DTB_UTIL_STARTING_DEPTH;\r
+ int32_t depth;\r
+ int32_t propertyLen;\r
+ const char *propertyName;\r
+ const void *propertyData; \r
Rm_LinuxValueRange *linuxValueRange;\r
- int32_t retVal = RM_DTB_UTIL_RESULT_OKAY; \r
+ int32_t retVal = RM_DTB_UTIL_RESULT_OKAY; \r
\r
- /* Initialize the allocator opInfo and resourceInfo structures that will be used to \r
- * reserve the resources taken by the Linux kernel */\r
memset((void *) &opInfo, 0, sizeof(Rm_AllocatorOpInfo));\r
memset((void *) &resourceInfo, 0, sizeof(Rm_ResourceInfo));\r
\r
strcpy(resourceInfo.name, resourceName);\r
-\r
- /* Set the source instance name for allocation to be the Linux Kernel */\r
- opInfo.serviceSrcInstName = RM_ALLOCATED_TO_LINUX;\r
+ opInfo.serviceSrcInstNode = Rm_policyGetLinuxInstNode(rmInst->validInstances);\r
opInfo.operation = Rm_allocatorOp_ALLOCATE;\r
opInfo.resourceInfo = &resourceInfo; \r
\r
- /* Find each resource specified in the Linux resource alias list and reserve that \r
- * resource as used */\r
- while(linuxAlias != NULL)\r
- {\r
- /* Reset the parsing variables */\r
+ while(linuxAlias != NULL) {\r
+ /* Reset parsing variables */\r
pathOffset = 0;\r
pathSize = strlen(linuxAlias->path) + 1;\r
nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;\r
@@ -1711,84 +1264,60 @@ int32_t Rm_findAndReserveLinuxResource(Rm_Inst *rmInst, const char *resourceName
resourceInfo.length = 0;\r
\r
spacePtr = strpbrk(linuxAlias->path, " ");\r
- if (spacePtr)\r
- {\r
+ if (spacePtr) {\r
*spacePtr = '\0';\r
} \r
\r
- while(pathOffset < pathSize)\r
- {\r
- /* Move through the DTB nodes until the next alias path node is found */\r
- if (strcmp(linuxAlias->path + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL)))\r
- {\r
+ while(pathOffset < pathSize) {\r
+ /* Move through DTB nodes until next alias path node found */\r
+ if (strcmp(linuxAlias->path + pathOffset, fdt_get_name(linuxDtb, nodeOffset, NULL))) {\r
nodeOffset = fdt_next_node(linuxDtb, nodeOffset, &depth);\r
\r
- if ((depth < prevDepth) || (nodeOffset == -FDT_ERR_NOTFOUND))\r
- {\r
+ if ((depth < prevDepth) || (nodeOffset == -FDT_ERR_NOTFOUND)) {\r
/* Returning from subnode that matched part of alias path without finding\r
- * the resource values */\r
+ * resource values */\r
retVal = (-31); /* TODO: COULD NOT FIND RESOURCE AT ALIAS PATH */\r
break;\r
}\r
}\r
- else\r
- {\r
- /* Found the next alias path node. Move to the next node name in the path\r
- * string. */\r
+ else {\r
+ /* Found next alias path node. Move to next node name in path string. */\r
pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);\r
spacePtr = strpbrk(linuxAlias->path + pathOffset, " ");\r
- if (spacePtr)\r
- {\r
+ if (spacePtr) {\r
*spacePtr = '\0';\r
} \r
\r
prevDepth = fdt_node_depth(linuxDtb, nodeOffset);\r
-\r
- /* Check the properties of the node to see if they match the next alias\r
- * path string */\r
propOffset = fdt_first_property_offset(linuxDtb, nodeOffset);\r
- \r
- /* Search the properties for the next alias path string */\r
while ((propOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&\r
- (pathOffset < pathSize))\r
- {\r
+ (pathOffset < pathSize)) {\r
propertyData = fdt_getprop_by_offset(linuxDtb, propOffset, \r
&propertyName, &propertyLen);\r
\r
- if (strcmp(linuxAlias->path + pathOffset, propertyName) == 0)\r
- {\r
+ if (strcmp(linuxAlias->path + pathOffset, propertyName) == 0) {\r
+ /* Found resource at end of alias path */\r
pathOffset += (strlen(linuxAlias->path + pathOffset) + 1);\r
- /* Found the alias property. Extract the values that will\r
- * contain the resource information that must be reserved. */\r
linuxValueRange = Rm_linuxExtractValues(propertyData, propertyLen);\r
- /* Use the values to reserve resources for the Linux kernel */\r
retVal = Rm_reserveLinuxResource(rmInst, linuxAlias, \r
linuxValueRange, &opInfo);\r
- \r
- /* Free the memory used to store the values */\r
Rm_linuxFreeValues(linuxValueRange);\r
}\r
- \r
propOffset = fdt_next_property_offset(linuxDtb, propOffset);\r
} \r
\r
- if (propOffset < -FDT_ERR_NOTFOUND)\r
- {\r
- /* Error was returned by LIBFDT when parsing the properties */\r
+ if (propOffset < -FDT_ERR_NOTFOUND) {\r
retVal = propOffset;\r
break;\r
}\r
}\r
}\r
\r
- if (retVal < RM_DTB_UTIL_RESULT_OKAY)\r
- {\r
- /* Error occurred during parsing of Linux DTB. Return the error */\r
+ if (retVal < RM_DTB_UTIL_RESULT_OKAY) {\r
break;\r
}\r
linuxAlias = (Rm_LinuxAlias *) linuxAlias->nextLinuxAlias;\r
}\r
-\r
return (retVal);\r
}\r
\r
@@ -2024,42 +1553,28 @@ int32_t Rm_initializeAllocators(Rm_Inst *rmInst, void *globalResourceDtb, void *
/* Server Only */\r
void Rm_printResourceStatus(Rm_Handle *rmHandle)\r
{\r
- Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
- Rm_Allocator *allocator = rmInst->allocators;\r
+ Rm_Inst *rmInst = (Rm_Inst *) rmHandle;\r
+ Rm_Allocator *allocator = rmInst->allocators;\r
Rm_ResourceTree *treeRoot;\r
Rm_ResourceNode *treeNode;\r
- uint32_t numLinuxResources;\r
-\r
- while (allocator != NULL)\r
- {\r
- numLinuxResources = 0;\r
\r
+ while (allocator != NULL) {\r
Rm_osalLog("Resource: %s\n", allocator->resourceName);\r
\r
treeRoot = allocator->allocatorRootEntry;\r
\r
- RB_FOREACH(treeNode, _Rm_ResourceTree, treeRoot)\r
- { \r
+ RB_FOREACH(treeNode, _Rm_ResourceTree, treeRoot) { \r
Rm_osalLog(" %10d - %10d ", treeNode->base, \r
treeNode->base + treeNode->length -1);\r
\r
- if (strcmp(treeNode->allocatedTo, RM_NOT_ALLOCATED_STRING) == 0)\r
- {\r
+ if (treeNode->allocationCount == 0) {\r
Rm_osalLog("NOT ALLOCATED\n");\r
}\r
- else\r
- {\r
- Rm_osalLog("allocated to %s\n", treeNode->allocatedTo);\r
- }\r
-\r
- if (strcmp(treeNode->allocatedTo, RM_ALLOCATED_TO_LINUX) == 0)\r
- {\r
- numLinuxResources += treeNode->length;\r
+ else {\r
+ Rm_osalLog("allocated to %s\n", \r
+ Rm_policyGetValidInstNodeName(treeNode->allocatedTo->instNameNode));\r
}\r
- }\r
- \r
- Rm_osalLog("Total allocated to Linux: %d\n", numLinuxResources);\r
- \r
+ } \r
allocator = allocator->nextAllocator;\r
}\r
\r
Rm_Handle Rm_init(Rm_InitCfg *initCfg, int32_t *result)\r
{\r
Rm_Inst *rmInst;\r
- void *globalResourceDtb = NULL;\r
- void *linuxResourceDtb = NULL;\r
+ void *globalResourceDtb = NULL;\r
+ void *linuxResourceDtb = NULL;\r
+ void *policyDtb = NULL;\r
\r
*result = RM_INIT_OK;\r
-\r
- /* Instance creation checks. Add one to strlen calculation for null character */\r
- if ((strlen(initCfg->instName) + 1) > RM_INSTANCE_NAME_MAX_CHARS)\r
- {\r
- /* Failure: Instance name is too big */\r
+ \r
+ if ((strlen(initCfg->instName) + 1) > RM_INSTANCE_NAME_MAX_CHARS) {\r
*result = RM_INIT_ERROR_INSTANCE_NAME_TOO_BIG;\r
return (NULL);\r
}\r
- \r
- /* Get memory for RM instance from local memory */\r
+\r
+ /* Create and initialize instance */\r
rmInst = Rm_osalMalloc (sizeof(Rm_Inst));\r
memset ((void *) rmInst, 0, sizeof(Rm_Inst));\r
- /* Populate instance based on input parameters */\r
strcpy (&rmInst->name[0], initCfg->instName);\r
rmInst->instType = initCfg->instType;\r
rmInst->registeredWithDelegateOrServer = false;\r
-\r
- /* Initialize the transport routing map linked list pointer to NULL. The linked list\r
- * nodes will be created when the application registers transports */\r
rmInst->routeMap = NULL;\r
-\r
- /* Initialize the allocators linked list pointer to NULL. The linked list nodes will\r
- * be created on the Server instance when the application reads in the resource list.\r
- * Nodes will also be created on Client Delegates when blocks of resources are requested\r
- * for allocation to clients. */\r
rmInst->allocators = NULL;\r
-\r
- /* Initialize the NameServer pointer to NULL. The NameServer should only be located\r
- * on the RM Server */\r
rmInst->nameServer = NULL;\r
-\r
- /* Initialize the pointer to the policy */\r
rmInst->policy = NULL;\r
-\r
- /* Initialize the transaction queue elements. */\r
+ rmInst->validInstances = NULL;\r
rmInst->transactionSeqNum = Rm_transactionInitSequenceNum();\r
rmInst->transactionQueue= NULL;\r
\r
+ if ((rmInst->instType != Rm_instType_CLIENT) && initCfg->policy) {\r
+ policyDtb = initCfg->policy;\r
+ fdt_open_into(policyDtb, policyDtb, fdt_totalsize(policyDtb)); \r
+\r
+ /* Create valid instance list from policy. Must be done prior to parsing\r
+ * GRL so that Linux resources can be reserved correctly */\r
+ rmInst->validInstances = Rm_policyCreateValidInstTree(policyDtb, result);\r
+ }\r
+\r
/* RM Server specific actions */\r
- if (rmInst->instType == Rm_instType_SERVER)\r
- {\r
- /* Initialize the NameServer */\r
+ if (rmInst->instType == Rm_instType_SERVER) {\r
Rm_nsInit(rmInst);\r
- \r
- /* Open the ResourceList file and provide it to the resource initializer. The Linux\r
- * DTB will be parsed simultaneously for resource's consumed by the kernel. The resources\r
- * used by the kernel will be marked as used in the resource allocators. */\r
- if (initCfg->globalResourceList)\r
- {\r
+\r
+ if (initCfg->globalResourceList) {\r
globalResourceDtb = initCfg->globalResourceList;\r
fdt_open_into(globalResourceDtb, globalResourceDtb, fdt_totalsize(globalResourceDtb));\r
\r
- if (initCfg->linuxDtb)\r
- {\r
+ if (initCfg->linuxDtb) {\r
linuxResourceDtb = initCfg->linuxDtb;\r
fdt_open_into(linuxResourceDtb, linuxResourceDtb, fdt_totalsize(linuxResourceDtb)); \r
}\r
- \r
Rm_initializeAllocators(rmInst, globalResourceDtb, linuxResourceDtb);\r
}\r
}\r
\r
- /* Open the instance's policy and store it. Instance policies are only used for Servers and \r
- * Client Delegates */\r
- if ((rmInst->instType != Rm_instType_CLIENT) && initCfg->policy)\r
- {\r
- if ((*result = Rm_policyInit(rmInst, initCfg->policy)) != RM_INIT_OK)\r
- {\r
- return(NULL);\r
- }\r
- }\r
+ if ((rmInst->instType != Rm_instType_CLIENT) && initCfg->policy) {\r
+ *result = Rm_policyValidatePolicy(rmInst, policyDtb);\r
+ } \r
\r
- /* Return the RM Handle */\r
return ((Rm_Handle) rmInst);\r
}\r
\r
diff --git a/src/rm_nameserver.c b/src/rm_nameserver.c
index a5c47cbffd3257c08c577ac7f0fe167af6cff915..10b5abeb52b6e119423132b7df85d2bc9ad0aa32 100644 (file)
--- a/src/rm_nameserver.c
+++ b/src/rm_nameserver.c
int32_t Rm_nsFindObject(Rm_Inst *rmInst, Rm_ResourceInfo *resourceInfo)
{
- Rm_NameServerNode findNode;
+ Rm_NameServerNode findNode;
Rm_NameServerNode *matchingNode = NULL;
- int32_t retVal = RM_SERVICE_PROCESSING;
-
+ int32_t retVal = RM_SERVICE_PROCESSING;
- /* Copy the name to find into the find node structure */
+ memset((void *)&findNode, 0, sizeof(Rm_NameServerNode));
strcpy(findNode.name, resourceInfo->nsName);
matchingNode = RB_FIND(_Rm_NameServerTree, rmInst->nameServer, &findNode);
- if (matchingNode)
- {
+ if (matchingNode) {
/* Copy the name's resource information */
strcpy(resourceInfo->name, matchingNode->resourceName);
resourceInfo->base = matchingNode->base;
resourceInfo->length = matchingNode->length;
}
- else
- {
+ else {
retVal = RM_SERVICE_ERROR_NAMESERVER_ERROR_NAME_DOES_NOT_EXIST;
}
diff --git a/src/rm_policy.c b/src/rm_policy.c
index f741468a790a287ea4a515abbc289e2ba196fd14..e870a5fab9eb9f57e52f5b61d81b582162b737e6 100644 (file)
--- a/src/rm_policy.c
+++ b/src/rm_policy.c
/* RM LIBFDT includes */
#include <ti/drv/rm/src/libfdt/libfdt.h>
+/* AVL BBST includes */
+#include <ti/drv/rm/include/tree.h>
+
/* RM OSAL layer */
#include <rm_osal.h>
+/**********************************************************************
+ ************************** Globals ***********************************
+ **********************************************************************/
+
char Rm_policyAllInstances[] = "*";
-int32_t Rm_policyCheckInstances(Rm_PolicyValidInst *validInstList,
+/**********************************************************************
+ ************ Red-Black BBST Tree Valid Instance Functions ************
+ **********************************************************************/
+Rm_ValidInstNode *Rm_newValidInstNode(char *instName)
+{
+ Rm_ValidInstNode *newNode = NULL;
+
+ newNode = Rm_osalMalloc(sizeof(Rm_ValidInstNode));
+
+ strcpy(newNode->name, instName);
+ newNode->allocRefCount = 0;
+ newNode->deletePending = FALSE;
+
+ return(newNode);
+}
+
+void Rm_freeValidInstNode(Rm_ValidInstNode *node)
+{
+ if (node->allocRefCount == 0) {
+ Rm_osalFree((void *)node, sizeof(Rm_ValidInstNode));
+ }
+}
+
+/* Prototype for tree node comparison function
+ * element1 < element2 --> return < 0
+ * element1 = element2 --> return 0
+ * element1 > element2 --> return > 0 */
+int Rm_ValidInstNodeCompare(Rm_ValidInstNode *element1, Rm_ValidInstNode *element2)
+{
+ return(strcmp(element1->name, element2->name));
+}
+
+/* Generate the red-black tree manipulation functions */
+RB_GENERATE(_Rm_ValidInstTree, _Rm_ValidInstNode, linkage, Rm_ValidInstNodeCompare);
+
+/**********************************************************************
+ ********************** Internal Functions ****************************
+ **********************************************************************/
+
+int32_t Rm_policyCheckInstances(Rm_ValidInstTree *root,
Rm_PolicyPermission *permissionsList)
{
- Rm_PolicyValidInst *validInst = validInstList;
Rm_PolicyPermission *permission = permissionsList;
- bool instNameMatch = FALSE;
+ bool instNameMatch = FALSE;
- /* Check each instance name in the permission list against the list of valid instance
- * names. Return an error if any permission instance name is not in the valid instance
- * name list */
- while (permission)
- {
- /* Instantly declare a name match if the permission's instance name is the "all"
- * wildcard */
- if (strcmp(permission->instName, Rm_policyAllInstances) == 0)
- {
+ while (permission) {
+ if (strcmp(permission->instName, Rm_policyAllInstances) == 0) {
instNameMatch = TRUE;
}
- else
- {
- while (validInst)
- {
- if (strcmp(permission->instName, validInst->instName) == 0)
- {
+ else if (Rm_policyGetValidInstNode(root, permission->instName)) {
instNameMatch = TRUE;
- }
- validInst = validInst->nextValidInst;
- }
}
- if (!instNameMatch)
- {
+ if (!instNameMatch) {
return(RM_INIT_ERROR_POLICY_UNKNOWN_INSTANCE);
}
- /* Get the next permission and reset to the beginning of the valid instance list */
permission = permission->nextPermission;
- validInst = validInstList;
instNameMatch = FALSE;
}
@@ -119,7 +146,8 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
uint32_t instNameIndex;
bool foundInstName;
bool instNameComplete;
- bool foundAssignment;
+ bool assignmentLeft;
+ bool assignmentRight;
/* Create a local copy of the sub-permission string */
permStrPtr = Rm_osalMalloc(permStrLen);
@@ -145,31 +173,27 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
* d) There is more than one instance subgroup specified in the string. There
* should only be one subgroup per sub-permission string */
Rm_osalFree((void *)permStrStart, permStrLen);
- *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_INSTANCE_GROUP;
return(NULL);
}
/* Create a permission entry for each instance specified in the instance group.
* Instances names are separated by one or more spaces. */
- permStrPtr = subgroupStart;
+ permStrPtr = subgroupStart + 1;
instNameIndex = 0;
foundInstName = FALSE;
instNameComplete = FALSE;
- while (permStrPtr <= subgroupEnd)
- {
+ while (permStrPtr <= subgroupEnd) {
if ((isspace(*permStrPtr) || (*permStrPtr == RM_POLICY_PERM_SUBGROUP_END))
- && foundInstName)
- {
+ && foundInstName) {
/* First space encountered after copying an instance name. This
* terminates the instance name. All other space characters are
* ignored. */
instNameTemp[instNameIndex] = '\0';
instNameComplete = TRUE;
}
- else
- {
- if (!foundInstName)
- {
+ else {
+ if (!foundInstName) {
/* First non-whitespace character encountered is the start of an
* instance name */
foundInstName = TRUE;
@@ -179,21 +203,18 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
instNameTemp[instNameIndex++] = *permStrPtr;
}
- if (instNameComplete)
- {
+ if (instNameComplete) {
newPerm = (Rm_PolicyPermission *) Rm_osalMalloc(sizeof(Rm_PolicyPermission));
memset((void *)newPerm, 0, sizeof(Rm_PolicyPermission));
strcpy(newPerm->instName, instNameTemp);
newPerm->nextPermission = NULL;
- if (prevPerm == NULL)
- {
+ if (prevPerm == NULL) {
/* Save the first instance so it can be returned */
startPerm = newPerm;
}
- else
- {
+ else {
prevPerm->nextPermission = (void *) newPerm;
}
prevPerm = newPerm;
@@ -208,220 +229,187 @@ Rm_PolicyPermission *Rm_policyParseSubPermission(char *permStrStart, char *permS
/* Fill in the permissions for each instance name */
- /* Look on left of instance group for the permission assignments. */
- permStrPtr = subgroupStart;
- foundAssignment = FALSE;
+ /* Look on left of instance group for permission assignments. */
+ permStrPtr = subgroupStart - 1;
+ assignmentLeft = FALSE;
while (permStrPtr >= permStrStart)
{
- if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT)
- {
- if (foundAssignment)
- {
+ if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT) {
+ if (assignmentLeft) {
/* Assignment character has been found more than once. This is a
* syntax error. Free the permission list and the temporary string
* and return. */
- while (startPerm)
- {
+ while (startPerm) {
nextPerm = startPerm->nextPermission;
Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
startPerm = nextPerm;
- Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
- *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
- return(NULL);
}
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
+ return(NULL);
}
- else
- {
- foundAssignment = TRUE;
+ else {
+ assignmentLeft = TRUE;
}
}
- else if (!isspace(*permStrPtr))
- {
- if (foundAssignment)
- {
+ else if (!isspace(*permStrPtr)) {
+ if (assignmentLeft) {
if ((*permStrPtr == RM_POLICY_PERM_INIT_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_INIT_UPPER))
- {
- /* Set the init permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_INIT_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_INIT_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_USE_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_USE_UPPER))
- {
- /* Set the use permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_USE_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_USE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER))
- {
- /* Set the exclusive permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_UPPER))
- {
- /* Set the shared Linux permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_SHARED_LINUX_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
- else
- {
+ else {
/* Invalid permission character. This is a
* syntax error. Free the permission list and the temporary string
* and return. */
- while (startPerm)
- {
+ while (startPerm) {
nextPerm = startPerm->nextPermission;
Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
startPerm = nextPerm;
- Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
- *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
- return(NULL);
- }
+ }
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_PERM_CHAR;
+ return(NULL);
}
}
- else
- {
+ else {
/* Character found without the assignment character being found. This is a
* syntax error. Free the permission list and the temporary string
* and return. */
- while (startPerm)
- {
+ while (startPerm) {
nextPerm = startPerm->nextPermission;
Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
startPerm = nextPerm;
- Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
- *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
- return(NULL);
- }
+ }
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_PERM_CHAR_WITHOUT_ASSIGN_CHAR;
+ return(NULL);
}
}
permStrPtr--;
}
- /* Look on right of instance group for the permission assignments. */
- permStrPtr = subgroupEnd;
- while (permStrPtr <= permStrEnd)
- {
- if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT)
- {
- if (foundAssignment)
- {
+ /* Look on right of instance group for permission assignments. */
+ permStrPtr = subgroupEnd + 1;
+ while (permStrPtr < permStrEnd) {
+ if (assignmentLeft && (!isspace(*permStrPtr))) {
+ /* There should be nothing but spaces on right if assignment was already found on left */
+ while (startPerm) {
+ nextPerm = startPerm->nextPermission;
+ Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
+ startPerm = nextPerm;
+ }
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_CHAR_ON_RIGHT_WITH_ASSINMENT_ON_LEFT;
+ return(NULL);
+ }
+
+ if (*permStrPtr == RM_POLICY_PERM_ASSIGNMENT) {
+ if (assignmentRight) {
/* Assignment character has been found more than once. This is a
* syntax error. Free the permission list and the temporary string
* and return. */
- while (startPerm)
- {
+ while (startPerm) {
nextPerm = startPerm->nextPermission;
Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
startPerm = nextPerm;
- Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
- *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
- return(NULL);
}
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
+ return(NULL);
}
- else
- {
- foundAssignment = TRUE;
+ else {
+ assignmentRight = TRUE;
}
}
- else if (!isspace(*permStrPtr))
- {
- if (foundAssignment)
- {
+ else if (!isspace(*permStrPtr)) {
+ if (assignmentRight) {
if ((*permStrPtr == RM_POLICY_PERM_INIT_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_INIT_UPPER))
- {
- /* Set the init permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_INIT_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_INIT_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_USE_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_USE_UPPER))
- {
- /* Set the use permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_USE_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_USE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER))
- {
- /* Set the exclusive permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_EXCLUSIVE_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_EXCLUSIVE_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
else if ((*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_LOWER) ||
- (*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_UPPER))
- {
- /* Set the shared Linux permissions for each of the instances specified in the group */
+ (*permStrPtr == RM_POLICY_PERM_SHARED_LINUX_UPPER)) {
newPerm = startPerm;
- while (newPerm)
- {
+ while (newPerm) {
RM_POLICY_SET_PERM(newPerm->permissionBits, RM_POLICY_PERM_SHARED_LINUX_SHIFT, 1);
newPerm = newPerm->nextPermission;
}
}
- else
- {
+ else {
/* Invalid permission character. This is a
* syntax error. Free the permission list and the temporary string
* and return. */
- while (startPerm)
- {
+ while (startPerm) {
nextPerm = startPerm->nextPermission;
Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
startPerm = nextPerm;
- Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
- *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
- return(NULL);
- }
+ }
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_INVALID_PERM_CHAR;
+ return(NULL);
}
}
- else
- {
+ else {
/* Character found without the assignment character being found. This is a
* syntax error. Free the permission list and the temporary string
* and return. */
- while (startPerm)
- {
+ while (startPerm) {
nextPerm = startPerm->nextPermission;
Rm_osalFree((void *)startPerm, sizeof(Rm_PolicyPermission));
startPerm = nextPerm;
- Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
- *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR;
- return(NULL);
}
+ Rm_osalFree((void *)permStrStart, sizeof(permStrLen));
+ *result = RM_INIT_ERROR_POLICY_SYNTAX_ERROR_MORE_THAN_ONE_ASSIGNMENT_CHAR;
+ return(NULL);
}
}
permStrPtr++;
{
Rm_PolicyPermission *nextPerm;
- while (permissionList != NULL)
- {
+ while (permissionList != NULL) {
nextPerm = permissionList->nextPermission;
- /* Free the list element */
Rm_osalFree((void *)permissionList, sizeof(Rm_PolicyPermission));
permissionList = nextPerm;
}
@@ -455,12 +441,10 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
uint32_t permStrLen = strlen(assignment->permissionsList) + 1;
uint32_t i = 0;
- while(i < permStrLen)
- {
+ while(i < permStrLen) {
/* Find the first sub-permission specification and parse it. A sub-permission
* can be terminated by the termination character or the end of the string. */
- if (!(permStrEnd = strchr(permStrStart, RM_POLICY_PERM_TERMINATOR)))
- {
+ if (!(permStrEnd = strchr(permStrStart, RM_POLICY_PERM_TERMINATOR))) {
/* Sub-permission termination character not found. The permission string
* end is the end of the entire permission string */
permStrEnd = permStrStart + strlen(permStrStart);
@@ -468,28 +452,24 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
newPerm = Rm_policyParseSubPermission(permStrStart, permStrEnd, result);
- if (*result != RM_INIT_OK)
- {
+ if (*result != RM_INIT_OK) {
/* Delete the permission list that's been created thus far, return
* the error and NULL for the permission list */
Rm_policyFreeAssignmentPermissions(startPerm);
return(NULL);
}
- if (prevPerm == NULL)
- {
+ if (prevPerm == NULL) {
/* Save the first sub-permission in the list so it can be returned */
startPerm = newPerm;
}
- else
- {
+ else {
prevPerm->nextPermission = newPerm;
}
/* Set prevPerm to the last sub-permission returned by the sub-permission parser */
prevPerm = newPerm;
- while(prevPerm->nextPermission != NULL)
- {
+ while(prevPerm->nextPermission != NULL) {
prevPerm = prevPerm->nextPermission;
}
@@ -500,33 +480,24 @@ Rm_PolicyPermission *Rm_policyGetAssignmentPermissions(Rm_PolicyAssignment *assi
}
*result = RM_INIT_OK;
- /* Return a pointer to the start of the permissions list */
return(startPerm);
}
-int32_t Rm_policyValidateAssignmentPermissions(Rm_PolicyValidInst *validInstList,
+int32_t Rm_policyValidateAssignmentPermissions(Rm_ValidInstTree *root,
Rm_PolicyAssignment *assignmentList)
{
Rm_PolicyAssignment *assignment = assignmentList;
Rm_PolicyPermission *permissionList;
int32_t result;
- while (assignment)
- {
- /* Run the permissions parser to make sure the assignment's permissions
- * parse okay */
+ while (assignment) {
+ /* Make sure assignment's permissions parse okay */
permissionList = Rm_policyGetAssignmentPermissions(assignment, &result);
- if (result != RM_INIT_OK)
- {
+ if (result != RM_INIT_OK) {
return(result);
}
- /* Compare the instances defined in the permissions with those defined
- * in the valid instance list. Return an error if there are any
- * instances defined in the permissions that are not defined in the
- * valid instance list */
- if (result = Rm_policyCheckInstances(validInstList, permissionList) != RM_INIT_OK)
- {
+ if (result = Rm_policyCheckInstances(root, permissionList) != RM_INIT_OK) {
Rm_policyFreeAssignmentPermissions(permissionList);
return(result);
}
@@ -538,111 +509,143 @@ int32_t Rm_policyValidateAssignmentPermissions(Rm_PolicyValidInst *validInstList
return (RM_INIT_OK);
}
+void Rm_policyIncrementValidInstAllocationCount(void *validInstNameNode)
+{
+ Rm_ValidInstNode *node = (Rm_ValidInstNode *)validInstNameNode;
+
+ node->allocRefCount++;
+}
+
+void Rm_policyDecrementValidInstAllocationCount(void *validInstNameNode)
+{
+ Rm_ValidInstNode *node = (Rm_ValidInstNode *)validInstNameNode;
+
+ node->allocRefCount--;
+}
+
+void *Rm_policyGetValidInstNode(void *validInstTree, char *instName)
+{
+ Rm_ValidInstTree *root = (Rm_ValidInstTree *)validInstTree;
+ Rm_ValidInstNode findNode;
+
+ memset((void *)&findNode, 0, sizeof(Rm_ValidInstNode));
+ strcpy(findNode.name, instName);
+
+ return (RB_FIND(_Rm_ValidInstTree, root, &findNode));
+}
+
+char *Rm_policyGetValidInstNodeName(void *validInstNode)
+{
+ Rm_ValidInstNode *node = validInstNode;
+
+ return (node->name);
+}
+
+void *Rm_policyGetLinuxInstNode(void * validInstTree)
+{
+ char linuxName[] = RM_ALLOCATED_TO_LINUX;
+
+ return (Rm_policyGetValidInstNode(validInstTree, linuxName));
+}
+
+/* TODO: ADD ABILITY TO RETURN THE SYNTAX ERROR LOCATION */
int32_t Rm_policyValidatePolicy(Rm_Inst *rmInst, void *policyDtb)
{
- int32_t nodeOffset;
- int32_t propertyOffset;
- int32_t depth;
- const char *nodeName;
- const char *propertyName;
- int32_t propertyLen;
- const void *propertyData;
- Rm_PolicyPropType propertyType;
- Rm_PolicyValidInst *validInstList;
+ int32_t nodeOffset;
+ int32_t propertyOffset;
+ int32_t depth;
+ const char *nodeName;
+ const char *propertyName;
+ int32_t propertyLen;
+ const void *propertyData;
+ Rm_PolicyPropType propertyType;
Rm_PolicyAssignment *assignmentList;
- int32_t result;
+ int32_t result;
depth = RM_DTB_UTIL_STARTING_DEPTH;
nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;
- /* Get the root node's properties which must contain the valid-instance list */
- nodeOffset = fdt_first_property_offset(policyDtb, nodeOffset);
- if (nodeOffset < -FDT_ERR_NOTFOUND)
- {
- return (nodeOffset);
- }
- else if (nodeOffset == -FDT_ERR_NOTFOUND)
- {
- return (RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED);
- }
- propertyData = fdt_getprop_by_offset(policyDtb, nodeOffset, &nodeName, &propertyLen);
- propertyType = Rm_policyGetPropertyType(nodeName);
- if (propertyType != Rm_policyPropType_VALID_INSTANCES)
- {
- return (RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED);
- }
- validInstList = Rm_policyExtractValidInstances(propertyData, propertyLen);
-
- /* Parse the DTB, verifying each resource's assignment permissions. The
- * permissions must have the correct syntax and contain valid instance names
- * according the validInstList */
- while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) && (depth >= RM_DTB_UTIL_STARTING_DEPTH))
- {
+ /* Parse DTB, verifying each resource's assignment permissions.
+ * Permissions must have correct syntax and contain valid instance names
+ * according validInstList */
+ while ((nodeOffset >= RM_DTB_UTIL_STARTING_NODE_OFFSET) &&
+ (depth >= RM_DTB_UTIL_STARTING_DEPTH)) {
nodeOffset = fdt_next_node(policyDtb, nodeOffset, &depth);
nodeName = fdt_get_name(policyDtb, nodeOffset, NULL);
-
- /* Parse the properties for an assignment field if the node contains any properties. */
propertyOffset = fdt_first_property_offset(policyDtb, nodeOffset);
- if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET)
- {
- /* Make sure the resource node name matches an existing allocator */
- if (Rm_allocatorFind(rmInst, (char *)nodeName) == NULL)
- {
- Rm_policyFreeValidInstances(validInstList);
+ if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+ if (Rm_allocatorFind(rmInst, (char *)nodeName) == NULL) {
+ /* No allocator tied to resource name */
return(RM_INIT_ERROR_POLICY_UNKNOWN_RESOURCE);
}
- while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET)
- {
- /* Get the assignment data */
+ while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
-
propertyType = Rm_policyGetPropertyType(propertyName);
- if (propertyType == Rm_policyPropType_ASSIGNMENTS)
- {
+ if (propertyType == Rm_policyPropType_ASSIGNMENTS) {
assignmentList = Rm_policyExtractAssignments(propertyData, propertyLen);
- /* Make sure the assignment's permissions parse okay and there all RM instances
- * defined in the permission lists match with the valid instances. */
- if ((result = Rm_policyValidateAssignmentPermissions(validInstList, assignmentList)) !=
- RM_INIT_OK)
- {
- Rm_policyFreeValidInstances(validInstList);
+ if ((result = Rm_policyValidateAssignmentPermissions((Rm_ValidInstTree *) rmInst->validInstances,
+ assignmentList)) != RM_INIT_OK) {
Rm_policyFreeAssignments(assignmentList);
return(result);
}
-
Rm_policyFreeAssignments(assignmentList);
}
-
propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
}
}
}
-
- Rm_policyFreeValidInstances(validInstList);
return(RM_INIT_OK);
}
-/* TODO: ADD ABILITY TO RETURN THE SYNTAX ERROR LOCATION */
-int32_t Rm_policyInit(Rm_Inst *rmInst, void *policyDtb)
+void *Rm_policyCreateValidInstTree(void *policyDtb, int32_t *result)
{
- int32_t result = RM_INIT_OK;
-
- /* Open the policy DTB and create the instance node offset lookup table */
- fdt_open_into(policyDtb, policyDtb, fdt_totalsize(policyDtb));
-
- /* Validate the RM policy and store it in the RM instance if validation succeeds
- * a) Compare the list of valid instances with the instances specified in
- * the permission assignments
- * b) Make sure there are no syntax errors in the assignment permission
- * strings */
- if ((result = Rm_policyValidatePolicy(rmInst, policyDtb)) == RM_INIT_OK)
- {
- rmInst->policy = policyDtb;
+ int32_t validInstOffset;
+ const char *validInstName;
+ int32_t validInstLen;
+ const void *validInstData;
+ Rm_PolicyPropType propertyType;
+ Rm_PolicyValidInst *validInstList;
+ Rm_ValidInstTree *rootEntry = NULL;
+ Rm_ValidInstNode *newNode;
+ char linuxName[] = RM_ALLOCATED_TO_LINUX;
+
+ /* Valid instance list must be first and only property in the root node of
+ * the policyDtb */
+ validInstOffset = fdt_first_property_offset(policyDtb, RM_DTB_UTIL_STARTING_NODE_OFFSET);
+ if (validInstOffset < -FDT_ERR_NOTFOUND) {
+ *result = validInstOffset;
+ return (NULL);
+ }
+ else if (validInstOffset == -FDT_ERR_NOTFOUND) {
+ *result = RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED;
+ return (NULL);
+ }
+ validInstData = fdt_getprop_by_offset(policyDtb, validInstOffset, &validInstName, &validInstLen);
+ propertyType = Rm_policyGetPropertyType(validInstName);
+ if (propertyType != Rm_policyPropType_VALID_INSTANCES) {
+ *result = RM_INIT_ERROR_POLICY_NO_VALID_INSTANCES_DEFINED;
+ return (NULL);
}
+ validInstList = Rm_policyExtractValidInstances(validInstData, validInstLen);
- return(result);
-}
+ /* Create the tree */
+ rootEntry = Rm_osalMalloc(sizeof(Rm_ValidInstTree));
+ RB_INIT(rootEntry);
+
+ while (validInstList) {
+ newNode = Rm_newValidInstNode(validInstList->instName);
+ RB_INSERT(_Rm_ValidInstTree, rootEntry, newNode);
+
+ validInstList = validInstList->nextValidInst;
+ }
+
+ /* Add the Linux kernel node */
+ newNode = Rm_newValidInstNode(linuxName);
+ RB_INSERT(_Rm_ValidInstTree, rootEntry, newNode);
+ *result = RM_INIT_OK;
+ return ((void *)rootEntry);
+}
diff --git a/src/rm_services.c b/src/rm_services.c
index dd85f95a0fa8f781bb05de2e0c13b21b979c9754..81027c13ad5c5543fa30ffd1295d23c763dd2bee 100644 (file)
--- a/src/rm_services.c
+++ b/src/rm_services.c
{
/* Service was approved and service was an allocate request the resource
* data is passed back to the component */
- if ((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||
+ if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
(transaction->type == Rm_service_RESOURCE_GET_BY_NAME))
{
strcpy(serviceResponse->resourceName, transaction->resourceInfo.name);
/* Service was approved and service was an allocate request. The resource
* data is passed back to the component */
if ((serviceResponse.serviceState == RM_SERVICE_APPROVED_AND_COMPLETED) &&
- ((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||
+ ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
(transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))
{
strcpy(serviceResponse.resourceName, transaction->resourceInfo.name);
diff --git a/src/rm_transport.c b/src/rm_transport.c
index 091870522ade5d9e4dd986ff638a3d65f31a1254..8d203bd0d2add30bc94b34987199578c19681a84 100644 (file)
--- a/src/rm_transport.c
+++ b/src/rm_transport.c
@@ -257,10 +257,14 @@ Rm_Packet *Rm_transportCreateResourceReqPkt(Rm_Inst *rmInst, Rm_TransportNode *d
resourceReqPkt = (Rm_ResourceRequestPkt *) rmPkt->data;\r
/* Populate the resource request packet using the transaction information */\r
resourceReqPkt->requestId = transaction->localId;\r
- if (transaction->type == Rm_service_RESOURCE_ALLOCATE)\r
+ if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT)\r
{\r
- resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE;\r
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_INIT;\r
}\r
+ else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)\r
+ {\r
+ resourceReqPkt->resourceReqType = Rm_resReqPktType_ALLOCATE_USE;\r
+ } \r
else if (transaction->type == Rm_service_RESOURCE_FREE)\r
{\r
resourceReqPkt->resourceReqType = Rm_resReqPktType_FREE;\r
transaction->remoteOriginatingId = resourceReqPkt->requestId;\r
\r
/* Transfer the rest of the data into the transaction */\r
- if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE)\r
+ if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE_INIT)\r
{\r
- transaction->type = Rm_service_RESOURCE_ALLOCATE;\r
+ transaction->type = Rm_service_RESOURCE_ALLOCATE_INIT;\r
}\r
+ else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_ALLOCATE_USE)\r
+ {\r
+ transaction->type = Rm_service_RESOURCE_ALLOCATE_USE;\r
+ } \r
else if (resourceReqPkt->resourceReqType == Rm_resReqPktType_FREE)\r
{\r
transaction->type = Rm_service_RESOURCE_FREE;\r
transaction->state = resourceRespPkt->requestState;\r
\r
if ((transaction->state == RM_SERVICE_APPROVED_AND_COMPLETED) &&\r
- ((transaction->type == Rm_service_RESOURCE_ALLOCATE) ||\r
+ ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||\r
+ (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||\r
(transaction->type == Rm_service_RESOURCE_GET_BY_NAME)))\r
{\r
/* Copy resources from request for allocations since an allocation\r
diff --git a/test/rm_test.c b/test/rm_test.c
index 92cecedd9dc44dd2865188a1e9d1c3e602f31fe9..ea44165a062d28f986be12c73e0c3b27cddc6fcb 100644 (file)
--- a/test/rm_test.c
+++ b/test/rm_test.c
/* Try to allocate the memory region taken by the Linux Kernel */
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = memRegionName;
requestInfo.resourceBase = 12;
requestInfo.resourceLength = 1;
/* Allocate some resources for testing tree interaction with multiple allocations from different instances */
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = aifName;
requestInfo.resourceBase = 14;
requestInfo.resourceLength = 5;
requestInfo.resourceLength);
}
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = aifName;
requestInfo.resourceBase = 19;
requestInfo.resourceLength = 31;
}
else if (MultiProc_self() == 1)
{
- char resourceName[RM_RESOURCE_NAME_MAX_CHARS] = "gp-queue";
char resourceNsName[RM_RESOURCE_NAME_MAX_CHARS] = "My_Favorite_Queue";
char aifName[RM_RESOURCE_NAME_MAX_CHARS] = "aif-rx-ch";
}
/* Allocate the resources via the service port from the Client */
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_INIT;
requestInfo.resourceName = responseInfo.resourceName;
requestInfo.resourceBase = responseInfo.resourceBase;
requestInfo.resourceLength = responseInfo.resourceLength;
/* Allocate some resources for testing tree interaction with multiple allocations from different instances */
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = aifName;
requestInfo.resourceBase = 0;
requestInfo.resourceLength = 6;
}
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_INIT;
requestInfo.resourceName = aifName;
requestInfo.resourceBase = 50;
requestInfo.resourceLength = 7;
takeSyncObj();
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = accumChName;
requestInfo.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
requestInfo.resourceLength = 5;
}
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = accumChName;
requestInfo.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
requestInfo.resourceLength = 2;
}
memset((void *) &requestInfo, 0, sizeof(Rm_ServiceReqInfo));
- requestInfo.type = Rm_service_RESOURCE_ALLOCATE;
+ requestInfo.type = Rm_service_RESOURCE_ALLOCATE_USE;
requestInfo.resourceName = accumChName;
requestInfo.resourceBase = RM_RESOURCE_BASE_UNSPECIFIED;
requestInfo.resourceLength = 2;
*/
Int main(Int argc, Char* argv[])
{
- Rm_InitCfg rmInitCfg;
- Task_Params taskParams;
- FILE *globalResourceFp;
- FILE *linuxDtbFp;
- FILE *globalPolicyFp;
- Int globalResourceFileSize;
- Int linuxDtbFileSize;
- Int globalPolicyFileSize;
- void *globalResourceList = NULL;
- void *linuxDtb = NULL;
- void *globalPolicy = NULL;
- Int status;
- Int readSize;
+ Rm_InitCfg rmInitCfg;
+ Task_Params taskParams;
+ FILE *globalResourceFp;
+ FILE *linuxDtbFp;
+ FILE *globalPolicyFp;
+ Int globalResourceFileSize;
+ Int linuxDtbFileSize;
+ Int globalPolicyFileSize;
+ void *globalResourceList = NULL;
+ void *linuxDtb = NULL;
+ void *globalPolicy = NULL;
+ Int status;
+ Int readSize;
+ int32_t result;
System_printf ("*********************************************************\n");
System_printf ("********************** RM Testing ***********************\n");
* Core 1: 2 RM Instances - RM Client Delegate
* RM Client
*/
- if (MultiProc_self()== 0)
- {
+ if (MultiProc_self()== 0) {
initSyncObj();
- /* Open the Global Resource and Policy DTB files */
globalResourceFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-global-resources.dtb", "rb");
linuxDtbFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-linux-evm.dtb", "rb");
globalPolicyFp = fopen("C:\\ti\\pdk_tci6614_1_0_0_11\\packages\\ti\\drv\\rm\\device\\tci6614-server-policy.dtb", "rb");
- /* Get the size of the Global Resource List, Linux DTB, and Global Policy */
fseek(globalResourceFp, 0, SEEK_END);
globalResourceFileSize = ftell(globalResourceFp);
rewind(globalResourceFp);
globalPolicyFileSize = ftell(globalPolicyFp);
rewind(globalPolicyFp);
- /* Allocate buffers to hold the Global Resource List, Linux DTB, and Global Policy */
globalResourceList = Osal_rmMalloc(globalResourceFileSize);
linuxDtb = Osal_rmMalloc(linuxDtbFileSize);
globalPolicy = Osal_rmMalloc(globalPolicyFileSize);
- /* Read the file data into the allocated buffers */
readSize = fread(globalResourceList, 1, globalResourceFileSize, globalResourceFp);
System_printf("Read Size compared to file size: %d : %d\n", readSize, globalResourceFileSize);
readSize = fread(linuxDtb, 1, linuxDtbFileSize, linuxDtbFp);
System_printf("Read Size compared to file size: %d : %d\n", readSize, linuxDtbFileSize);
readSize = fread(globalPolicy, 1, globalPolicyFileSize, globalPolicyFp);
System_printf("Read Size compared to file size: %d : %d\n", readSize, globalPolicyFileSize);
-
- /* Create the RM Server instance */
+
+ /* Create the Server instance */
rmInitCfg.instName = &rmServerName[0];
rmInitCfg.instType = Rm_instType_SERVER;
- /* Provide the DTBs to the RM Server */
rmInitCfg.globalResourceList = globalResourceList;
rmInitCfg.linuxDtb = linuxDtb;
rmInitCfg.policy = globalPolicy;
-
- /* Get the RM Server handle */
- rmServerHandle = Rm_init(&rmInitCfg);
- System_printf("Core %d: RM Server instance created\n", MultiProc_self());
+ rmServerHandle = Rm_init(&rmInitCfg, &result);
+ System_printf("Core %d: RM Server instance created. Result = %d\n", MultiProc_self(), result);
Rm_printResourceStatus(rmServerHandle);
}
- else if (MultiProc_self()== 1)
- {
+ else if (MultiProc_self()== 1) {
/* Create the RM Client Delegate instance */
rmInitCfg.instName = &rmClientDelegateName[0];
rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE;
- /* SET TO NULL - FEATURES NOT ADDED YET */
rmInitCfg.globalResourceList = NULL;
+ rmInitCfg.linuxDtb = NULL;
rmInitCfg.policy = NULL;
-
- /* Get the RM Client Delegate handle */
- rmClientDelegateHandle = Rm_init(&rmInitCfg);
- System_printf("Core %d: RM Client Delegate instance created\n", MultiProc_self());
+ rmClientDelegateHandle = Rm_init(&rmInitCfg, &result);
+ System_printf("Core %d: RM Client Delegate instance created. Result = %d\n", MultiProc_self(), result);
/* Create the RM Client instance */
rmInitCfg.instName = &rmClientName[0];
rmInitCfg.instType = Rm_instType_CLIENT;
- /* SET TO NULL - FEATURES NOT ADDED YET */
rmInitCfg.globalResourceList = NULL;
+ rmInitCfg.linuxDtb = NULL;
rmInitCfg.policy = NULL;
-
- /* Get the RM Client handle */
- rmClientHandle = Rm_init(&rmInitCfg);
- System_printf("Core %d: RM Client instance created\n", MultiProc_self());
+ rmClientHandle = Rm_init(&rmInitCfg, &result);
+ System_printf("Core %d: RM Client instance created. Result = %d\n", MultiProc_self(), result);
}
- /*
- * Ipc_start() calls Ipc_attach() to synchronize all remote processors
- * because 'Ipc.procSync' is set to 'Ipc.ProcSync_ALL' in *.cfg
- */
System_printf("Core %d: Starting IPC...\n", MultiProc_self());
status = Ipc_start();
- if (status < 0)
- {
+ if (status < 0) {
System_abort("Ipc_start failed\n");
}