summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: 7802887)
raw | patch | inline | side by side (parent: 7802887)
author | Justin Sobota <jsobota@ti.com> | |
Tue, 5 Mar 2013 23:27:56 +0000 (18:27 -0500) | ||
committer | Justin Sobota <jsobota@ti.com> | |
Tue, 5 Mar 2013 23:27:56 +0000 (18:27 -0500) |
include/rm_loc.h | patch | blob | history | |
rm_osal.h | patch | blob | history | |
rm_services.h | patch | blob | history | |
src/rm.c | patch | blob | history | |
src/rm_services.c | patch | blob | history | |
test/rm_osal.c | patch | blob | history | |
test/rm_test.c | patch | blob | history |
diff --git a/include/rm_loc.h b/include/rm_loc.h
index d351977c2f6f97a1b645ac0aee6607cb0ad5ab8f..69e197d72bfc38890a408b57f273ba8c86b2e19f 100644 (file)
--- a/include/rm_loc.h
+++ b/include/rm_loc.h
uint32_t transactionSeqNum;
/* Service transaction linked list queue */
Rm_Transaction *transactionQueue;
- /* Local gate key provided through OSAL when RM needs to block due to
- * a service request that requires a blocking operation to complete */
- uint32_t localGateKey;
+ /* Block handle provided through OSAL for when RM needs to block due to
+ * a service request that requires a blocking operation to complete and
+ * a service callback function has not been provided */
+ void *blockHandle;
/* Instance-type specific constructs */
union {
/* Server-specific instance data */
diff --git a/rm_osal.h b/rm_osal.h
index 843b5edc0657d1318a3be83161b57841022b8017..8825204def9eb63dd86ce62625397f2d58c34dd6 100644 (file)
--- a/rm_osal.h
+++ b/rm_osal.h
************************* Extern Declarations ************************
**********************************************************************/
-extern void *Osal_rmMalloc (uint32_t num_bytes);
-extern void Osal_rmFree (void *ptr, uint32_t size);
-extern uint32_t Osal_rmLocalGateEnter (void);
-extern void Osal_rmLocalGateLeave (uint32_t localGateKey);
-extern void Osal_rmLog (char *fmt, ... );
+extern void *Osal_rmMalloc (uint32_t num_bytes);
+extern void Osal_rmFree (void *ptr, uint32_t size);
+extern void *Osal_rmTaskBlockCreate (void);
+extern void Osal_rmTaskBlock (void *handle);
+extern void Osal_rmTaskUnblock (void *handle);
+extern void Osal_rmTaskBlockDelete (void *handle);
+extern void Osal_rmLog (char *fmt, ... );
/**
* @brief The macro is used by RM to allocate memory of specified
*/
#define Rm_osalFree Osal_rmFree
-#define Rm_osalLocalGateEnter Osal_rmLocalGateEnter
+/**
+ * @brief The macro is used by RM to create a task blocking
+ * mechanism allowing a RM instance to block when it
+ * has not been provided a service callback function
+ * and it must send a packet to remote RM instance
+ * to complete a service.
+ *
+ * <b> Prototype: </b>
+ * The following is the C prototype for the expected OSAL API.
+ *
+ * @verbatim
+ void *Osal_rmTaskBlockCreate (void)
+ @endverbatim
+ *
+ * <b> Parameter </b>
+ * @n Not applicable.
+ *
+ * <b> Return Value </b>
+ * @n Task blocking mechanism handle cast as a void pointer
+ */
+#define Rm_osalTaskBlockCreate Osal_rmTaskBlockCreate
+
+/**
+ * @brief The macro is used by a RM instance to block when it
+ * has not been provided a service callback function
+ * and it must send a packet to remote RM instance
+ * to complete a service. The blocking operation
+ * should block the current RM instance's task/thread
+ * from executing until a task/thread from which the
+ * RM receive code runs unblocks the RM instance
+ *
+ * <b> Prototype: </b>
+ * The following is the C prototype for the expected OSAL API.
+ *
+ * @verbatim
+ void Osal_rmTaskBlock (void *handle)
+ @endverbatim
+ *
+ * <b> Parameter </b>
+ * @n Task blocking mechanism handle cast as a void pointer
+ *
+ * <b> Return Value </b>
+ * @n Not applicable.
+ */
+#define Rm_osalTaskBlock Osal_rmTaskBlock
-#define Rm_osalLocalGateLeave Osal_rmLocalGateLeave
+/**
+ * @brief The macro is used by a RM instance to unblock from
+ * a previous block operation.
+ *
+ * <b> Prototype: </b>
+ * The following is the C prototype for the expected OSAL API.
+ *
+ * @verbatim
+ void Osal_rmTaskUnblock (void *handle)
+ @endverbatim
+ *
+ * <b> Parameter </b>
+ * @n Task blocking mechanism handle cast as a void pointer
+ *
+ * <b> Return Value </b>
+ * @n Not applicable.
+ */
+#define Rm_osalTaskUnblock Osal_rmTaskUnblock
+
+/**
+ * @brief The macro is used by a RM instance to delete its
+ * task blocking mechanism.
+ *
+ * <b> Prototype: </b>
+ * The following is the C prototype for the expected OSAL API.
+ *
+ * @verbatim
+ void Osal_rmTaskBlockDelete (void *handle)
+ @endverbatim
+ *
+ * <b> Parameter </b>
+ * @n Task blocking mechanism handle cast as a void pointer
+ *
+ * <b> Return Value </b>
+ * @n Not applicable.
+ */
+#define Rm_osalTaskBlockDelete Osal_rmTaskBlockDelete
/**
* @brief The macro is used by RM to log various
diff --git a/rm_services.h b/rm_services.h
index 67c1670391fa2ca1a2ae1a2eda505fbefd80fac3..2968a97891184b955a91f104e756fea1cf141eaf 100644 (file)
--- a/rm_services.h
+++ b/rm_services.h
* property defined.
* b) The default alignment of 1 if no alignment is specified in the policy
* for the resource.
- * This value is only valid if resourceBase is set to
- * #RM_RESOURCE_BASE_UNSPECIFIED */
+ * This value is only valid if resourceBase is set to #RM_RESOURCE_BASE_UNSPECIFIED */
#define RM_RESOURCE_ALIGNMENT_UNSPECIFIED (-1)
/** Alignment of the resource affected by the service request. Only valid
* if resourceBase is set to #RM_RESOURCE_BASE_UNSPECIFIED.
* occur. */
const char *resourceNsName;
/** Callback function used by RM to provide responses back to application
- * components after a service request resulted in a blocking operation. */
+ * components after a service request resulted in a blocking operation.
+ * If no callback function is provided the RM instance will block until
+ * the service response is ready. */
Rm_ServiceCallback callback;
} Rm_ServiceReqInfo;
diff --git a/src/rm.c b/src/rm.c
index bb6e697a7709aa6fc3f1f1a0191d759de4e77df2..e10403316261c28095a217b3d2f0876aacd2574c 100644 (file)
--- a/src/rm.c
+++ b/src/rm.c
}
}
}
+
+ /* Create the instance's task blocking mechanism */
+ rmInst->blockHandle = Rm_osalTaskBlockCreate();
+
return ((Rm_Handle) rmInst);
errorExit:
if (rmInst) {
while(rmInst->transactionQueue) {
rmTransactionQueueDelete(rmInst, rmInst->transactionQueue->localId);
}
+
+ /* Delete the instance's task blocking mechanism */
+ Rm_osalTaskBlockDelete(rmInst->blockHandle);
+
+ Rm_osalFree((void *)rmInst, sizeof(Rm_Inst));
return (RM_OK);
}
diff --git a/src/rm_services.c b/src/rm_services.c
index 3a2b7844394db33987a22179fc9a0f1a43aabc98..c689ee4a3f5de036806755fdf61b543f0f84a38b 100644 (file)
--- a/src/rm_services.c
+++ b/src/rm_services.c
********************** Internal Functions ****************************
**********************************************************************/
+/* FUNCTION PURPOSE: Internal Callback to unblock RM instance
+ ***********************************************************************
+ * DESCRIPTION: Internal callback function executed when the result
+ * of a service request has been received from a remote
+ * instance. The original service request did not specify
+ * a callback function so the Rm_serviceHandler is blocked
+ * waiting for the response. This function unblocks the
+ * Rm_serviceHandler to return the response to the
+ * application.
+ */
void rmServiceInternalCallback(Rm_Handle rmHandle)
{
Rm_Inst *rmInst = (Rm_Inst *)rmHandle;
- /* Unblock so the serviceHandler can provide the response to the application */
- Rm_osalLocalGateLeave(rmInst->localGateKey);
+ /* Unblock so Rm_serviceHandler can provide response to application */
+ Rm_osalTaskUnblock(rmInst->blockHandle);
}
/**********************************************************************
@@ -118,7 +128,7 @@ void Rm_serviceHandler (void *rmHandle, const Rm_ServiceReqInfo *serviceRequest,
if ((transaction->state == RM_SERVICE_PROCESSING) && (transaction->callback.serviceCallback == NULL)) {
/* Block until response is received. Response will be received in transaction. */
- rmInst->localGateKey = Rm_osalLocalGateEnter();
+ Rm_osalTaskBlock(rmInst->blockHandle);
}
serviceResponse->rmHandle = rmHandle;
diff --git a/test/rm_osal.c b/test/rm_osal.c
index 99bcc0f32f40b28a1fb1fb91ce94f91bb835c423..5a0812b6e96381d7aeb568250107141f010c2a52 100644 (file)
--- a/test/rm_osal.c
+++ b/test/rm_osal.c
/* Standard Includes */
#include <stdarg.h>
+#include <stdbool.h>
/* XDC Includes */
#include <xdc/std.h>
#include <xdc/runtime/System.h>
/* BIOS Includes */
-#include <ti/sysbios/gates/GateMutex.h>
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Task.h>
+#include <ti/sysbios/knl/Semaphore.h>
/**********************************************************************
****************************** Defines *******************************
**********************************************************************/
-#define RM_INTERNAL_GATE_NAME "rmInternalLocalGate"
+
+/* Specifies the number of test tasks running that have at least one
+ * RM running instance running within their context */
+#define NUM_TASKS_CONTAINING_RM_INSTANCES 2
+
+/* Structure that maps a semaphore to a task */
+typedef struct {
+ /* Task handle */
+ Task_Handle task;
+ /* Semaphore handle */
+ Semaphore_Handle sem;
+ /* Number of times semaphore has been returned via create API */
+ uint32_t ownerCount;
+} Semaphore_Owner;
/**********************************************************************
************************** Global Variables **************************
uint32_t rmMallocCounter = 0;
uint32_t rmFreeCounter = 0;
-GateMutex_Handle rmInternalGateHandle;
+Semaphore_Owner semOwners[NUM_TASKS_CONTAINING_RM_INSTANCES] = {{NULL, NULL, 0},
+ {NULL, NULL, 0}};
/**********************************************************************
*************************** OSAL Functions **************************
* DESCRIPTION: The function is used to allocate a memory block of the
* specified size.
*/
-void* Osal_rmMalloc (uint32_t num_bytes)
+void *Osal_rmMalloc (uint32_t num_bytes)
{
Error_Block errorBlock;
Memory_free(NULL, ptr, size);
}
-void Osal_rmLocalGateInit (void)
+void *Osal_rmTaskBlockCreate(void)
+{
+ Semaphore_Params semParams;
+#if 0
+ Task_Handle currentTask = Task_self();
+ uint32_t ownerIndex;
+
+ /* See if task from which create has been called already has a sem */
+ for (ownerIndex = 0; ownerIndex < NUM_TASKS_CONTAINING_RM_INSTANCES; ownerIndex++) {
+ if (semOwners[ownerIndex].task == currentTask) {
+ break;
+ }
+ }
+ if (ownerIndex == NUM_TASKS_CONTAINING_RM_INSTANCES) {
+ /* First time create called within this task context. Find next
+ * available slot in semOwners array */
+ ownerIndex = 0;
+ while(semOwners[ownerIndex].task) {
+ ownerIndex++;
+ }
+ semOwners[ownerIndex].task = currentTask;
+ }
+
+ if (semOwners[ownerIndex].sem == NULL) {
+ Semaphore_Params_init(&semParams);
+ semOwners[ownerIndex].sem = Semaphore_create(0, &semParams, NULL);
+ }
+ semOwners[ownerIndex].ownerCount++;
+ return((void *)semOwners[ownerIndex].sem);
+#endif
+ Semaphore_Params_init(&semParams);
+ return((void *)Semaphore_create(0, &semParams, NULL));
+}
+
+void Osal_rmTaskBlock(void *handle)
{
- Error_Block eb;
- GateMutex_Params gateParams;
-
- /* Create a GateMutex object to be use as a resource lock */
- GateMutex_Params_init(&gateParams);
- rmInternalGateHandle = GateMutex_create(&gateParams, &eb);
- /* Immediately take the gate so that calls from within RM will block */
- GateMutex_enter(rmInternalGateHandle);
+ Semaphore_pend((Semaphore_Handle)handle, BIOS_WAIT_FOREVER);
}
-uint32_t Osal_rmLocalGateEnter (void)
+void Osal_rmTaskUnblock(void *handle)
{
- return ((uint32_t)GateMutex_enter(rmInternalGateHandle));
+ Semaphore_post((Semaphore_Handle)handle);
}
-void Osal_rmLocalGateLeave (uint32_t localGateKey)
+void Osal_rmTaskBlockDelete(void *handle)
{
- GateMutex_leave(rmInternalGateHandle, (IArg)localGateKey);
+ Semaphore_delete((Semaphore_Handle *)&handle);
}
/* FUNCTION PURPOSE: Prints a variable list
diff --git a/test/rm_test.c b/test/rm_test.c
index 1e12b99028e5358825727c23b042b32a8fe472d9..baccd589d85bc5bf4d4126c22bcbf2bf8125b3f4 100644 (file)
--- a/test/rm_test.c
+++ b/test/rm_test.c
System_printf("FAILED : denial or error : %d\n", responseInfo.serviceState);
}
- /* Allocate a resource without providing a callback function. RM should block and not return until the result
+ /* BEGIN Allocating some resources without providing a callback function. RM should block and not return until the result
* is returned by the server. */
setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ,
7000, 1, 0, NULL, FALSE, &responseInfo);
resourceNameGpQ,
requestInfo.resourceBase,
(requestInfo.resourceBase + requestInfo.resourceLength - 1));
- if (responseInfo.serviceState == RM_SERVICE_PROCESSING) {
- waitForResponse(&responseInfo);
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED) {
+ System_printf("PASSED\n");
}
+ else {
+ System_printf("FAILED : denial or error : %d\n", responseInfo.serviceState);
+ }
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameGpQ,
+ 7005, 25, 0, NULL, FALSE, &responseInfo);
+ rmCdServiceHandle->Rm_serviceHandler(rmCdServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ System_printf("Core %d : %s use allocation (without callback specified) of %s %d - %d : ", coreNum,
+ rmCdName,
+ resourceNameGpQ,
+ requestInfo.resourceBase,
+ (requestInfo.resourceBase + requestInfo.resourceLength - 1));
if (responseInfo.serviceState == RM_SERVICE_APPROVED) {
System_printf("PASSED\n");
}
else {
System_printf("FAILED : denial or error : %d\n", responseInfo.serviceState);
- }
+ }
+
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_USE, resourceNameGpQ,
+ 7010, 5, 0, NULL, FALSE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ System_printf("Core %d : %s use allocation (without callback specified) of %s %d - %d : ", coreNum,
+ rmClientName,
+ resourceNameGpQ,
+ requestInfo.resourceBase,
+ (requestInfo.resourceBase + requestInfo.resourceLength - 1));
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED) {
+ System_printf("PASSED\n");
+ }
+ else {
+ System_printf("FAILED : denial or error : %d\n", responseInfo.serviceState);
+ }
+
+ /* Init allocation of resource already owned by Client should return approved and the resource should
+ * only be shown as allocated once to the instance in the resource print out */
+ setRmRequest(&requestInfo, Rm_service_RESOURCE_ALLOCATE_INIT, resourceNameGpQ,
+ 7011, 1, 0, NULL, FALSE, &responseInfo);
+ rmClientServiceHandle->Rm_serviceHandler(rmClientServiceHandle->rmHandle, &requestInfo, &responseInfo);
+ System_printf("Core %d : %s use allocation (without callback specified) of %s %d - %d : ", coreNum,
+ rmClientName,
+ resourceNameGpQ,
+ requestInfo.resourceBase,
+ (requestInfo.resourceBase + requestInfo.resourceLength - 1));
+ if (responseInfo.serviceState == RM_SERVICE_APPROVED) {
+ System_printf("PASSED\n");
+ }
+ else {
+ System_printf("FAILED : denial or error : %d\n", responseInfo.serviceState);
+ }
+ /* END Allocating some resources without providing a callback function. RM should block and not return until the result
+ * is returned by the server. */
GateMP_leave(gateHandle, gateKey);
/* Initialize the transport map */
for (i = 0; i < MAX_MAPPING_ENTRIES; i++) {
rmTransportMap[i].transportHandle = NULL;
- }
-
- /* Create the gate internal to RM for service requests not specifying a callback function
- * and needing a blocking operation to complete.
- *
- * Must be created from a different task than the test tasks to allow proper blocking. */
- Osal_rmLocalGateInit();
+ }
if (coreNum == 0) {
GateMP_Params_init(&gateParams);