]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - keystone-rtos/rm-lld.git/commitdiff
Merge branch 'master' of gtgit01.gt.design.ti.com:git/projects/rm-lld
authorJustin Sobota <jsobota@ti.com>
Tue, 23 Apr 2013 22:18:26 +0000 (18:18 -0400)
committerJustin Sobota <jsobota@ti.com>
Tue, 23 Apr 2013 22:18:26 +0000 (18:18 -0400)
16 files changed:
build/armv7/librm_aearmv7.mk [new file with mode: 0644]
include/rm_allocatorloc.h
include/rm_loc.h
include/rm_policyloc.h
makefile_armv7 [new file with mode: 0644]
rm.h
rm_services.h
src/rm.c
src/rm_allocator.c
src/rm_policy.c
src/rm_services.c
test/dts_files/server-policy.c
test/dts_files/server-policy.dtb
test/dts_files/server-policy.dts
test/rm_mem_test.c
test/rm_test.c

diff --git a/build/armv7/librm_aearmv7.mk b/build/armv7/librm_aearmv7.mk
new file mode 100644 (file)
index 0000000..ec58792
--- /dev/null
@@ -0,0 +1,83 @@
+#*******************************************************************************
+#* FILE PURPOSE: Lower level makefile for Creating Component Libraries for ARMv7
+#*******************************************************************************
+#* FILE NAME: ./lib/librm_aearmv7.mk
+#*
+#* DESCRIPTION: Defines Source Files, Compilers flags and build rules
+#*
+#*******************************************************************************
+#
+
+#
+# Macro definitions referenced below
+#
+empty =
+space =$(empty) $(empty)
+
+# Output for prebuilt generated libraries
+ARMV7LIBDIR ?= ./lib
+ARMV7OBJDIR ?= ./obj
+ARMV7OBJDIR := $(ARMV7OBJDIR)/rm/lib
+ARMV7BINDIR ?= ./bin
+
+ifdef CROSS_TOOL_INSTALL_PATH
+# Support backwards compatibility with KeyStone1 approach
+ CC = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)gcc
+ AC = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)as
+ AR = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)ar
+ LD = $(CROSS_TOOL_INSTALL_PATH)/$(CROSS_TOOL_PRFX)gcc
+endif
+
+INCS = -I. -I$(strip $(subst ;, -I,$(subst $(space),\$(space),$(INCDIR))))
+
+INTERNALDEFS = -D__ARMv7 -D_LITTLE_ENDIAN=1 -D_VIRTUAL_ADDR_SUPPORT -DMAKEFILE_BUILD $(CFLAGS) $(LDFLAGS)
+
+OBJEXT = o 
+INTERNALLINKDEFS =
+SRCDIR = ./src
+UTLSRCDIR = ./util/libfdt
+
+VPATH=$(SRCDIR) $(UTLSRCDIR)
+
+#List the COMMONSRC Files
+COMMONSRCC =        \
+    rm.c            \
+    rm_nameserver.c \
+    rm_policy.c     \
+    rm_services.c   \
+    rm_transport.c  \
+    rm_tree.c       \
+    rm_dtb_util.c   \
+    rm_allocator.c  \
+    fdt.c           \
+    fdt_ro.c        \
+    fdt_rw.c        \
+    fdt_strerror.c  \
+    fdt_sw.c        \
+    fdt_wip.c
+
+# FLAGS for the COMMONSRC Files
+COMMONSRCCFLAGS = $(DEBUG_FLAG) -I$(SRCDIR) -I$(UTLSRCDIR) -I.
+
+# Make Rule for the COMMONSRC Files
+COMMONSRCCOBJS = $(patsubst %.c, $(ARMV7OBJDIR)/%.$(OBJEXT), $(COMMONSRCC))
+
+$(COMMONSRCCOBJS): $(ARMV7OBJDIR)/%.$(OBJEXT): %.c $(ARMV7OBJDIR)/.created
+       -@echo compiling $< ...
+       @$(CC) -c $(COMMONSRCCFLAGS) $(INTERNALDEFS) $(INCS)  $< -o $@
+
+$(ARMV7LIBDIR)/librm.a: $(COMMONSRCCOBJS) $(ARMV7LIBDIR)/.created
+       @echo archiving $? into $@ ...
+       @$(AR) -r $@ $?
+
+$(ARMV7OBJDIR)/.created:
+       @mkdir -p $(ARMV7OBJDIR)
+       @touch $(ARMV7OBJDIR)/.created
+
+$(ARMV7LIBDIR)/.created:
+       @mkdir -p $(ARMV7LIBDIR)
+       @touch $(ARMV7LIBDIR)/.created
+
+clean:
+       @$(RMDIR) $(ARMV7OBJDIR)
+
index 9298ff1d703e4930cdeb7a49ae6d6eb76e867c2e..fae62d8a46a39b465b8cfe5b3cbbda1ae6577ee6 100644 (file)
@@ -49,6 +49,7 @@ extern "C" {
 
 /* RM internal includes */
 #include <ti/drv/rm/include/rm_internal.h>
+#include <ti/drv/rm/include/rm_dtb_utilloc.h>
 #include <ti/drv/rm/include/rm_treeloc.h>
 
 /* Resource properties extracted from the GRL DTB */
@@ -110,9 +111,15 @@ typedef struct Rm_Allocator_s {
     struct Rm_Allocator_s *nextAllocator;
 } Rm_Allocator;
 
+int32_t rmAllocatorCreate(Rm_Handle rmHandle, const char *resourceName, Rm_ResourceRange *range);
+Rm_Allocator *rmAllocatorGetAllocatorList(Rm_Handle rmHandle);
 Rm_Allocator *rmAllocatorFind(Rm_Handle rmHandle, const char *resourceName);
+int rmAllocatorGetNodeLocalization(Rm_Handle rmHandle, char *resourceName,
+                                   int32_t *resBase, uint32_t *resLen);
 int32_t rmAllocatorOperation(Rm_Handle rmHandle, Rm_AllocatorOpInfo *opInfo);
 int32_t rmAllocatorInitializeResources(Rm_Handle rmHandle, void *globalResourceDtb, void *linuxDtb);
+void rmAllocatorDeleteNode(Rm_Handle rmHandle, const char *resName, int32_t resBase, uint32_t resLen);
+int32_t rmAllocatorDelete(Rm_Handle rmHandle, const char *resourceName);
 void rmAllocatorDeleteResources(Rm_Handle rmHandle);
 
 #ifdef __cplusplus
index daef888312e86d2e7e6e73adbb5315f3f32d16be..a2b919f884bdabd77236ac103e18b6cd4c863621 100644 (file)
@@ -78,6 +78,10 @@ typedef struct Rm_Transaction_s {
     int32_t                  state;
     /* Transaction has been forwarded to CD or Server instance.  Waiting for response */
     int8_t                   hasBeenForwarded;
+    /* The transaction ID for a transaction pending on a CD while this
+     * transaction is sent to the Server as a request for data required to complete
+     * pending transaction */
+    uint32_t                 pendingTransactionId;
     /* Name of the RM instance the service originated from */
     char                     serviceSrcInstName[RM_NAME_MAX_CHARS];    
     /* Resource information */
index f430343b5ef58498a42b391158b8a6f2ff169897..2d7373c984e77bb93a761f893f3fc4f22df0d38c 100644 (file)
@@ -155,6 +155,7 @@ uint32_t rmPolicyGetResourceBase(void *policyDtb, Rm_PolicyValidInstNode *validI
                                  int32_t resourceOffset, Rm_PolicyCheckType policyCheckType, 
                                  int32_t *result);
 uint32_t rmPolicyGetResourceAlignment(void *policyDtb, int32_t resourceOffset);
+uint32_t rmPolicyGetResourceAllocSize(void *policyDtb, int32_t resourceOffset);
 int32_t rmPolicyGetResourceOffset(void *policyDtb, char *resourceName);
 int32_t rmPolicyValidatePolicyResourceNames(Rm_Handle rmHandle);
 int32_t rmPolicyValidatePolicy(Rm_Handle rmHandle);
diff --git a/makefile_armv7 b/makefile_armv7
new file mode 100644 (file)
index 0000000..b6730fd
--- /dev/null
@@ -0,0 +1,112 @@
+#*******************************************************************************
+#* FILE PURPOSE: Top level makefile for Creating Component Libraries for ARM
+#* architectures
+#*******************************************************************************
+#* FILE NAME: makefile
+#*
+#* DESCRIPTION: Defines Compiler tools paths, libraries , Build Options 
+#*
+#*
+#*******************************************************************************
+#*
+# (Mandatory) Specify where various tools are installed.
+
+# Output for prebuilt generated libraries
+export ARMV7LIBDIR ?= ./lib
+export DEVICE ?=k2h
+export ARMV7OBJDIR ?= ./obj/$(DEVICE)
+export ARMV7BINDIR ?= ./bin/$(DEVICE)
+
+# ROOT Directory
+export ROOTDIR := ../../..
+
+# INSTALL default paths
+export INSTALL_BIN_BASE_DIR ?= ./install/bin
+export INSTALL_INC_BASE_DIR ?= ./install/include
+export INSTALL_LIB_BASE_DIR ?= ./install/lib
+
+# INCLUDE Directory
+export INCDIR := ../../..;$(PDK_INSTALL_PATH);$(ROOTDIR)
+
+# Common Macros used in make
+
+ifndef RM
+export RM = rm -f
+endif
+
+ifndef CP
+export CP = cp -p
+endif
+
+export MKDIR = mkdir -p
+
+ifndef RMDIR
+export RMDIR = rm -rf
+endif
+
+ifndef SED
+export SED = sed
+endif
+
+ifndef MAKE
+export MAKE = make
+endif
+
+# PHONY Targets
+#.PHONY: all clean lib tests install installbin
+.PHONY: all clean lib install installbin
+
+# all rule
+all: .executables install installbin
+#.executables: lib tests
+.executables: lib
+
+# Libraries
+lib: .libraries
+
+# tests Stub to add tests
+#tests: 
+#      @$(MAKE) -f ./test/$(DEVICE)/armv7/linux/build/makefile all
+
+# examples Stub to add Examples
+#examples: 
+#      @$(MAKE) -f ./example/InfraDmaSC/$(DEVICE)/armv7/linux/build/makefile all
+
+# Make rule to create $(ARMV7LIBDIR)/librm.a library
+.libraries: $(ARMV7LIBDIR)/librm.a
+
+$(ARMV7LIBDIR)/librm.a:
+       @$(MAKE) -f ./build/armv7/librm_aearmv7.mk $@
+
+# Rule to clean $(ARMV7LIBDIR)/librm.a library
+clean:
+       @$(MAKE) -f ./build/armv7/librm_aearmv7.mk $@
+#      @$(MAKE) -f ./test/$(DEVICE)/armv7/linux/build/makefile $@
+       @$(RMDIR) $(ARMV7OBJDIR)/rm
+       @$(RMDIR) $(ARMV7BINDIR)/rm
+       @$(RM) $(ARMV7LIBDIR)/librm.a
+
+installbin:
+       install -d $(INSTALL_BIN_BASE_DIR)
+#      install -c -m 755 $(ARMV7BINDIR)/rm/test/rmTest.out    $(INSTALL_BIN_BASE_DIR)/rmTest_$(DEVICE).out
+#      install -c -m 755 $(ARMV7BINDIR)/rm/test/rmMemTest.out    $(INSTALL_BIN_BASE_DIR)/rmMemTest_$(DEVICE).out       
+#      install -c -m 755 $(ARMV7BINDIR)/rm/test/rmSharedTest.out    $(INSTALL_BIN_BASE_DIR)/rmSharedTest_$(DEVICE).out
+
+install:
+       install -d $(INSTALL_INC_BASE_DIR)/ti/drv/rm/include
+       install -d $(INSTALL_INC_BASE_DIR)/ti/drv/rm/util
+       install -d $(INSTALL_INC_BASE_DIR)/ti/drv/rm/util/libfdt
+       install -d $(INSTALL_INC_BASE_DIR)/ti/drv/rm/device/k2k/
+       install -d $(INSTALL_INC_BASE_DIR)/ti/drv/rm/device/k2h/        
+       install -d $(INSTALL_LIB_BASE_DIR)
+       $(CP) ./*.h                $(INSTALL_INC_BASE_DIR)/ti/drv/rm
+       $(CP) ./include/*.h        $(INSTALL_INC_BASE_DIR)/ti/drv/rm/include
+       $(CP) ./util/*.h        $(INSTALL_INC_BASE_DIR)/ti/drv/rm/util
+       $(CP) ./util/libfdt/*.h $(INSTALL_INC_BASE_DIR)/ti/drv/rm/util/libfdt   
+       $(CP) ./device/k2h/*.c $(INSTALL_INC_BASE_DIR)/ti/drv/rm/device/k2h
+       $(CP) ./device/k2h/*.dtb $(INSTALL_INC_BASE_DIR)/ti/drv/rm/device/k2h
+       $(CP) ./device/k2h/*.dts $(INSTALL_INC_BASE_DIR)/ti/drv/rm/device/k2h           
+       $(CP) ./device/k2k/*.c $(INSTALL_INC_BASE_DIR)/ti/drv/rm/device/k2k     
+       $(CP) ./device/k2k/*.dtb $(INSTALL_INC_BASE_DIR)/ti/drv/rm/device/k2k   
+       $(CP) ./device/k2k/*.dts $(INSTALL_INC_BASE_DIR)/ti/drv/rm/device/k2k           
+       @$(CP) -r $(ARMV7LIBDIR)/*.a         $(INSTALL_LIB_BASE_DIR)
\ No newline at end of file
diff --git a/rm.h b/rm.h
index 79af0bcfe9990802e38544e0e5ad8c92f48c9b80..f61840c2904a90428fd6ee5ea41597b06867ca88 100644 (file)
--- a/rm.h
+++ b/rm.h
@@ -181,11 +181,13 @@ extern "C" {
 #define RM_OK                                      0
 /** RM processing requested service */
 #define RM_SERVICE_PROCESSING                      1
+/** RM CD has placed on the request on hold pending a Server response */
+#define RM_SERVICE_PENDING_SERVER_RESPONSE         2
 /** RM has approved requested service */
-#define RM_SERVICE_APPROVED                        2
+#define RM_SERVICE_APPROVED                        3
 /** RM has approved requested service based on static policy.  Request will be validated 
  *  against global policy once all transports have been registered */
-#define RM_SERVICE_APPROVED_STATIC                 3
+#define RM_SERVICE_APPROVED_STATIC                 4
 
 /** RM service request denial reasons base */
 #define RM_SERVICE_DENIED_BASE                     64
@@ -228,6 +230,8 @@ extern "C" {
 /** Allocate request denied because the resource is already reserved by Linux and "Shared Linux"
  *  privileges are not assigned to the requesting instance */
 #define RM_SERVICE_DENIED_RES_NOT_SHARED_LINUX     RM_SERVICE_DENIED_BASE+17
+/** Status request resource range partially found (Handling of partial status requests not yet implemented) */
+#define RM_SERVICE_DENIED_PARTIAL_STATUS           RM_SERVICE_DENIED_BASE+18
 
 /** Start of libfdt.h error codes */
 #define RM_ERROR_LIBFDT_START                      (-1)
@@ -313,36 +317,46 @@ extern "C" {
 /** RM client attempted to register with more than one Server or CD or a CD attempted to register 
  *  with more than one Server */
 #define RM_ERROR_ALREADY_REGD_SERVER_OR_CD         RM_ERROR_BASE-35
-/** Service has both a NameServer name and a base, length, or alignment specified */
-#define RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT      RM_ERROR_BASE-36
 /** Instance type not recognized */
-#define RM_ERROR_INVALID_INST_TYPE                 RM_ERROR_BASE-37
+#define RM_ERROR_INVALID_INST_TYPE                 RM_ERROR_BASE-36
 /** RM attempted to allocate a transport packet but the rmAllocPkt callout was not registered */
-#define RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD      RM_ERROR_BASE-38
+#define RM_ERROR_TRANSPORT_ALLOC_PKT_NOT_REGD      RM_ERROR_BASE-37
 /** RM attempted to send a packet but the rmSendPkt callout was not registered */
-#define RM_ERROR_TRANSPORT_SEND_NOT_REGD           RM_ERROR_BASE-39
+#define RM_ERROR_TRANSPORT_SEND_NOT_REGD           RM_ERROR_BASE-38
 /** RM attempted to send a response packet but the transport to the remote instance that sent
  *  the request packet is not registered */
-#define RM_ERROR_TRANSPORT_REMOTE_HNDL_NOT_REGD    RM_ERROR_BASE-40
+#define RM_ERROR_TRANSPORT_REMOTE_HNDL_NOT_REGD    RM_ERROR_BASE-39
 /** RM instance cannot be deleted with transports still registered */
-#define RM_ERROR_CANT_DELETE_WITH_REGD_TRANSPORT   RM_ERROR_BASE-41
+#define RM_ERROR_CANT_DELETE_WITH_REGD_TRANSPORT   RM_ERROR_BASE-40
 /** RM instance cannot be deleted with open service handle */
-#define RM_ERROR_CANT_DELETE_WITH_OPEN_SERV_HNDL   RM_ERROR_BASE-42
+#define RM_ERROR_CANT_DELETE_WITH_OPEN_SERV_HNDL   RM_ERROR_BASE-41
 /** RM instance cannot be deleted when there are transactions pending and the 
  *  ignorePendingServices parameter is set to false */
-#define RM_ERROR_CANT_DELETE_PENDING_TRANSACTIONS  RM_ERROR_BASE-43
+#define RM_ERROR_CANT_DELETE_PENDING_TRANSACTIONS  RM_ERROR_BASE-42
 /** Only the Server instance can be used to return resource status via the
  *  Rm_resourceStatus API */
-#define RM_ERROR_INVALID_RES_STATUS_INSTANCE       RM_ERROR_BASE-44
+#define RM_ERROR_INVALID_RES_STATUS_INSTANCE       RM_ERROR_BASE-43
 /** RM Shared Server and Client instances should always return a finished request since 
  *  the instance has access to the resource structures no matter what core the service
  *  is requested from */
-#define RM_ERROR_SHARED_INSTANCE_UNFINISHED_REQ    RM_ERROR_BASE-45
+#define RM_ERROR_SHARED_INSTANCE_UNFINISHED_REQ    RM_ERROR_BASE-44
 /** RM Shared Server and Client instances cannot register transports */
-#define RM_ERROR_SHARED_INSTANCE_CANNOT_REG_TRANS  RM_ERROR_BASE-46
+#define RM_ERROR_SHARED_INSTANCE_CANNOT_REG_TRANS  RM_ERROR_BASE-45
 /** RM Shared Client handle was provided an invalid Shared Server handle.  The shared
  *  server handle was either NULL or was not an instance of type Rm_instType_SHARED_SERVER */
-#define RM_ERROR_INVALID_SHARED_SERVER_HANDLE      RM_ERROR_BASE-47
+#define RM_ERROR_INVALID_SHARED_SERVER_HANDLE      RM_ERROR_BASE-46
+/** A RM Client failed to create a new transaction to request data from the Server in order
+ *  to potentially process a transaction on a Client Delegate */
+#define RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED   RM_ERROR_BASE-47
+/** Service request required a policy check but instance was not initialized with a policy */
+#define RM_ERROR_INSTANCE_HAS_NO_POLICY            RM_ERROR_BASE-48
+/** RM Client Delegate was not provided a policy at initialization */
+#define RM_ERROR_INVALID_CD_CONFIGURATION          RM_ERROR_BASE-49
+/** RM CD freed local resources which allowed a free request of local request to be sent to
+ *  the Server.  The Server free failed so the CD tried to realloc the local resources 
+ *  that were originally freed.  The re-allocate operation failed causing a resource loss
+ *  on the CD */
+#define RM_ERROR_LOST_RESOURCES_ON_CD              RM_ERROR_BASE-50 
 
 /** 
  * @brief Maximum number of characters allowed for RM instance, resource, and
@@ -480,12 +494,11 @@ typedef struct {
  *      status will be printed for every resource.  Also, the NameServer name
  *      entries will be displayed.
  *
- *      This function only prints resources when provided the server handle
- *      since the server stores all the resource and NameServer
- *      data structures.
+ *      This function will return error if a Client handle is provided since
+ *      Clients do not track any resource data structures
  *
- *  @param[in]  rmServerHandle
- *      Server instance handle.
+ *  @param[in]  rmHandle
+ *      Instance handle.
  *
  *  @param[in]  printResources
  *      Non-zero - Resource ownership details will be printed for all
@@ -500,7 +513,7 @@ typedef struct {
  *  @retval
  *      Failure - #RM_ERROR_INVALID_RES_STATUS_INSTANCE  
  */
-int32_t Rm_resourceStatus(Rm_Handle rmServerHandle, int printResources);
+int32_t Rm_resourceStatus(Rm_Handle rmHandle, int printResources);
 
 /**
  *  @b Description
index 6c2ebd4557e3ef924d03febca75facad56cca590..8550ce5c975f1c36a0316050ee1084cc654e9ab8 100644 (file)
@@ -157,9 +157,12 @@ typedef struct {
      *  #RM_RESOURCE_ALIGNMENT_UNSPECIFIED can be substituted. */
     int32_t             resourceAlignment;
     /** The NameServer name associated, or to be associated, with a resource. 
-     *  If the service type is #Rm_service_RESOURCE_GET_BY_NAME and the
-     *  #resourceBase and #resourceLength fields are not NULL a error will
-     *  occur. */
+     *  The NameServer name has precedence over #resourceBase and #resourceLength
+     *  for all resource modification service types as well as
+     *  #Rm_service_RESOURCE_GET_BY_NAME.  If the NameServer name and the base
+     *  and length are not NULL the resource information retrieved from the
+     *  NameServer entry for the name will replace the values present in
+     *  #resourceBase and #resourceLenth */
     const char         *resourceNsName;
     /** Callback function used by RM to provide responses back to application
      *  components after a service request resulted in a blocking operation.
index 4ee5361e33706bf7f817ee22334e95594a6402fa..c19695b058a4b322902193fd67aed75c29251fbb 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
@@ -415,70 +415,95 @@ static void staticAllocationHandler (Rm_Handle rmHandle, Rm_Transaction *transac
     } 
 }
 
-/* FUNCTION PURPOSE: Handles resource status service requests
+/* FUNCTION PURPOSE: Requests resources from Server for CD
  ***********************************************************************
- * DESCRIPTION: Issues a set of allocator operations to retrieve the
- *              current status (currently just owner reference count)
- *              for the resource specified in the transaction
+ * DESCRIPTION: Function creates a service request to allocate resources
+ *              from the Server for local management by the CD.  The
+ *              transaction which causes this request is put in the
+ *              pending state in order to wait for the response from the 
+ *              Server
  */
-static void statusHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+static int32_t cdRequestServerResources(Rm_Inst *rmInst, Rm_Transaction *transaction)
 {
-    Rm_AllocatorOpInfo  opInfo;
-    Rm_NameServerObjCfg nameServerObjCfg;
-    int32_t             retVal = transaction->state;
-
-    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        /* Fill in status logic for CDs */  
-    }
-    else if ((rmInst->instType == Rm_instType_SERVER)||
-             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
-        memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-
-        opInfo.policy = rmInst->u.server.globalPolicy;
-        opInfo.resourceInfo = &transaction->resourceInfo;
-        opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
-        if (opInfo.serviceSrcInstNode) {
-            /* Populated NameServer name has precedence over base and length values */
-            if (strlen(transaction->resourceInfo.nameServerName) > 0) {
-                if ((transaction->resourceInfo.base == 0) &&
-                    (transaction->resourceInfo.length == 0) &&
-                    (transaction->resourceInfo.alignment == 0)) {
-                    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
-                        rmNameServerTreeInv(rmInst->u.server.nameServer);
-                    }
-                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                    nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
-                    nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
-                    if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
-                        strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
-                        transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
-                        transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
-                    }
-                    else {
-                        goto errorExit;
-                    }
-                }
-                else {
-                    retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
-                    goto errorExit;
+    Rm_Transaction *newTrans = NULL;
+    void *          policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    int32_t         resourceOffsetInPolicy;
+    uint32_t        allocSize = 0;
+    int32_t         retVal;
+
+    resourceOffsetInPolicy = rmPolicyGetResourceOffset(policy, transaction->resourceInfo.name);
+    if (resourceOffsetInPolicy > 0) {
+        if (allocSize = rmPolicyGetResourceAllocSize(policy, resourceOffsetInPolicy)) {
+            if (newTrans = rmTransactionQueueAdd(rmInst)) {
+                newTrans->type = transaction->type;
+                strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+                newTrans->state = RM_SERVICE_PROCESSING;       
+                strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+                newTrans->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+                /* Make sure request length will satisfy transaction length */
+                newTrans->resourceInfo.length = allocSize;
+                while (newTrans->resourceInfo.length < transaction->resourceInfo.length) {
+                    newTrans->resourceInfo.length += allocSize;
                 }
-            }
+                newTrans->resourceInfo.alignment = transaction->resourceInfo.alignment;
+                newTrans->pendingTransactionId = transaction->localId;
+                transactionForwarder(rmInst, newTrans);
 
-            if ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
-                (transaction->resourceInfo.length == 0)) {
-                retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
-                goto errorExit;
+                retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
             }
-        
-            opInfo.operation = Rm_allocatorOp_GET_STATUS;
-            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);    
+            else {
+                retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;    
+            }       
         }
         else {
-            retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+            /* Forward request to Server for completion if policy has 
+             * no allocation size for resource */
+            retVal = RM_SERVICE_PROCESSING;
         }
-errorExit:        
-        transaction->state = retVal;                 
     }
+    else {
+        /* Resource could not be found in policy */
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+    }
+    return (retVal);
+}
+
+/* FUNCTION PURPOSE: Frees local resources to Server from CD
+ ***********************************************************************
+ * DESCRIPTION: Function creates a service request to free locally
+ *              managed resources that are now localized back to
+ *              the Server.
+ */
+static int32_t cdFreeResourcesToServer(Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    int32_t         baseToFree = transaction->resourceInfo.base;
+    uint32_t        lenToFree = transaction->resourceInfo.length;
+    Rm_Transaction *newTrans = NULL; 
+    /* This function should only be called after a free was approved */
+    int32_t         retVal = RM_SERVICE_APPROVED;    
+    
+    /* Did free result in a localized free node that can be given back to Server?  If
+     * so create transaction to Server to free localized resource node */
+    if (rmAllocatorGetNodeLocalization((Rm_Handle)rmInst, transaction->resourceInfo.name,
+                                       &baseToFree, &lenToFree)) {
+        if (newTrans = rmTransactionQueueAdd(rmInst)) {
+            newTrans->type = transaction->type;
+            strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+            newTrans->state = RM_SERVICE_PROCESSING;       
+            strncpy(newTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+            newTrans->resourceInfo.base = baseToFree;
+            newTrans->resourceInfo.length = lenToFree;
+            newTrans->pendingTransactionId = transaction->localId;
+            transactionForwarder(rmInst, newTrans);
+
+            retVal = RM_SERVICE_PENDING_SERVER_RESPONSE;
+        }
+        else {
+            /* Error: Need to re-allocate what was freed */
+            retVal = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;    
+        }
+    }    
+    return (retVal);
 }
 
 /* FUNCTION PURPOSE: Arbitrates allocation service requests
@@ -493,81 +518,217 @@ errorExit:
  */
 static void allocationHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
 {
-    Rm_AllocatorOpInfo  opInfo;
-    Rm_NameServerObjCfg nameServerObjCfg;
-    int32_t             retVal = transaction->state;
-
+    Rm_AllocatorOpInfo   opInfo;
+    Rm_NameServerObjCfg  nameServerObjCfg;
+    int32_t              retVal = transaction->state;
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+    if (opInfo.serviceSrcInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }        
+                
     if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        /* Fill in allocation logic for CDs */  
-    }
-    else if ((rmInst->instType == Rm_instType_SERVER)||
-             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
-        memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-        
-        opInfo.policy = rmInst->u.server.globalPolicy;
-        opInfo.resourceInfo = &transaction->resourceInfo;
-        opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
-        if (opInfo.serviceSrcInstNode) {
-            /* Populated NameServer name has precedence over base */
-            if (strlen(transaction->resourceInfo.nameServerName) > 0) {
-                if ((transaction->resourceInfo.base == 0) &&
-                    (transaction->resourceInfo.length == 0) &&
-                    (transaction->resourceInfo.alignment == 0)) {
-                    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
-                        rmNameServerTreeInv(rmInst->u.server.nameServer);
-                    }
-                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                    nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
-                    nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
-                    if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
-                        strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
-                        transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
-                        transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
-                    }
-                    else {
-                        goto errorExit;
-                    }
-                }
-                else {
-                    retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
-                    goto errorExit;
-                }
-            }
-
-            if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
+        if (transaction->resourceInfo.base != RM_RESOURCE_BASE_UNSPECIFIED) {
+            if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+                /* Attempt to allocate from local resources that were provided by Server */
                 if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
-                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
                 }
                 else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
-                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
                 }
                 else {
                     retVal = RM_ERROR_INVALID_SERVICE_TYPE;
                     goto errorExit;
                 }
                 retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+                if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                    /* Request resource range was not found within local resources
+                     * provided by Server.  Set back to PROCESSING so request is forwarded to
+                     * Server */
+                    retVal = RM_SERVICE_PROCESSING;
+                }
             }
-        
-            if (retVal == RM_SERVICE_PROCESSING) {
+        }
+        else {
+            if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+                int32_t oldAlign = transaction->resourceInfo.alignment;
+                
+                /* Attempt to allocate from local resources that were provided by Server */
                 if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
-                    opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
                 }
                 else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
-                    opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+                    opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
                 }
                 else {
                     retVal = RM_ERROR_INVALID_SERVICE_TYPE;
                     goto errorExit;
                 }
                 retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
-            }      
+                
+                if (retVal == RM_SERVICE_PROCESSING) {
+                    if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                        opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+                    }
+                    else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+                        opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+                    }
+                    else {
+                        retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                        goto errorExit;
+                    }
+                    retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+                    if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                        /* Request resource range was not found within local resources
+                         * provided by Server.  Set back to PROCESSING so request is forwarded to
+                         * Server */
+                        retVal = RM_SERVICE_PROCESSING;
+                    }                    
+                }
+                else if (retVal == RM_SERVICE_DENIED_RES_ALLOC_REQS_NOT_MET) {
+                    if (transaction->pendingTransactionId) {
+                        /* Request to Server for resources to complete transaction locally
+                         * performed once already.  Forward transaction to Server for completion */
+                        retVal = RM_SERVICE_PROCESSING;
+                    }
+                    else {
+                        /* Restore base and alignment since they were replaced in pre-allocate routine */
+                        transaction->resourceInfo.base = RM_RESOURCE_BASE_UNSPECIFIED;
+                        transaction->resourceInfo.alignment = oldAlign;
+                        
+                        retVal = cdRequestServerResources(rmInst, transaction);
+                    }
+                }
+            }
+            else {
+                retVal = cdRequestServerResources(rmInst, transaction);
+            }                
         }
-        else {
-            retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+    }
+    else if ((rmInst->instType == Rm_instType_SERVER)||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        /* Populated NameServer name has precedence over base */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+            nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+            if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+                strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+            }
+            else {
+                goto errorExit;
+            }
+        }
+
+        if (transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) {
+            if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_INIT;
+            }
+            else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+                opInfo.operation = Rm_allocatorOp_PRE_ALLOCATE_USE;
+            }
+            else {
+                retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                goto errorExit;
+            }
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+        }
+    
+        if (retVal == RM_SERVICE_PROCESSING) {
+            if (transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) {
+                opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+            }
+            else if (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) {
+                opInfo.operation = Rm_allocatorOp_ALLOCATE_USE;
+            }
+            else {
+                retVal = RM_ERROR_INVALID_SERVICE_TYPE;
+                goto errorExit;
+            }
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+        }             
+    }
+errorExit:        
+    transaction->state = retVal;      
+}
+
+/* FUNCTION PURPOSE: Handles resource status service requests
+ ***********************************************************************
+ * DESCRIPTION: Issues a set of allocator operations to retrieve the
+ *              current status (currently just owner reference count)
+ *              for the resource specified in the transaction
+ */
+static void statusHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
+{
+    Rm_AllocatorOpInfo  opInfo;
+    Rm_NameServerObjCfg nameServerObjCfg;
+    int32_t             retVal = transaction->state;
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    opInfo.operation = Rm_allocatorOp_GET_STATUS;
+    opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+    if (opInfo.serviceSrcInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }     
+
+    if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+        ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+         (transaction->resourceInfo.length == 0))) {
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+        goto errorExit;
+    }
+
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+            /* Attempt to get status from local resources that were provided by Server */
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+            if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                /* Request resource range was not found within local allocator resources
+                 * provided by Server.  Set back to PROCESSING so request is forwarded to
+                 * Server */
+                retVal = RM_SERVICE_PROCESSING;
+            }            
         }
+    }
+    else if ((rmInst->instType == Rm_instType_SERVER)||
+             (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        /* Populated NameServer name has precedence over base and length values */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+            nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+            if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+                strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
+            }
+            else {
+                goto errorExit;
+            }
+        }
+        retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);                 
+    }
 errorExit:        
-        transaction->state = retVal;                 
-    }   
+    transaction->state = retVal;       
 }
 
 /* FUNCTION PURPOSE: Arbitrates free service requests
@@ -585,54 +746,65 @@ static void freeHandler (Rm_Inst *rmInst, Rm_Transaction *transaction)
     Rm_AllocatorOpInfo  opInfo; 
     Rm_NameServerObjCfg nameServerObjCfg;    
     int32_t             retVal = transaction->state;
-    
+
+    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+    opInfo.operation = Rm_allocatorOp_FREE;
+    opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    opInfo.resourceInfo = &transaction->resourceInfo;
+    opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
+    if (opInfo.serviceSrcInstNode == NULL) {
+        retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+        goto errorExit;
+    }
+
+    if ((strlen(transaction->resourceInfo.nameServerName) == 0) &&
+        ((transaction->resourceInfo.base == RM_RESOURCE_BASE_UNSPECIFIED) ||
+         (transaction->resourceInfo.length == 0))) {
+        retVal = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+        goto errorExit;
+    }
+
     if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        /* Fill in free logic for CDs */    
+        if (rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+            /* Attempt to free from local resources that were provided by Server */
+            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);
+
+            if (retVal == RM_SERVICE_APPROVED) {
+                /* Check if free allows local resources to be freed back to Server */
+                retVal = cdFreeResourcesToServer(rmInst, transaction);
+            }
+            else if (retVal == RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST) {
+                /* Request resource range was not found within local allocator resources
+                 * provided by Server.  Set back to PROCESSING so request is forwarded to
+                 * Server */
+                retVal = RM_SERVICE_PROCESSING;
+            }  
+        } 
     }
     else if ((rmInst->instType == Rm_instType_SERVER) ||
              (rmInst->instType == Rm_instType_SHARED_SERVER)) {
-        memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
-        
-        opInfo.policy = rmInst->u.server.globalPolicy;
-        opInfo.resourceInfo = &transaction->resourceInfo;
-        opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, transaction->serviceSrcInstName);
-        if (opInfo.serviceSrcInstNode) {
-            /* Populated NameServer name has precedence over base */
-            if (strlen(transaction->resourceInfo.nameServerName) > 0) {
-                if ((transaction->resourceInfo.base == 0) &&
-                    (transaction->resourceInfo.length == 0) &&
-                    (transaction->resourceInfo.alignment == 0)) {
-                    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
-                        rmNameServerTreeInv(rmInst->u.server.nameServer);
-                    }                    
-                    memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
-                    nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
-                    nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
-                    if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
-                        strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
-                        transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
-                        transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
-                    }
-                    else {
-                        goto errorExit;
-                    }
-                }
-                else {
-                    retVal = RM_ERROR_NS_NAME_AND_RES_VAL_CONFLICT;
-                    goto errorExit;
-                }                
+        /* Populated NameServer name has precedence over base */
+        if (strlen(transaction->resourceInfo.nameServerName) > 0) {
+            if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+                rmNameServerTreeInv(rmInst->u.server.nameServer);
+            }                    
+            memset((void *)&nameServerObjCfg, 0, sizeof(Rm_NameServerObjCfg));
+            nameServerObjCfg.nameServerTree = rmInst->u.server.nameServer;
+            nameServerObjCfg.nodeCfg.objName = transaction->resourceInfo.nameServerName;
+            if ((retVal = rmNameServerFindObject(&nameServerObjCfg)) == RM_SERVICE_PROCESSING) {
+                strncpy(transaction->resourceInfo.name, nameServerObjCfg.nodeCfg.resourceName, RM_NAME_MAX_CHARS);
+                transaction->resourceInfo.base = nameServerObjCfg.nodeCfg.resourceBase;
+                transaction->resourceInfo.length = nameServerObjCfg.nodeCfg.resourceLength;
             }
-                 
-            opInfo.operation = Rm_allocatorOp_FREE;
-            retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo); 
-        }
-        else {
-            retVal = RM_SERVICE_DENIED_INST_NAME_NOT_VALID;
+            else {
+                goto errorExit;
+            }             
         }
-
-errorExit:
-        transaction->state = retVal;       
+             
+        retVal = rmAllocatorOperation((Rm_Handle)rmInst, &opInfo);     
     }   
+errorExit:
+    transaction->state = retVal;       
 }
 
 /* FUNCTION PURPOSE: Client transaction handling process
@@ -687,8 +859,10 @@ static void clientProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
  *                    received from registered Clients
  */
 static void cdProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
-{        
-    Rm_Transaction *transQ = rmInst->transactionQueue;    
+{      
+    Rm_Transaction *newTrans = NULL;
+    Rm_Allocator   *allocator = NULL;
+    Rm_Transaction *transQ = rmInst->transactionQueue;
 
     if (!rmInst->registeredWithDelegateOrServer) {
         if ((transaction->state == RM_SERVICE_PROCESSING) &&
@@ -700,10 +874,115 @@ static void cdProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
          * Server is registered */
     }
     else {
+        if (transaction->pendingTransactionId) {
+            Rm_Transaction *pendingTrans = rmTransactionQueueFind(rmInst, transaction->pendingTransactionId);
+            
+            /* Transaction is response from Server for transaction sent to get
+             * information in order to complete pending transaction */
+            if (transaction->state == RM_SERVICE_APPROVED) {
+                if (transaction->type == Rm_service_RESOURCE_GET_BY_NAME) {
+                    /* Transfer resource data tied to name to pending transaction */
+                    strncpy(pendingTrans->resourceInfo.name, transaction->resourceInfo.name, RM_NAME_MAX_CHARS);
+                    pendingTrans->resourceInfo.base = transaction->resourceInfo.base;
+                    pendingTrans->resourceInfo.length = transaction->resourceInfo.length;
+                    /* Delete NS name from pending transaction so Server isn't queried again */
+                    memset(pendingTrans->resourceInfo.nameServerName, 0, RM_NAME_MAX_CHARS);
+                    /* Now that resource values have been retrieved clear pending transaction ID so 
+                     * CD doesn't think a resource request was sent to Server already for more local resources */
+                    pendingTrans->pendingTransactionId = 0;
+
+                    /* Return original transaction to processing state to attempt completion. */
+                    pendingTrans->state = RM_SERVICE_PROCESSING;
+                }
+                else if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+                         (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
+                    /* Add resources provided by Server to those managed by CD */
+                    if (allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name)) {
+                        Rm_ResourceNode *treeNode = NULL;
+                        
+                        treeNode = rmResourceNodeNew(transaction->resourceInfo.base, transaction->resourceInfo.length);
+                        RB_INSERT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, treeNode);
+                    }
+                    else {
+                        Rm_ResourceRange resRange;
+
+                        memset((void *)&resRange, 0, sizeof(resRange));
+                        resRange.base = transaction->resourceInfo.base;
+                        resRange.length = transaction->resourceInfo.length;
+                        
+                        rmAllocatorCreate((Rm_Handle)rmInst, transaction->resourceInfo.name, &resRange);
+                    }
+
+                    /* Return original transaction to processing state to attempt completion */
+                    pendingTrans->state = RM_SERVICE_PROCESSING;
+                }
+                else if (transaction->type == Rm_service_RESOURCE_FREE) {
+                    /* Local resource freed on Server.  Need to remove from local allocator. */
+                    rmAllocatorDeleteNode((Rm_Handle)rmInst, transaction->resourceInfo.name,
+                                          transaction->resourceInfo.base, transaction->resourceInfo.length);                   
+                    
+                    /* Delete the allocator if there are no nodes left in the tree */
+                    allocator = rmAllocatorFind((Rm_Handle)rmInst, transaction->resourceInfo.name);
+                    if (RB_MIN(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry) == NULL) {
+                        rmAllocatorDelete((Rm_Handle)rmInst, transaction->resourceInfo.name);
+                    }   
+
+                    /* Allow original free to complete */
+                    pendingTrans->state = RM_SERVICE_APPROVED;
+                }
+            }
+            else {
+                if (transaction->type == Rm_service_RESOURCE_FREE) {
+                    /* Error occurred when trying to free local resource on Server.  Reinsert local
+                     * resources freed by original request */
+                    Rm_AllocatorOpInfo   opInfo;
+
+                    memset((void *)&opInfo, 0, sizeof(Rm_AllocatorOpInfo));
+                    opInfo.policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+                    opInfo.resourceInfo = &pendingTrans->resourceInfo;
+                    opInfo.serviceSrcInstNode = rmPolicyGetValidInstNode((Rm_Handle)rmInst, pendingTrans->serviceSrcInstName);
+                    /* Can't regain the original type of allocate.  Default to init */
+                    opInfo.operation = Rm_allocatorOp_ALLOCATE_INIT;
+                    if (rmAllocatorOperation((Rm_Handle)rmInst, &opInfo) != RM_SERVICE_APPROVED) {
+                        transaction->state = RM_ERROR_LOST_RESOURCES_ON_CD;
+                    }                    
+                }
+                /* Transfer error or denial to pending transaction */
+                pendingTrans->state = transaction->state;
+            }
+            rmTransactionQueueDelete(rmInst, transaction->localId);
+            /* Switch to pending transaction */
+            transaction = pendingTrans;
+        }
+        
+        if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
+            (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE) ||
+            (transaction->type == Rm_service_RESOURCE_STATUS) ||
+            (transaction->type == Rm_service_RESOURCE_FREE)) {
+            if ((transaction->state == RM_SERVICE_PROCESSING) &&
+                (strlen(transaction->resourceInfo.nameServerName) > 0)) {   
+                /* Create and forward new transaction to Server to
+                 * retrieve resource data mapped to name */
+                if (newTrans = rmTransactionQueueAdd(rmInst)) {
+                    newTrans->type = Rm_service_RESOURCE_GET_BY_NAME;
+                    strncpy(newTrans->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS);
+                    newTrans->state = RM_SERVICE_PROCESSING;       
+                    strncpy(newTrans->resourceInfo.nameServerName, transaction->resourceInfo.nameServerName, 
+                            RM_NAME_MAX_CHARS);
+                    newTrans->pendingTransactionId = transaction->localId;
+                    transactionForwarder(rmInst, newTrans);
+
+                    transaction->state = RM_SERVICE_PENDING_SERVER_RESPONSE;
+                }
+                else {
+                    transaction->state = RM_ERROR_TRANS_REQ_TO_SERVER_NOT_CREATED;    
+                }        
+            }                
+        }
+
         if ((transaction->type == Rm_service_RESOURCE_ALLOCATE_INIT) ||
             (transaction->type == Rm_service_RESOURCE_ALLOCATE_USE)) {
-            if ((transaction->state == RM_SERVICE_PROCESSING) ||
-                (transaction->state == RM_SERVICE_APPROVED_STATIC)) {   
+            if (transaction->state == RM_SERVICE_PROCESSING) {   
                 allocationHandler(rmInst, transaction);
             }
         }
@@ -723,7 +1002,7 @@ static void cdProcess (Rm_Inst *rmInst, Rm_Transaction *transaction)
             /* CD could not complete transaction.  Forward to Server */
             transactionForwarder(rmInst, transaction);
         }
-        else {
+        else if (transaction->state != RM_SERVICE_PENDING_SERVER_RESPONSE) {
             /* Transaction completed by CD or completed response received from Server.  Return result */
             if (strncmp(transaction->serviceSrcInstName, rmInst->instName, RM_NAME_MAX_CHARS)) {
                 /* Transaction did not originate on this instance */
@@ -945,11 +1224,11 @@ void rmProcessRouter (Rm_Inst *rmInst, Rm_Transaction *transaction)
  *              instance network.  Also, prints the NameServer name
  *              entries.  The number of resource range owners is
  *              returned as well.  This function is only available on
- *              server instances.
+ *              Server and CD instances.
  */
-int32_t Rm_resourceStatus(Rm_Handle rmServerHandle, int printResources)
+int32_t Rm_resourceStatus(Rm_Handle rmHandle, int printResources)
 {
-    Rm_Inst         *rmInst = (Rm_Inst *)rmServerHandle;
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
     Rm_Allocator    *allocator = NULL;
     Rm_Owner        *owners;
     Rm_ResourceTree *treeRoot;
@@ -960,14 +1239,39 @@ int32_t Rm_resourceStatus(Rm_Handle rmServerHandle, int printResources)
     RM_SS_INST_INV_ENTER_CS(key);
     RM_SC_INST_INV_ENTER_CS(key);
 
+    if (rmInst->instType != Rm_instType_CLIENT) {
+        Rm_osalLog("Instance name: %s\n", rmInst->instName);
+        Rm_osalLog("Handle: 0x%08x\n", rmHandle);    
+        if (rmInst->instType == Rm_instType_SERVER) {
+            Rm_osalLog("Type:   Server\n");
+        }
+        else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+            Rm_osalLog("Type:   Client Delegate\n");
+        }
+        else if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+            Rm_osalLog("Type:   Shared Server\n");
+        }
+        else if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
+            Rm_osalLog("Type:   Shared Client\n");
+        }
+
+        Rm_osalLog("\nResource Status:\n\n");
+    }
+
     if (rmInst->instType == Rm_instType_SHARED_CLIENT) {
         /* Transfer control to shared server instance */
         rmInst = rmInst->u.sharedClient.sharedServerHandle;
     }
 
     if ((rmInst->instType == Rm_instType_SERVER) ||
-        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
-        allocator = rmInst->u.server.allocators;
+        (rmInst->instType == Rm_instType_SHARED_SERVER) ||
+        (rmInst->instType == Rm_instType_CLIENT_DELEGATE)) {
+        allocator = rmAllocatorGetAllocatorList(rmHandle);
+        
+        if (!allocator) {
+            Rm_osalLog("No resources managed by instance at the moment\n\n");
+        }
+        
         while (allocator) {
             RM_SS_OBJ_INV(allocator, Rm_Allocator);
             if (printResources) {
@@ -1014,8 +1318,12 @@ int32_t Rm_resourceStatus(Rm_Handle rmServerHandle, int printResources)
             }        
             allocator = allocator->nextAllocator; 
         }
-        if (printResources) {
-            rmNameServerPrintObjects((Rm_Handle)rmInst);
+        
+        if ((rmInst->instType == Rm_instType_SERVER) ||
+            (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+            if (printResources) {
+                rmNameServerPrintObjects((Rm_Handle)rmInst);
+            }
         }
     }
     else {
@@ -1207,19 +1515,22 @@ Rm_Handle Rm_init(const Rm_InitCfg *initCfg, int32_t *result)
         }
     }
     else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        if (initCfg->instCfg.cdCfg.cdPolicy) {
-            rmInst->u.cd.cdPolicy = initCfg->instCfg.cdCfg.cdPolicy;
-            rmInst->u.cd.cdValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);        
-            if (*result == RM_OK) {
-                *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
-            }
+        if (!initCfg->instCfg.cdCfg.cdPolicy) {
+            *result = RM_ERROR_INVALID_CD_CONFIGURATION;
+            goto errorExit;
+        }        
 
-            if (*result != RM_OK) {
-                if (rmInst->u.cd.cdValidInstTree) {
-                    rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
-                }
-                goto errorExit;
+        rmInst->u.cd.cdPolicy = initCfg->instCfg.cdCfg.cdPolicy;
+        rmInst->u.cd.cdValidInstTree = rmPolicyCreateValidInstTree((Rm_Handle)rmInst, addLinux, result);        
+        if (*result == RM_OK) {
+            *result = rmPolicyValidatePolicy((Rm_Handle)rmInst);
+        }
+
+        if (*result != RM_OK) {
+            if (rmInst->u.cd.cdValidInstTree) {
+                rmPolicyFreeValidInstTree((Rm_Handle)rmInst);
             }
+            goto errorExit;
         }
 
         rmInst->u.cd.allocators = NULL;
index 0795db7fbfd76573d4ecf8b4a324832c2ec284f2..b36dd37a657d495d4fb11b2466886b6ac0a9b31c 100644 (file)
@@ -71,7 +71,7 @@
 static Rm_Allocator *allocatorAdd(Rm_Handle rmHandle, const char *resourceName)
 {
     Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;
-    Rm_Allocator *allocators   = rmInst->u.server.allocators;
+    Rm_Allocator *allocators   = rmAllocatorGetAllocatorList(rmHandle);
     Rm_Allocator *newAllocator = NULL;
 
     newAllocator = Rm_osalMalloc(sizeof(*allocators));
@@ -91,112 +91,18 @@ static Rm_Allocator *allocatorAdd(Rm_Handle rmHandle, const char *resourceName)
             RM_SS_OBJ_WB(allocators, Rm_Allocator);
         }
         else {
-            rmInst->u.server.allocators = newAllocator;
+            if ((rmInst->instType == Rm_instType_SERVER) ||
+                (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+                rmInst->u.server.allocators = newAllocator;
+            }
+            else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+                rmInst->u.cd.allocators = newAllocator;
+            }            
         }
     }
     return (newAllocator);
 }
 
-/* FUNCTION PURPOSE: Creates a new resource tree
- ***********************************************************************
- * DESCRIPTION: Creates and populates a new resource tree allocator
- *              using the provided resource name and value range.  The
- *              name and value originate from the GRL.
- */
-static int32_t allocatorCreate(Rm_Handle rmHandle, const char *resourceName, Rm_ResourceRange *range)
-{
-    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
-    Rm_Allocator    *allocator = NULL;
-    Rm_ResourceTree *treeRoot = NULL;
-    Rm_ResourceNode *treeNode = NULL;
-
-    allocator = allocatorAdd(rmHandle, resourceName);
-    treeRoot = Rm_osalMalloc(sizeof(*treeRoot));
-    RB_INIT(treeRoot);
-
-    while (range != NULL) {
-        treeNode = rmResourceNodeNew(range->base, range->length);
-        RB_INSERT(_Rm_AllocatorResourceTree, treeRoot, treeNode);
-        range = range->nextRange;
-    }
-    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
-        rmResourceTreeWb(treeRoot);
-    }
-    
-    allocator->allocatorRootEntry = treeRoot;
-    RM_SS_OBJ_WB(allocator, Rm_Allocator);
-    return(RM_OK);
-}
-
-/* FUNCTION PURPOSE: Returns a pointer to the allocator list
- ***********************************************************************
- * DESCRIPTION: Returns a pointer to the instance's allocator list
- *              based on the instance type
- */
-static Rm_Allocator *allocatorGetAllocatorList(Rm_Handle rmHandle)
-{
-    Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;
-    Rm_Allocator *list = NULL;
-
-    if ((rmInst->instType == Rm_instType_SERVER) ||
-        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
-        list = rmInst->u.server.allocators;
-    }
-    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
-        list = rmInst->u.cd.allocators;
-    }
-    return(list);
-}
-
-/* FUNCTION PURPOSE: Deletes a resource allocator
- ***********************************************************************
- * DESCRIPTION: Deletes a resource allocator based on the given
- *              resource name.  The resource allocator will be
- *              removed from the RM instance allocator list.
- */
-static int32_t allocatorDelete(Rm_Handle rmHandle, const char *resourceName)
-{
-    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;    
-    Rm_Allocator    *allocator = rmInst->u.server.allocators;
-    Rm_Allocator    *prevAllocator = NULL;
-    Rm_ResourceTree *treeRoot;
-    Rm_ResourceNode *node = NULL;
-    Rm_ResourceNode *nextNode = NULL;
-    int32_t          retVal = RM_OK;
-
-    while (allocator) {
-        if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
-            break;             
-        }
-        prevAllocator = allocator;
-        allocator = allocator->nextAllocator;
-    }
-
-    if (allocator) {
-        if (prevAllocator == NULL) {
-            rmInst->u.server.allocators = allocator->nextAllocator;
-        }
-        else {
-            prevAllocator->nextAllocator = allocator->nextAllocator;
-            RM_SS_OBJ_WB(prevAllocator, Rm_Allocator);
-        }
-            
-        /* Destroy tree and return error */
-        treeRoot = allocator->allocatorRootEntry;
-        for (node = RB_MIN(_Rm_AllocatorResourceTree, treeRoot); node != NULL; node = nextNode) {
-               nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRoot, node);
-               RB_REMOVE(_Rm_AllocatorResourceTree, treeRoot, nextNode);
-            rmResourceNodeFree(node);
-        }
-        Rm_osalFree((void *)treeRoot, sizeof(*treeRoot));        
-        Rm_osalFree((void *)allocator, sizeof(*allocator));
-    }
-    else {
-        retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
-    }
-    return (retVal);
-}
-
 /* FUNCTION PURPOSE: Adds an owner to an allocator resource
  ***********************************************************************
  * DESCRIPTION: Adds a RM instance node to a resource node's
@@ -235,6 +141,31 @@ static void allocatorResNodeOwnerAdd(Rm_Handle rmHandle, Rm_ResourceNode *node,
     }
 }
 
+/* FUNCTION PURPOSE: Compares two resource node's boundaries
+ ***********************************************************************
+ * DESCRIPTION: Returns TRUE if the resource nodes are neighbors from
+ *              a base+length perspective.  Otherwise, returns FALSE.
+ */
+static int allocatorResNodeBoundaryCompare(Rm_ResourceNode *node1, Rm_ResourceNode *node2)
+{
+    uint32_t node1End = node1->base + node1->length - 1;
+    uint32_t node2End = node2->base + node2->length - 1;
+
+    if (node1 && node2) {
+        if (node1->base < node2->base) {
+            if (node1End == (node2->base - 1)) {
+                return(RM_TRUE);
+            }
+        }
+        else if (node2->base < node1->base) {
+            if (node2End == (node1->base - 1)) {
+                return(RM_TRUE);
+            }     
+        }
+    }
+    return(RM_FALSE);
+}
+
 /* FUNCTION PURPOSE: Compares two resource node's owners
  ***********************************************************************
  * DESCRIPTION: Returns TRUE if the owners of two resource nodes 
@@ -412,7 +343,9 @@ static int allocatorResNodeIsOwnedBy(Rm_Handle rmHandle, Rm_ResourceNode *node,
 static int32_t allocatorStatus(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opInfo)
 {
     Rm_ResourceNode  findNode;
-    Rm_ResourceNode *matchingNode = NULL;  
+    Rm_ResourceNode *matchingNode = NULL; 
+    uint32_t         matchingEnd;
+    uint32_t         findEnd;    
     int32_t          retVal;
 
     memset((void *)&findNode, 0, sizeof(findNode));
@@ -421,8 +354,15 @@ static int32_t allocatorStatus(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opIn
     matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
 
     if (matchingNode) {
-        opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
-        retVal = RM_SERVICE_APPROVED;
+        matchingEnd = matchingNode->base + matchingNode->length - 1;
+        findEnd = findNode.base + findNode.length - 1;
+        if ((findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {        
+            opInfo->resourceInfo->ownerCount = matchingNode->allocationCount;
+            retVal = RM_SERVICE_APPROVED;
+        }
+        else {
+            retVal = RM_SERVICE_DENIED_PARTIAL_STATUS;
+        }
     }
     else {
         retVal = RM_SERVICE_DENIED_RES_RANGE_DOES_NOT_EXIST;
@@ -443,15 +383,17 @@ static int32_t allocatorStatus(Rm_Allocator *allocator, Rm_AllocatorOpInfo *opIn
 static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, int32_t resourcePolicy, 
                                     Rm_AllocatorOpInfo *opInfo)
 {   
+    Rm_Inst           *rmInst = (Rm_Inst *)rmHandle;
     Rm_ResourceNode    findNode;
     Rm_ResourceNode   *matchingNode = NULL;
     uint32_t           matchingEnd;
+    uint32_t           findEnd;
     uint32_t           rangeIndex;
     int                resourceFound = RM_FALSE;
     Rm_PolicyCheckType policyCheckType;
     Rm_PolicyCheckCfg  policyCheckCfg;
     int                nodePassesPolicy;
-    int32_t            retVal;
+    int32_t            retVal = RM_OK;
 
     if (opInfo->operation == Rm_allocatorOp_PRE_ALLOCATE_INIT) {
         policyCheckType = Rm_policyCheck_INIT;
@@ -463,10 +405,18 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
         retVal = RM_ERROR_INVALID_SERVICE_TYPE;
         return (retVal);
     }
+
+    if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        /* Set base to first node's base since CD will not have all resources like Server */
+        matchingNode = RB_MIN(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry);
+        opInfo->resourceInfo->base = matchingNode->base;
+    }
+    else {
+        opInfo->resourceInfo->base = rmPolicyGetResourceBase(opInfo->policy, opInfo->serviceSrcInstNode, 
+                                                             resourcePolicy, policyCheckType, 
+                                                             &retVal);
+    }
     
-    opInfo->resourceInfo->base = rmPolicyGetResourceBase(opInfo->policy, opInfo->serviceSrcInstNode, 
-                                                         resourcePolicy, policyCheckType, 
-                                                         &retVal);
     if (retVal != RM_OK) {
         return (retVal);
     }
@@ -493,8 +443,12 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
         matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
         
         if (matchingNode) {
-            if (matchingNode->allocationCount == 0) {
-                /* Attempt to preallocate from node only if not owned by anyone */
+            matchingEnd = matchingNode->base + matchingNode->length - 1;
+            findEnd = findNode.base + findNode.length - 1;
+            if ((matchingNode->allocationCount == 0) &&
+                (findNode.base >= matchingNode->base) && (findEnd <= matchingEnd)) {
+                /* Attempt to preallocate from node only if not owned by anyone and sits
+                 * within a matching node. */
                 nodePassesPolicy = RM_FALSE;
                 policyCheckCfg.type = policyCheckType;
                 policyCheckCfg.validInstNode = opInfo->serviceSrcInstNode;
@@ -532,8 +486,7 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
                 }
 
                 if (nodePassesPolicy) {
-                    matchingEnd = matchingNode->base + matchingNode->length - 1;
-                    /* Initialize indexer to be first resource value that alignment */
+                    /* Initialize indexer to be first resource value that alignment satisfies */
                     rangeIndex = findNode.base;
                     if (rangeIndex % opInfo->resourceInfo->alignment) {
                         rangeIndex += (opInfo->resourceInfo->alignment -
@@ -552,7 +505,12 @@ static int32_t allocatorPreAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator,
             
             if (!resourceFound) {
                 /* Check next resource node for available resources */
-                findNode.base = matchingNode->base + matchingNode->length;
+                if (findNode.base < matchingNode->base) {
+                    findNode.base = matchingNode->base;
+                }
+                else {
+                    findNode.base = matchingNode->base + matchingNode->length;
+                }
             }
         }
         else {
@@ -687,11 +645,13 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
                         RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                         allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
 
-                        if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode)) {
+                        if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+                            allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
                             RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
                             combineLeft = RM_TRUE;
                         }
-                        if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode)) {
+                        if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+                            allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
                             RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
                             combineRight = RM_TRUE;
                         }
@@ -781,7 +741,8 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
                             /* Add allocating instance to owner list for compare with leftNode */
                             allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
                             
-                            if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode)) {
+                            if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+                                allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
                                 RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
                                 /* Combine leftNode and findNode */
                                 leftNode->length += findNode.length;
@@ -811,7 +772,8 @@ static int32_t allocatorAllocate(Rm_Handle rmHandle, Rm_Allocator *allocator, in
                             /* Add allocating instance to owner list for compare with rightNode */
                             allocatorResNodeOwnerAdd(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
                             
-                            if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode)) {
+                            if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+                                allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
                                 RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
                                 /* Combine rightNode and findNode */
                                 rightNode->base = findNode.base;
@@ -897,11 +859,13 @@ static int32_t allocatorFree(Rm_Handle rmHandle, Rm_Allocator *allocator, Rm_All
                         RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
                         allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
 
-                        if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode)) {
+                        if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+                            allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
                             RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
                             combineLeft = RM_TRUE;
                         }
-                        if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode)) {
+                        if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+                            allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
                             RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
                             combineRight = RM_TRUE;
                         }
@@ -997,7 +961,8 @@ static int32_t allocatorFree(Rm_Handle rmHandle, Rm_Allocator *allocator, Rm_All
                             /* Remove freeing instance from owner list for compare with leftNode */
                             allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
                             
-                            if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode)) {
+                            if (leftNode && allocatorResNodeOwnerCompare(rmHandle, leftNode, matchingNode) &&
+                                allocatorResNodeBoundaryCompare(leftNode, matchingNode)) {
                                 RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, leftNode);
                                 /* Combine leftNode and findNode */
                                 leftNode->length += findNode.length;
@@ -1028,7 +993,8 @@ static int32_t allocatorFree(Rm_Handle rmHandle, Rm_Allocator *allocator, Rm_All
                             /* Remove freeing instance from owner list for compare with rightNode */
                             allocatorResNodeOwnerDelete(rmHandle, matchingNode, opInfo->serviceSrcInstNode);
                             
-                            if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode)) {
+                            if (rightNode && allocatorResNodeOwnerCompare(rmHandle, rightNode, matchingNode) &&
+                                allocatorResNodeBoundaryCompare(rightNode, matchingNode)) {
                                 RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, rightNode);
                                 /* Combine rightNode and findNode */
                                 rightNode->base = findNode.base;
@@ -1248,7 +1214,7 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
         range = rangeBasePtr = rmDtbUtilResExtractRange(resourceProperties->rangeData, 
                                                         resourceProperties->rangeLen);
         
-        if ((retVal = allocatorCreate(rmHandle, resourceName, range)) >= RM_OK) {
+        if ((retVal = rmAllocatorCreate(rmHandle, resourceName, range)) >= RM_OK) {
             if (resourceProperties->linuxAliasData && resourceProperties->linuxAliasLen) {
                 if (linuxDtb) {
                     linuxAlias = rmDtbUtilResExtractLinuxAlias(resourceProperties->linuxAliasData,
@@ -1288,7 +1254,7 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
         }
     }
     else {
-        allocatorDelete(rmHandle, resourceName);
+        rmAllocatorDelete(rmHandle, resourceName);
     }
 
     rmDtbUtilResFreeRange(rangeBasePtr);
@@ -1302,6 +1268,57 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
  ********************** Internal Functions ****************************
  **********************************************************************/
 
+/* FUNCTION PURPOSE: Creates a new resource tree
+ ***********************************************************************
+ * DESCRIPTION: Creates and populates a new resource tree allocator
+ *              using the provided resource name and value range.  The
+ *              name and value originate from the GRL.
+ */
+int32_t rmAllocatorCreate(Rm_Handle rmHandle, const char *resourceName, Rm_ResourceRange *range)
+{
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Allocator    *allocator = NULL;
+    Rm_ResourceTree *treeRoot = NULL;
+    Rm_ResourceNode *treeNode = NULL;
+
+    allocator = allocatorAdd(rmHandle, resourceName);
+    treeRoot = Rm_osalMalloc(sizeof(*treeRoot));
+    RB_INIT(treeRoot);
+
+    while (range != NULL) {
+        treeNode = rmResourceNodeNew(range->base, range->length);
+        RB_INSERT(_Rm_AllocatorResourceTree, treeRoot, treeNode);
+        range = range->nextRange;
+    }
+    if (rmInst->instType == Rm_instType_SHARED_SERVER) {
+        rmResourceTreeWb(treeRoot);
+    }
+    
+    allocator->allocatorRootEntry = treeRoot;
+    RM_SS_OBJ_WB(allocator, Rm_Allocator);
+    return(RM_OK);
+}
+
+/* FUNCTION PURPOSE: Returns a pointer to the allocator list
+ ***********************************************************************
+ * DESCRIPTION: Returns a pointer to the instance's allocator list
+ *              based on the instance type
+ */
+Rm_Allocator *rmAllocatorGetAllocatorList(Rm_Handle rmHandle)
+{
+    Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;
+    Rm_Allocator *list = NULL;
+
+    if ((rmInst->instType == Rm_instType_SERVER) ||
+        (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+        list = rmInst->u.server.allocators;
+    }
+    else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+        list = rmInst->u.cd.allocators;
+    }
+    return(list);
+}
+
 /* FUNCTION PURPOSE: Finds an allocator
  ***********************************************************************
  * DESCRIPTION: Returns a pointer to an allocator that matches the 
@@ -1310,7 +1327,7 @@ static int32_t allocatorExtractGrlResProps(Rm_Handle rmHandle, const char *resou
 Rm_Allocator *rmAllocatorFind(Rm_Handle rmHandle, const char *resourceName)
 {
     Rm_Inst      *rmInst = (Rm_Inst *)rmHandle;
-    Rm_Allocator *allocatorList = rmInst->u.server.allocators;
+    Rm_Allocator *allocatorList = rmAllocatorGetAllocatorList(rmHandle);
     
     while (allocatorList) {
         RM_SS_OBJ_INV(allocatorList, Rm_Allocator);
@@ -1323,6 +1340,75 @@ Rm_Allocator *rmAllocatorFind(Rm_Handle rmHandle, const char *resourceName)
     return (allocatorList);
 }
 
+/* FUNCTION PURPOSE: Checks if a resource node is localized
+ ***********************************************************************
+ * DESCRIPTION: Checks if a resource node is localized.  A localized
+ *              node is one that is free and has no neighboring nodes
+ *              or neighboring nodes that do not have resource values
+ *              contiguous with the node being checked.  The function
+ *              will return RM_TRUE is the node is localized.  
+ *              Otherwise, the function returns RM_FALSE
+ */
+int rmAllocatorGetNodeLocalization(Rm_Handle rmHandle, char *resourceName, 
+                                   int32_t *resBase, uint32_t *resLen)
+{
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
+    void *           policy = rmPolicyGetPolicy((Rm_Handle)rmInst);
+    int32_t          resOffsetInPolicy = rmPolicyGetResourceOffset(policy, resourceName);
+    uint32_t         allocSize = rmPolicyGetResourceAllocSize(policy, resOffsetInPolicy);    
+    Rm_Allocator    *allocator = rmAllocatorFind(rmHandle, resourceName);
+    Rm_ResourceNode  findNode;
+    Rm_ResourceNode *matchingNode = NULL;
+    Rm_ResourceNode *neighborNode = NULL;   
+    int              nodeIsLocalized;
+
+    memset((void *)&findNode, 0, sizeof(findNode));
+    findNode.base = *resBase;
+    findNode.length = *resLen;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+
+    if (matchingNode) {
+        /* Node can be freed back to Server from CD if:
+         * - allocationCount == 0
+         * - node's resource range is multiple of policy allocation size
+         * - node's resource range boundaries are not contiguous with surrounding nodes */
+        if (matchingNode->allocationCount) {
+            nodeIsLocalized = RM_FALSE;
+            goto exitLocalization;
+        }
+            
+        if (matchingNode->length % allocSize) {
+            nodeIsLocalized = RM_FALSE;
+            goto exitLocalization;        
+        }
+
+        /* Check left neighbor */
+        neighborNode = RB_PREV(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+        if (neighborNode && allocatorResNodeBoundaryCompare(neighborNode, matchingNode)) {
+            nodeIsLocalized = RM_FALSE;
+            goto exitLocalization; 
+        }
+
+        /* Check right neighbor */
+        neighborNode = RB_NEXT(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+        if (neighborNode && allocatorResNodeBoundaryCompare(neighborNode, matchingNode)) {
+            nodeIsLocalized = RM_FALSE;
+            goto exitLocalization; 
+        }
+
+        /* All localization checks passed.  Return the base and length of localized node. */
+        nodeIsLocalized = RM_TRUE;
+        *resBase = matchingNode->base;
+        *resLen = matchingNode->length;
+    }
+    else {
+        nodeIsLocalized = RM_FALSE;
+    }
+
+exitLocalization:
+    return (nodeIsLocalized);
+}
+
 /* FUNCTION PURPOSE: Issues an allocator operation
  ***********************************************************************
  * DESCRIPTION: Issues an allocator preallocate, allocate, or free
@@ -1446,6 +1532,83 @@ exitAllocInit:
     return(retVal);
 }
 
+/* FUNCTION PURPOSE: Deletes a resource allocator resource node
+ ***********************************************************************
+ * DESCRIPTION: Deletes a resource allocator's node based on the given
+ *              resource name, base and length.
+ */
+void rmAllocatorDeleteNode(Rm_Handle rmHandle, const char *resName, int32_t resBase, uint32_t resLen)
+{
+    Rm_Allocator    *allocator = rmAllocatorFind(rmHandle, resName);
+    Rm_ResourceNode  findNode;
+    Rm_ResourceNode *matchingNode;
+
+    memset((void *)&findNode, 0, sizeof(findNode));
+    findNode.base = resBase;
+    findNode.length = resLen;
+    matchingNode = RB_FIND(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, &findNode);
+    
+    if (matchingNode) {
+        RB_REMOVE(_Rm_AllocatorResourceTree, allocator->allocatorRootEntry, matchingNode);
+        rmResourceNodeFree(matchingNode);
+    }
+}
+
+/* FUNCTION PURPOSE: Deletes a resource allocator
+ ***********************************************************************
+ * DESCRIPTION: Deletes a resource allocator based on the given
+ *              resource name.  The resource allocator will be
+ *              removed from the RM instance allocator list.
+ */
+int32_t rmAllocatorDelete(Rm_Handle rmHandle, const char *resourceName)
+{
+    Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;    
+    Rm_Allocator    *allocator = rmAllocatorGetAllocatorList(rmHandle);
+    Rm_Allocator    *prevAllocator = NULL;
+    Rm_ResourceTree *treeRoot;
+    Rm_ResourceNode *node = NULL;
+    Rm_ResourceNode *nextNode = NULL;
+    int32_t          retVal = RM_OK;
+
+    while (allocator) {
+        if (strncmp(allocator->resourceName, resourceName, RM_NAME_MAX_CHARS) == 0) {
+            break;             
+        }
+        prevAllocator = allocator;
+        allocator = allocator->nextAllocator;
+    }
+
+    if (allocator) {
+        if (prevAllocator == NULL) {
+            if ((rmInst->instType == Rm_instType_SERVER) ||
+                (rmInst->instType == Rm_instType_SHARED_SERVER)) {
+                rmInst->u.server.allocators = allocator->nextAllocator;
+            }
+            else if (rmInst->instType == Rm_instType_CLIENT_DELEGATE) {
+                rmInst->u.cd.allocators = allocator->nextAllocator;
+            }              
+        }
+        else {
+            prevAllocator->nextAllocator = allocator->nextAllocator;
+            RM_SS_OBJ_WB(prevAllocator, Rm_Allocator);
+        }
+            
+        /* Destroy tree and return error */
+        treeRoot = allocator->allocatorRootEntry;
+        for (node = RB_MIN(_Rm_AllocatorResourceTree, treeRoot); node != NULL; node = nextNode) {
+               nextNode = RB_NEXT(_Rm_AllocatorResourceTree, treeRoot, node);
+               RB_REMOVE(_Rm_AllocatorResourceTree, treeRoot, nextNode);
+            rmResourceNodeFree(node);
+        }
+        Rm_osalFree((void *)treeRoot, sizeof(*treeRoot));        
+        Rm_osalFree((void *)allocator, sizeof(*allocator));
+    }
+    else {
+        retVal = RM_ERROR_RES_ALLOCATOR_DOES_NOT_EXIST;
+    }
+    return (retVal);
+}
+
 /* FUNCTION PURPOSE: Deletes server allocators
  ***********************************************************************
  * DESCRIPTION: Removes all resource nodes for each
@@ -1456,7 +1619,7 @@ exitAllocInit:
 void rmAllocatorDeleteResources(Rm_Handle rmHandle)
 {
     Rm_Inst         *rmInst = (Rm_Inst *)rmHandle;
-    Rm_Allocator    *allocatorList = allocatorGetAllocatorList(rmHandle);
+    Rm_Allocator    *allocatorList = rmAllocatorGetAllocatorList(rmHandle);
     Rm_Allocator    *nextAllocator;
     Rm_ResourceTree *resTree;
     Rm_ResourceNode *resNode;
index 63f1dc0e1cd136aa9639a7aafd1aa8fe894a6a8f..cdd815ff75bfcc7bc38c42f0a195742e6a02bf65 100644 (file)
@@ -731,9 +731,8 @@ uint32_t rmPolicyGetResourceBase(void *policyDtb, Rm_PolicyValidInstNode *validI
 
 /* FUNCTION PURPOSE: Returns resource alignment value according to the Policy
  ***********************************************************************
- * DESCRIPTION: Returns a resource alignment value based on the resource
- *              alignment assigned to the specified valid instance by the
- *              Policy DTB.
+ * DESCRIPTION: Parses the policy DTB to find and return a resource's 
+ *              alignment.
  */
 uint32_t rmPolicyGetResourceAlignment(void *policyDtb, int32_t resourceOffset)
 {
@@ -759,6 +758,36 @@ uint32_t rmPolicyGetResourceAlignment(void *policyDtb, int32_t resourceOffset)
     return(resourceAlignment);
 }
 
+/* FUNCTION PURPOSE: Returns resource allocation size according to the Policy
+ ***********************************************************************
+ * DESCRIPTION: Parses the policy DTB to find and return a resource's 
+ *              allocation size.
+ */
+uint32_t rmPolicyGetResourceAllocSize(void *policyDtb, int32_t resourceOffset)
+{
+    int32_t            propertyOffset;
+    const char        *propertyName;
+    int32_t            propertyLen;
+    const void        *propertyData;
+    Rm_ResourceValue  *allocSizeList;
+    uint32_t           resourceAllocSize = 0;
+
+    propertyOffset = fdt_first_property_offset(policyDtb, resourceOffset);
+    if (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+        while (propertyOffset > RM_DTB_UTIL_STARTING_NODE_OFFSET) {
+            propertyData = fdt_getprop_by_offset(policyDtb, propertyOffset, &propertyName, &propertyLen);
+            if (rmDtbUtilPolicyGetPropertyType(propertyName) == Rm_policyPropType_ALLOCATION_SIZE) {
+                allocSizeList = rmDtbUtilPolicyExtractAllocationSizes(propertyData, propertyLen);
+                resourceAllocSize = allocSizeList->value;                
+                rmDtbUtilPolicyFreeAllocationSizes(allocSizeList);
+            }
+            propertyOffset = fdt_next_property_offset(policyDtb, propertyOffset);
+        }
+    }
+    return(resourceAllocSize);
+}
+
+
 /* FUNCTION PURPOSE: Get a resource's offset into a Policy
  ***********************************************************************
  * DESCRIPTION: Returns the location of the specified resource node
@@ -772,24 +801,29 @@ int32_t rmPolicyGetResourceOffset(void *policyDtb, char *resourceName)
     int32_t     depth;
     const char *nodeName;
 
-    depth = RM_DTB_UTIL_STARTING_DEPTH;
-    nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;       
+    if (policyDtb) {
+        depth = RM_DTB_UTIL_STARTING_DEPTH;
+        nodeOffset = RM_DTB_UTIL_STARTING_NODE_OFFSET;       
 
-    /* Find node offset for provided resource name */
-    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);
+        /* Find node offset for provided resource name */
+        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);
 
-        if (strncmp(nodeName, resourceName, RM_NAME_MAX_CHARS) == 0)
-        {
-            break;
+            if (strncmp(nodeName, resourceName, RM_NAME_MAX_CHARS) == 0)
+            {
+                break;
+            }
         }
-    }
 
-    if (depth < RM_DTB_UTIL_STARTING_DEPTH) {
-        /* Resource name not found */
-        nodeOffset = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+        if (depth < RM_DTB_UTIL_STARTING_DEPTH) {
+            /* Resource name not found */
+            nodeOffset = RM_SERVICE_DENIED_RES_DOES_NOT_EXIST;
+        }
+    }
+    else {
+        nodeOffset = RM_ERROR_INSTANCE_HAS_NO_POLICY;
     }
     return(nodeOffset);
 }
index 3c1ce652399fcf7dcb0ad45d5bb4282e7a649ff5..d0036f82ee3fe4455642c09f82cdae3061bb089e 100644 (file)
@@ -159,7 +159,8 @@ void Rm_serviceHandler (void *rmHandle, const Rm_ServiceReqInfo *serviceRequest,
              * it will be RM_RESOURCE_NUM_OWNERS_INVALID */
             serviceResponse->resourceNumOwners = transaction->resourceInfo.ownerCount;
             if ((serviceResponse->serviceState == RM_SERVICE_PROCESSING) ||
-                (serviceResponse->serviceState == RM_SERVICE_APPROVED_STATIC)) {
+                (serviceResponse->serviceState == RM_SERVICE_APPROVED_STATIC) ||
+                (serviceResponse->serviceState == RM_SERVICE_PENDING_SERVER_RESPONSE)) {
                 /* Service still being processed.  Static requests will have their validation responses sent once
                  * all transports have been established.  Provide transaction ID back to component so it can sort 
                  * service responses received via callback function */
@@ -176,7 +177,8 @@ void Rm_serviceHandler (void *rmHandle, const Rm_ServiceReqInfo *serviceRequest,
             /* Transactions still processing not deleted from queue including static transactions which will be 
              * verified once all transports are up */
             if ((serviceResponse->serviceState != RM_SERVICE_PROCESSING) &&
-                (serviceResponse->serviceState != RM_SERVICE_APPROVED_STATIC)) {
+                (serviceResponse->serviceState != RM_SERVICE_APPROVED_STATIC) &&
+                (serviceResponse->serviceState != RM_SERVICE_PENDING_SERVER_RESPONSE)) {
                 rmTransactionQueueDelete(rmInst, transaction->localId);
             }
         }
index 00621c27ebc9bdd9519567beddaa1b8d9130b3ef..15a4f6b5462588efaabd1f5a789af3bc17b9a0b9 100644 (file)
@@ -8,7 +8,7 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x0a,
-0xa1,
+0xc1,
 0x00,
 0x00,
 0x00,
@@ -16,7 +16,7 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x0a,
-0x70,
+0x80,
 0x00,
 0x00,
 0x00,
@@ -36,11 +36,11 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x00,
-0x31,
+0x41,
 0x00,
 0x00,
 0x0a,
-0x38,
+0x48,
 0x00,
 0x00,
 0x00,
@@ -1420,6 +1420,22 @@ const char rmGlobalPolicy[] = {
 0x00,
 0x00,
 0x00,
+0x03,
+0x00,
+0x00,
+0x00,
+0x04,
+0x00,
+0x00,
+0x00,
+0x31,
+0x00,
+0x00,
+0x00,
+0x10,
+0x00,
+0x00,
+0x00,
 0x02,
 0x00,
 0x00,
@@ -2722,37 +2738,21 @@ const char rmGlobalPolicy[] = {
 0x6e,
 0x74,
 0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
+0x61,
+0x6c,
+0x6c,
+0x6f,
+0x63,
+0x61,
+0x74,
+0x69,
+0x6f,
+0x6e,
+0x2d,
+0x73,
+0x69,
+0x7a,
+0x65,
 0x00,
 0x00,
 0x00,
index eba8c6b40ade9e78d0a47abc15dd360c612ec982..b61d2005caa2b1c327850d5187e3410f82fa2f1c 100644 (file)
Binary files a/test/dts_files/server-policy.dtb and b/test/dts_files/server-policy.dtb differ
index 6b734afa294ccf02c158b3e59d4208d788af8e1a..6ab43f8d640e5a61ae262f804774f0ebe8688d8e 100644 (file)
@@ -81,6 +81,7 @@
             assignments = <896  1104>, "xiu = (*)",
                           <2000 1000>, "iu=(RM_Server RM_Client_Delegate RM_Client)",
                           <3000 5192>, "iux=(RM_Server) & iu=(RM_Client_Delegate RM_Client)";
+            allocation-size = <16>;
         };
     }; /* qmss */
 
index ee1d3da5525eaecde0b90321c0312012005f15d4..4ab57257a7ccb98116c1331b0ee778e9f8ce4514 100644 (file)
@@ -241,7 +241,8 @@ void waitForResponse(Rm_ServiceRespInfo *respInfo)
 {
     uint32_t qIndex = 0;
 
-    if (respInfo->serviceState == RM_SERVICE_PROCESSING) {
+    if ((respInfo->serviceState == RM_SERVICE_PROCESSING) ||
+        (respInfo->serviceState == RM_SERVICE_PENDING_SERVER_RESPONSE)) {
         /* Scan responseInfoQueue for the response received via the callback function */
         while((responseInfoQueue[qIndex].serviceId != respInfo->serviceId) ||
               (responseInfoQueue[qIndex].rmHandle != respInfo->rmHandle)) {
@@ -360,7 +361,7 @@ void rmServerTsk(UArg arg0, UArg arg1)
     GateMP_leave(clientGateHandle, clientKey);
     /* Block until Client finishes freeing the resource */
     serverKey = GateMP_enter(serverGateHandle);
-    MEM_TEST_END_PRINT("------------- Remote Alloc/Free From Client -------------",
+    MEM_TEST_END_PRINT("------- Remote Alloc/Free From Client (Blocking) --------",
                        "Pre Client Alloc     ", "Post Client Alloc Req", "Post Client Free     ");   
 
 
@@ -373,7 +374,7 @@ void rmServerTsk(UArg arg0, UArg arg1)
     GateMP_leave(clientGateHandle, clientKey);
     /* Block until Client finishes freeing the resources */
     serverKey = GateMP_enter(serverGateHandle);           
-    MEM_TEST_END_PRINT("-------- Remote Multiple Alloc/Free From Client ---------",
+    MEM_TEST_END_PRINT("--- Remote Multiple Alloc/Free From Client (Blocking) ---",
                        "Pre Client Alloc     ", "Post Client Alloc Req", "Post Client Free     ");    
 
 
@@ -386,10 +387,23 @@ void rmServerTsk(UArg arg0, UArg arg1)
     GateMP_leave(clientGateHandle, clientKey);
     /* Block until Client finishes unmapping resource */
     serverKey = GateMP_enter(serverGateHandle);           
-    MEM_TEST_END_PRINT("-------- Remote NameServer Map/Unmap From Client --------",
+    MEM_TEST_END_PRINT("-- Remote NameServer Map/Unmap From Client (Blocking) ---",
                        "Pre Client NS Map    ", "Post Client NS Map   ", "Post Client NS Unmap ");    
 
 
+    MEM_TEST_START_STORE();
+    /* Leave the server gate to let client task request resources */
+    GateMP_leave(serverGateHandle, serverKey);
+    /* Block until Client finishes allocating the resources */
+    clientKey = GateMP_enter(clientGateHandle); 
+    MEM_TEST_MID_STORE();
+    GateMP_leave(clientGateHandle, clientKey);
+    /* Block until Client finishes freeing the resources */
+    serverKey = GateMP_enter(serverGateHandle);           
+    MEM_TEST_END_PRINT("- Remote Multiple Alloc/Free From Client (Non-Blocking) -",
+                       "Pre Client Alloc     ", "Post Client Alloc Req", "Post Client Free     "); 
+
+
     Rm_serviceCloseHandle(serviceHandle);
     
     /* Create the RM cleanup task. */
@@ -428,7 +442,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
                  896, 1, 0, NULL, RM_TEST_FALSE, &response);
     serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
     ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Free failed");
-    MEM_TEST_END_PRINT("------------ Client Alloc/Free (Non-Blocking) -----------",
+    MEM_TEST_END_PRINT("-------------- Client Alloc/Free (Blocking) -------------",
                        "Pre Alloc            ", "Post Alloc Request   ", "Post Free            ");
     /* Let server print memory usage */
     GateMP_leave(serverGateHandle, serverKey);
@@ -471,7 +485,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
                  900, 100, 0, NULL, RM_TEST_FALSE, &response);
     serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
     ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Free failed");  
-    MEM_TEST_END_PRINT("--------------- Client Multiple Alloc/Free --------------",
+    MEM_TEST_END_PRINT("--------- Client Multiple Alloc/Free (Blocking) ---------",
                        "Pre Alloc            ", "Post Alloc Requests  ", "Post Free            ");
     /* Let server print memory usage */
     GateMP_leave(serverGateHandle, serverKey);
@@ -494,12 +508,62 @@ void rmClientTsk(UArg arg0, UArg arg1)
                  0, 0, 0, nsNameFavQ, RM_TEST_FALSE, &response);
     serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
     ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "NameServer unmap failed");
-    MEM_TEST_END_PRINT("-------------- Client NameServer Map/Unmap --------------",
+    MEM_TEST_END_PRINT("-------- Client NameServer Map/Unmap (Blocking) ---------",
                        "Pre NS Map           ", "Name Mapped to NS    ", "Name Unmapped from NS");       
     /* Let server print memory usage */
     GateMP_leave(serverGateHandle, serverKey);
 
 
+    /* Block until server is ready to receive request */
+    serverKey = GateMP_enter(serverGateHandle);
+    MEM_TEST_START_STORE();       
+    /* Perform multiple allocs without RM blocking to force the tree to combine nodes */
+    setRmRequest(&request, Rm_service_RESOURCE_ALLOCATE_INIT, resNameMcGpQ, 
+                 900, 50, 0, NULL, RM_TEST_TRUE, &response);
+    serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
+    waitForResponse(&response);
+    ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Allocate failed");
+    setRmRequest(&request, Rm_service_RESOURCE_ALLOCATE_INIT, resNameMcGpQ, 
+                 2000, 50, 0, NULL, RM_TEST_TRUE, &response);
+    serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
+    waitForResponse(&response);
+    ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Allocate failed");
+    setRmRequest(&request, Rm_service_RESOURCE_ALLOCATE_INIT, resNameMcGpQ, 
+                 1000, 1000, 0, NULL, RM_TEST_TRUE, &response);
+    serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
+    waitForResponse(&response);
+    ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Allocate failed");
+    setRmRequest(&request, Rm_service_RESOURCE_ALLOCATE_INIT, resNameMcGpQ, 
+                 950, 50, 0, NULL, RM_TEST_TRUE, &response);
+    serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
+    waitForResponse(&response);
+    ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Allocate failed"); 
+    /* Let server save memory usage for alloc */
+    GateMP_leave(clientGateHandle, clientKey);
+    MEM_TEST_MID_STORE();    
+    /* Block until Server saves malloc/free info */
+    clientKey = GateMP_enter(clientGateHandle);      
+    setRmRequest(&request, Rm_service_RESOURCE_FREE, resNameMcGpQ, 
+                 1000, 500, 0, NULL, RM_TEST_TRUE, &response);
+    serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
+    waitForResponse(&response);
+    ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Free failed");     
+    setRmRequest(&request, Rm_service_RESOURCE_FREE, resNameMcGpQ, 
+                 1500, 550, 0, NULL, RM_TEST_TRUE, &response);
+    serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
+    waitForResponse(&response);
+    ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Free failed");   
+    setRmRequest(&request, Rm_service_RESOURCE_FREE, resNameMcGpQ, 
+                 900, 100, 0, NULL, RM_TEST_TRUE, &response);
+    serviceHandle->Rm_serviceHandler(serviceHandle->rmHandle, &request, &response);
+    waitForResponse(&response);
+    ERROR_CHECK(RM_SERVICE_APPROVED, response.serviceState, rmInstName, "Free failed");  
+    MEM_TEST_END_PRINT("------- Client Multiple Alloc/Free (Non-Blocking) -------",
+                       "Pre Alloc            ", "Post Alloc Requests  ", "Post Free            ");
+    /* Let server print memory usage */
+    GateMP_leave(serverGateHandle, serverKey);
+
+
     Rm_serviceCloseHandle(serviceHandle);
     
     /* Create the RM cleanup task. */
@@ -751,6 +815,7 @@ void testCd(void)
     System_sprintf (rmInstName, "RM_Client_Delegate");
     rmInitCfg.instName = rmInstName;
     rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE;
+    rmInitCfg.instCfg.cdCfg.cdPolicy = (void *)rmGlobalPolicy;    
     rmHandle = Rm_init(&rmInitCfg, &rmResult);
     ERROR_CHECK(RM_OK, rmResult, rmInstName, "Initialization failed");
     MEM_TEST_MID_STORE();
@@ -884,7 +949,8 @@ void testServerCdClient(void)
     memset((void *)&rmInitCfg, 0, sizeof(rmInitCfg));
     System_sprintf (cdName, "RM_Client_Delegate");
     rmInitCfg.instName = cdName;
-    rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE;      
+    rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE;
+    rmInitCfg.instCfg.cdCfg.cdPolicy = (void *)rmGlobalPolicy;
     cdHandle = Rm_init(&rmInitCfg, &rmResult);
     ERROR_CHECK(RM_OK, rmResult, cdName, "Initialization failed"); 
     /* Init Client */
index b28417dc402db0aa060f3526819eb0a39484ca37..0c47e1665532b07c33c1d01f5ab2d13da6d8dde6 100644 (file)
@@ -479,7 +479,8 @@ void waitForResponse(Rm_ServiceRespInfo *respInfo)
 {
     uint32_t qIndex = 0;
 
-    if (respInfo->serviceState == RM_SERVICE_PROCESSING) {
+    if ((respInfo->serviceState == RM_SERVICE_PROCESSING) ||
+        (respInfo->serviceState == RM_SERVICE_PENDING_SERVER_RESPONSE)) {
         /* Scan responseInfoQueue for the response received via the callback function */
         while((responseInfoQueue[qIndex].serviceId != respInfo->serviceId) ||
               (responseInfoQueue[qIndex].rmHandle != respInfo->rmHandle)) {
@@ -751,9 +752,18 @@ void rmServerTsk(UArg arg0, UArg arg1)
     NEGATIVE_PASS_CHECK("------ Use Allocation of Exclusively Owned Resource -----", 
                         coreNum, rmServerName, resourceNameAifRxCh,
                         requestInfo.resourceBase, requestInfo.resourceLength, 
-                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);       
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+
+    /* Allocate small regions of general purpuse queues to prepare for CD local allocation testing */
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameGpQ, 
+                 2100, 10, 0, NULL, RM_TEST_TRUE, &responseInfo);      
+    rmServerServiceHandle->Rm_serviceHandler(rmServerServiceHandle->rmHandle, &requestInfo, &responseInfo);  
+    POSITIVE_PASS_CHECK("-- Use Allocation Preparing for CD Local Alloc Testing --", 
+                        coreNum, rmServerName, resourceNameGpQ,
+                        responseInfo.resourceBase, responseInfo.resourceLength, 
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);      
 
-    /* Wait for Client and Client Delegate to do their UNSPECIFIED allocates */
+    /* Wait for Client and Client Delegate to do their UNSPECIFIED allocates and CD testing */
     GateMP_leave(serverGate, serverKey);
     clientKey = GateMP_enter(clientGate);
     GateMP_leave(clientGate, clientKey);
@@ -803,6 +813,17 @@ void rmServerTsk(UArg arg0, UArg arg1)
                       responseInfo.resourceBase, responseInfo.resourceLength, 
                       responseInfo.resourceNumOwners, responseInfo.serviceState, RM_SERVICE_APPROVED, 0);
 
+    /* BEGIN Testing CD local allocation feature from Server */
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameGpQ, 
+                 2051, 2, 0, NULL, RM_TEST_TRUE, &responseInfo);      
+    rmServerServiceHandle->Rm_serviceHandler(rmServerServiceHandle->rmHandle, &requestInfo, &responseInfo);
+    POSITIVE_PASS_CHECK("--------- CD Testing: Allocate Use From Server ----------", 
+                        coreNum, rmServerName, resourceNameGpQ,
+                        responseInfo.resourceBase, responseInfo.resourceLength, 
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+    /* END Testing CD local allocation feature from Server */
+
+
 #if PRINT_USED_RESOURCES
     Rm_resourceStatus(rmServerHandle, RM_TEST_TRUE);
 #endif
@@ -829,9 +850,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_GET_BY_NAME, NULL, 
                  0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);     
     rmCdServiceHandle->Rm_serviceHandler(rmCdServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }
+    waitForResponse(&responseInfo); 
     POSITIVE_PASS_CHECK("------- Retrieve Resource Via NameServer Object ---------", 
                         coreNum, rmCdName, responseInfo.resourceName,
                         responseInfo.resourceBase, responseInfo.resourceLength, 
@@ -846,9 +865,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     requestInfo.resourceNsName = NULL;
     requestInfo.callback.serviceCallback = serviceCallback;     
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    } 
+    waitForResponse(&responseInfo); 
     POSITIVE_PASS_CHECK("-------- Init Allocate Using Retrieved Resource ---------", 
                         coreNum, rmClientName, responseInfo.resourceName,
                         requestInfo.resourceBase, requestInfo.resourceLength, 
@@ -858,9 +875,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, NULL, 
                  0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);     
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }
+    waitForResponse(&responseInfo); 
     STATUS_PASS_CHECK("---- Retrieve Resource Status Via NameServer Object -----", 
                       coreNum, rmClientName, responseInfo.resourceName,
                       responseInfo.resourceBase, responseInfo.resourceLength, 
@@ -870,9 +885,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_FREE, NULL, 
                  0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);     
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }
+    waitForResponse(&responseInfo); 
     POSITIVE_PASS_CHECK("--- Free of Retrieved Resource Using NameServer Name ----", 
                         coreNum, rmClientName, nameServerNameFavQ,
                         0, 1, 0, responseInfo.serviceState, RM_SERVICE_APPROVED);      
@@ -881,9 +894,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_UNMAP_NAME, NULL, 
                  0, 0, 0, nameServerNameFavQ, RM_TEST_TRUE, &responseInfo);     
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }
+    waitForResponse(&responseInfo); 
     POSITIVE_PASS_CHECK("--------------- Delete NameServer Object ----------------", 
                         coreNum, rmClientName, nameServerNameFavQ,
                         0, 1, 0, responseInfo.serviceState, RM_SERVICE_APPROVED);      
@@ -897,9 +908,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAifRxCh, 
                  0, 6, 0, NULL, RM_TEST_TRUE, &responseInfo);     
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }    
+    waitForResponse(&responseInfo);    
     POSITIVE_PASS_CHECK("- Resource Node Expand/Contract Testing (Use Allocate) --", 
                         coreNum, rmClientName, resourceNameAifRxCh,
                         requestInfo.resourceBase, requestInfo.resourceLength, 
@@ -908,9 +917,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameAifRxCh, 
                  50, 7, 0, NULL, RM_TEST_TRUE, &responseInfo);        
     rmCdServiceHandle->Rm_serviceHandler(rmCdServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }    
+    waitForResponse(&responseInfo);    
     POSITIVE_PASS_CHECK("- Resource Node Expand/Contract Testing (Init Allocate) -", 
                         coreNum, rmCdName, resourceNameAifRxCh,
                         requestInfo.resourceBase, requestInfo.resourceLength, 
@@ -927,9 +934,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh, 
                  RM_RESOURCE_BASE_UNSPECIFIED, 5, 4, NULL, RM_TEST_TRUE, &responseInfo);        
     rmCdServiceHandle->Rm_serviceHandler(rmCdServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    } 
+    waitForResponse(&responseInfo); 
     POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------", 
                         coreNum, rmCdName, resourceNameAccumCh,
                         RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength, 
@@ -938,9 +943,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh, 
                  RM_RESOURCE_BASE_UNSPECIFIED, 2, 1, NULL, RM_TEST_TRUE, &responseInfo);      
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo); 
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }
+    waitForResponse(&responseInfo); 
     POSITIVE_PASS_CHECK("---------- Use Allocation w/ UNSPECIFIED Base -----------", 
                         coreNum, rmClientName, resourceNameAccumCh,
                         RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength, 
@@ -949,9 +952,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameAccumCh, 
                  RM_RESOURCE_BASE_UNSPECIFIED, 2, RM_RESOURCE_ALIGNMENT_UNSPECIFIED, NULL, RM_TEST_TRUE, &responseInfo);     
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }
+    waitForResponse(&responseInfo); 
     POSITIVE_PASS_CHECK("---- Use Allocation w/ UNSPECIFIED Base & Alignment -----", 
                         coreNum, rmClientName, resourceNameAccumCh,
                         RM_RESOURCE_BASE_UNSPECIFIED, requestInfo.resourceLength, 
@@ -962,9 +963,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameInfraQ, 
                  800, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);     
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }
+    waitForResponse(&responseInfo); 
     POSITIVE_PASS_CHECK("-- Init Allocation of Shared Linux and Client Resource --", 
                         coreNum, rmClientName, resourceNameInfraQ,
                         requestInfo.resourceBase, requestInfo.resourceLength, 
@@ -1006,15 +1005,13 @@ void rmClientTsk(UArg arg0, UArg arg1)
                         requestInfo.resourceBase, requestInfo.resourceLength, 
                         requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);     
     /* END Allocating some resources without providing a callback function.  RM should block and not return
-     * until the result is returned by the server. */   
+     * until the result is returned by the Server. */   
 
     /* BEGIN Getting the status of resources from Client and CD */
     setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, resourceNameGpQ, 
                  7012, 2, 0, NULL, RM_TEST_TRUE, &responseInfo);     
     rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }    
+    waitForResponse(&responseInfo);  
     STATUS_PASS_CHECK("-- Status Check of Resources from Client (Non-Blocking) -", 
                       coreNum, rmClientName, responseInfo.resourceName,
                       responseInfo.resourceBase, responseInfo.resourceLength, 
@@ -1031,9 +1028,7 @@ void rmClientTsk(UArg arg0, UArg arg1)
     setRmRequest(&requestInfo, Rm_service_RESOURCE_STATUS, resourceNameInfraQ, 
                  800, 1, 0, NULL, RM_TEST_TRUE, &responseInfo);     
     rmCdServiceHandle->Rm_serviceHandler(rmCdServiceHandle->rmHandle, &requestInfo, &responseInfo);
-    if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
-        waitForResponse(&responseInfo);
-    }     
+    waitForResponse(&responseInfo);     
     STATUS_PASS_CHECK("---- Status Check of Resources from CD (Non-Blocking) ---", 
                       coreNum, rmCdName, responseInfo.resourceName,
                       responseInfo.resourceBase, responseInfo.resourceLength, 
@@ -1048,6 +1043,43 @@ void rmClientTsk(UArg arg0, UArg arg1)
                       responseInfo.resourceNumOwners, responseInfo.serviceState, RM_SERVICE_APPROVED, 1);   
     /* END Getting the status of resources from Client and CD */    
 
+    /* BEGIN Testing CD local allocation feature */
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ, 
+                 RM_RESOURCE_BASE_UNSPECIFIED, 5, 0, NULL, RM_TEST_TRUE, &responseInfo);     
+    rmCdServiceHandle->Rm_serviceHandler(rmCdServiceHandle->rmHandle, &requestInfo, &responseInfo);
+    waitForResponse(&responseInfo);   
+    POSITIVE_PASS_CHECK("---- CD Testing: Allocate From CD (Non-Blocking) ----", 
+                        coreNum, rmCdName, resourceNameGpQ,
+                        responseInfo.resourceBase, responseInfo.resourceLength, 
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);
+    
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ, 
+                 RM_RESOURCE_BASE_UNSPECIFIED, 5, 0, NULL, RM_TEST_FALSE, &responseInfo);     
+    rmCdServiceHandle->Rm_serviceHandler(rmCdServiceHandle->rmHandle, &requestInfo, &responseInfo); 
+    POSITIVE_PASS_CHECK("------ CD Testing: Allocate From CD (Blocking) ------", 
+                        coreNum, rmCdName, resourceNameGpQ,
+                        responseInfo.resourceBase, responseInfo.resourceLength, 
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);  
+    
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ, 
+                 RM_RESOURCE_BASE_UNSPECIFIED, 50, 0, NULL, RM_TEST_TRUE, &responseInfo);     
+    rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+    waitForResponse(&responseInfo);    
+    POSITIVE_PASS_CHECK("---- CD Testing: Allocate From Client (Non-Blocking) ----", 
+                        coreNum, rmClientName, resourceNameGpQ,
+                        responseInfo.resourceBase, responseInfo.resourceLength, 
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);   
+
+    setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ, 
+                 RM_RESOURCE_BASE_UNSPECIFIED, 50, 0, NULL, RM_TEST_FALSE, &responseInfo);     
+    rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);  
+    POSITIVE_PASS_CHECK("------ CD Testing: Allocate From Client (Blocking) ------", 
+                        coreNum, rmClientName, resourceNameGpQ,
+                        responseInfo.resourceBase, responseInfo.resourceLength, 
+                        requestInfo.resourceAlignment, responseInfo.serviceState, RM_SERVICE_APPROVED);      
+    /* END Testing CD local allocation feature */ 
+
+
     /* Verify static allocations were validated.  Validation responses should have been received after the
      * first service requests were made on the Client and CD post transport path registration. */
     while (numStaticResponses > 0) {
@@ -1072,6 +1104,10 @@ void rmClientTsk(UArg arg0, UArg arg1)
         }    
     }  
 
+#if PRINT_USED_RESOURCES
+    Rm_resourceStatus(rmCdHandle, RM_TEST_TRUE);
+#endif
+
     GateMP_leave(clientGate, clientKey);
     GateMP_leave(serverGate, serverKey);
     clientKey = GateMP_enter(clientGate);
@@ -1411,7 +1447,7 @@ int main(Int argc, Char* argv[])
         /* Create the RM Client Delegate instance */
         rmInitCfg.instName = rmCdName;
         rmInitCfg.instType = Rm_instType_CLIENT_DELEGATE;
-        rmInitCfg.instCfg.cdCfg.cdPolicy = (void *)rmStaticPolicy;
+        rmInitCfg.instCfg.cdCfg.cdPolicy = (void *)rmGlobalPolicy;
         rmCdHandle = Rm_init(&rmInitCfg, &result);
         ERROR_CHECK(RM_OK, result, rmCdName, "Initialization failed");