author | Sam Siluvaimani <a0862859@ti.com> | |
Wed, 7 Jun 2017 19:54:33 +0000 (14:54 -0500) | ||
committer | Sam Siluvaimani <a0862859@ti.com> | |
Wed, 7 Jun 2017 19:54:33 +0000 (14:54 -0500) |
* commit '3e4ff006f700b50d46734cd890ce5e02dfc457e8':
host_linux: Temporarily disable local lock
host_linux: Add example for use case with host running linux
host_linux: Temporarily disable local lock
host_linux: Add example for use case with host running linux
50 files changed:
diff --git a/host_linux/simple_buffer_example/dsp/Dsp.cfg b/host_linux/simple_buffer_example/dsp/Dsp.cfg
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2017 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======== Dsp.cfg ========
+ * Platform: DRA7XX_linux_elf
+ * Target: ti.targets.elf.C66
+ */
+
+/* root of the configuration object model */
+var Program = xdc.useModule('xdc.cfg.Program');
+var cfgArgs = Program.build.cfgArgs;
+
+/* application uses the following modules and packages */
+xdc.useModule('xdc.runtime.Assert');
+xdc.useModule('xdc.runtime.Diags');
+xdc.useModule('xdc.runtime.Error');
+xdc.useModule('xdc.runtime.Log');
+xdc.useModule('xdc.runtime.Registry');
+
+xdc.useModule('ti.sysbios.knl.Semaphore');
+xdc.useModule('ti.sysbios.knl.Task');
+
+/*
+ * ======== IPC Configuration ========
+ */
+xdc.useModule('ti.ipc.ipcmgr.IpcMgr');
+
+/* load the configuration shared across cores */
+Program.global.procName = cfgArgs.procname;
+
+/* configure processor names */
+var procNameAry = cfgArgs.procnamelist;
+
+var MultiProc = xdc.useModule('ti.sdo.utils.MultiProc');
+MultiProc.setConfig(Program.global.procName, procNameAry);
+
+var BIOS = xdc.useModule('ti.sysbios.BIOS');
+BIOS.addUserStartupFunction('&IpcMgr_ipcStartup');
+
+/*
+ * ======== SYS/BIOS Configuration ========
+ */
+if (Program.build.profile == "debug") {
+ BIOS.libType = BIOS.LibType_Debug;
+} else {
+ BIOS.libType = BIOS.LibType_Custom;
+}
+
+/* no rts heap */
+Program.argSize = 100; /* minimum size */
+Program.stack = 0x1000;
+
+var Task = xdc.useModule('ti.sysbios.knl.Task');
+Task.common$.namedInstance = true;
+
+/* default memory heap */
+var Memory = xdc.useModule('xdc.runtime.Memory');
+var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');
+var heapMemParams = new HeapMem.Params();
+heapMemParams.size = 0x8000;
+Memory.defaultHeapInstance = HeapMem.create(heapMemParams);
+
+/* create a heap for MessageQ messages */
+var HeapBuf = xdc.useModule('ti.sysbios.heaps.HeapBuf');
+var params = new HeapBuf.Params;
+params.align = 8;
+params.blockSize = 512;
+params.numBlocks = 256;
+var msgHeap = HeapBuf.create(params);
+
+var MessageQ = xdc.useModule('ti.sdo.ipc.MessageQ');
+MessageQ.registerHeapMeta(msgHeap, 0);
+
+/* Setup MessageQ transport */
+var VirtioSetup = xdc.useModule('ti.ipc.transports.TransportRpmsgSetup');
+MessageQ.SetupTransportProxy = VirtioSetup;
+
+/* Setup NameServer remote proxy */
+var NameServer = xdc.useModule("ti.sdo.utils.NameServer");
+var NsRemote = xdc.useModule("ti.ipc.namesrv.NameServerRemoteRpmsg");
+NameServer.SetupProxy = NsRemote;
+
+/* Enable Memory Translation module that operates on the BIOS Resource Table */
+var Resource = xdc.useModule('ti.ipc.remoteproc.Resource');
+Resource.loadSegment = Program.platform.codeMemory;
+/* Override default resource table to add CMEM memory section*/
+Resource.customTable = true;
+
+/* Use SysMin because trace buffer address is required for Linux/QNX
+ * trace debug driver, plus provides better performance.
+ */
+var System = xdc.useModule('xdc.runtime.System');
+var SysMin = xdc.useModule('ti.trace.SysMin');
+System.SupportProxy = SysMin;
+SysMin.bufSize = 0x8000;
+
+Program.sectMap[".tracebuf"] = Program.platform.dataMemory;
+
+/* Add Shared Region module */
+var SharedRegion = xdc.useModule('ti.sdo.ipc.SharedRegion');
+
+/*
+ * ======== Instrumentation Configuration ========
+ */
+
+/* system logger */
+var LoggerSys = xdc.useModule('xdc.runtime.LoggerSys');
+var LoggerSysParams = new LoggerSys.Params();
+var Defaults = xdc.useModule('xdc.runtime.Defaults');
+Defaults.common$.logger = LoggerSys.create(LoggerSysParams);
+
+/* enable runtime Diags_setMask() for non-XDC spec'd modules */
+var Diags = xdc.useModule('xdc.runtime.Diags');
+Diags.setMaskEnabled = true;
+
+/* override diags mask for selected modules */
+xdc.useModule('xdc.runtime.Main');
+Diags.setMaskMeta("xdc.runtime.Main",
+ Diags.ENTRY | Diags.EXIT | Diags.INFO, Diags.RUNTIME_ON);
+
+var Registry = xdc.useModule('xdc.runtime.Registry');
+Registry.common$.diags_ENTRY = Diags.RUNTIME_OFF;
+Registry.common$.diags_EXIT = Diags.RUNTIME_OFF;
+Registry.common$.diags_INFO = Diags.RUNTIME_OFF;
+Registry.common$.diags_USER1 = Diags.RUNTIME_OFF;
+Registry.common$.diags_LIFECYCLE = Diags.RUNTIME_OFF;
+Registry.common$.diags_STATUS = Diags.RUNTIME_OFF;
+
+var Main = xdc.useModule('xdc.runtime.Main');
+Main.common$.diags_ASSERT = Diags.ALWAYS_ON;
+Main.common$.diags_INTERNAL = Diags.ALWAYS_ON;
diff --git a/host_linux/simple_buffer_example/dsp/MainDsp.c b/host_linux/simple_buffer_example/dsp/MainDsp.c
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2017, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======== main_Dsp1.c ========
+ *
+ */
+
+/* xdctools header files */
+#include <xdc/std.h>
+#include <xdc/runtime/Diags.h>
+#include <xdc/runtime/Error.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/System.h>
+
+/* package header files */
+#include <ti/ipc/Ipc.h>
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Task.h>
+
+#include "rsc_table_dsp.h"
+
+/* local header files */
+#include "Server.h"
+
+/* private functions */
+static Void smain(UArg arg0, UArg arg1);
+
+
+/*
+ * ======== main ========
+ */
+Int main(Int argc, Char* argv[])
+{
+ Error_Block eb;
+ Task_Params taskParams;
+
+ Log_print0(Diags_ENTRY, "--> main:");
+
+ /* must initialize the error block before using it */
+ Error_init(&eb);
+
+ /* create main thread (interrupts not enabled in main on BIOS) */
+ Task_Params_init(&taskParams);
+ taskParams.instance->name = "smain";
+ taskParams.arg0 = (UArg)argc;
+ taskParams.arg1 = (UArg)argv;
+ taskParams.stackSize = 0x1000;
+ Task_create(smain, &taskParams, &eb);
+
+ if (Error_check(&eb)) {
+ System_abort("main: failed to create application startup thread");
+ }
+
+ /* start scheduler, this never returns */
+ BIOS_start();
+
+ /* should never get here */
+ Log_print0(Diags_EXIT, "<-- main:");
+ return (0);
+}
+
+
+/*
+ * ======== smain ========
+ */
+Void smain(UArg arg0, UArg arg1)
+{
+ Int status = 0;
+ Error_Block eb;
+ Bool running = TRUE;
+
+ Log_print0(Diags_ENTRY | Diags_INFO, "--> smain:");
+
+ Error_init(&eb);
+
+ /* initialize modules */
+ Server_init();
+
+ /* turn on Diags_INFO trace */
+ Diags_setMask("Server+F");
+
+ /* loop forever */
+ while (running) {
+
+ /* BEGIN server phase */
+
+ /* server setup phase */
+ status = Server_create();
+
+ if (status < 0) {
+ goto leave;
+ }
+
+ /* server execute phase */
+ status = Server_exec();
+
+ if (status < 0) {
+ goto leave;
+ }
+
+ Log_print0(Diags_INFO, "DSP: Test Passed");
+
+ /* server shutdown phase */
+ status = Server_delete();
+
+ if (status < 0) {
+ goto leave;
+ }
+
+ /* END server phase */
+
+ } /* while (running) */
+
+ /* finalize modules */
+ Server_exit();
+
+leave:
+ if (status < 0)
+ Log_print1(Diags_INFO, "DSP: Test Failed: %d", status);
+
+ Log_print1(Diags_EXIT, "<-- smain: %d", (IArg)status);
+ return;
+}
diff --git a/host_linux/simple_buffer_example/dsp/Server.c b/host_linux/simple_buffer_example/dsp/Server.c
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2017, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======== Server.c ========
+ *
+ */
+
+/* this define must precede inclusion of any xdc header file */
+#define Registry_CURDESC Test__Desc
+#define MODULE_NAME "Server"
+
+/* xdctools header files */
+#include <xdc/std.h>
+#include <xdc/runtime/Assert.h>
+#include <xdc/runtime/Diags.h>
+#include <xdc/runtime/Log.h>
+#include <xdc/runtime/Registry.h>
+
+#include <stdio.h>
+
+/* package header files */
+#include <ti/ipc/MessageQ.h>
+#include <ti/ipc/MultiProc.h>
+#include <ti/ipc/SharedRegion.h>
+#include <ti/ipc/HeapMemMP.h>
+#include <ti/ipc/remoteproc/Resource.h>
+#include <ti/sysbios/hal/Cache.h>
+#include <xdc/runtime/IHeap.h>
+#include <xdc/runtime/Memory.h>
+
+#include <ti/sysbios/BIOS.h>
+#include <ti/sysbios/knl/Task.h>
+
+/* local header files */
+#include "../shared/AppCommon.h"
+
+/* module header file */
+#include "Server.h"
+
+/* module structure */
+typedef struct {
+ UInt16 hostProcId; // host processor id
+ MessageQ_Handle slaveQue; // created locally
+} Server_Module;
+
+/* private data */
+Registry_Desc Registry_CURDESC;
+static Server_Module Module;
+
+/*
+ * ======== Server_init ========
+ */
+Void Server_init(Void)
+{
+ Registry_Result result;
+
+ /* register with xdc.runtime to get a diags mask */
+ result = Registry_addModule(&Registry_CURDESC, MODULE_NAME);
+ Assert_isTrue(result == Registry_SUCCESS, (Assert_Id)NULL);
+
+ /* initialize module object state */
+ Module.hostProcId = MultiProc_getId("HOST");
+}
+
+/*
+ * ======== Server_create ========
+ */
+Int Server_create()
+{
+ Int status = 0;
+ MessageQ_Params msgqParams;
+ char msgqName[32];
+
+ /* enable some log events */
+ Diags_setMask(MODULE_NAME"+EXF");
+
+ /* create local message queue (inbound messages) */
+ MessageQ_Params_init(&msgqParams);
+ sprintf(msgqName, App_SlaveMsgQueName, MultiProc_getName(MultiProc_self()));
+ Module.slaveQue = MessageQ_create(msgqName, &msgqParams);
+
+ if (Module.slaveQue == NULL) {
+ status = -1;
+ goto leave;
+ }
+
+ Log_print0(Diags_INFO,"Server_create: server is ready");
+
+leave:
+ Log_print1(Diags_EXIT, "<-- Server_create: %d", (IArg)status);
+ return (status);
+}
+
+/*
+ * ======== Server_exec ========
+ */
+Int Server_exec()
+{
+ Int status;
+ Bool running = TRUE;
+ App_Msg * msg;
+ MessageQ_QueueId queId;
+ UInt16 regionId1=1;
+ Uint32 *bigDataLocalPtr;
+ Int j;
+ UInt32 errorCount=0;
+ Int retVal;
+ bigDataLocalDesc_t bigDataLocalDesc;
+ SharedRegion_Entry srEntry;
+ void *sharedRegionAllocPtr=NULL;
+
+ Log_print0(Diags_ENTRY | Diags_INFO, "--> Server_exec:");
+
+ while (running) {
+
+ /* wait for inbound message */
+ status = MessageQ_get(Module.slaveQue, (MessageQ_Msg *)&msg,
+ MessageQ_FOREVER);
+
+ if (status < 0) {
+ goto leave;
+ }
+ Log_print1(Diags_ENTRY | Diags_INFO, "Message received...%d", msg->id);
+ switch (msg->cmd) {
+ case App_CMD_SHARED_REGION_INIT:
+ /* Create Shared region with information from init message */
+ /* Configure srEntry */
+
+ status = Resource_physToVirt((UInt32)msg->u.sharedRegionInitCfg.base,
+ (UInt32 *)&sharedRegionAllocPtr);
+ if(status != Resource_S_SUCCESS) {
+ printf("Resource_physToVirt failed \n");
+ goto leave;
+ }
+ srEntry.base = sharedRegionAllocPtr;
+ srEntry.len = msg->u.sharedRegionInitCfg.size;
+ srEntry.ownerProcId = MultiProc_self();
+ srEntry.isValid = TRUE;
+ /* Make sure CacheEnable is TRUE if using cached memory */
+ srEntry.cacheEnable = TRUE;
+ srEntry.createHeap = FALSE;
+ srEntry.cacheLineSize = 128;
+ srEntry.name = "SR1";
+
+ status = SharedRegion_setEntry (regionId1, &srEntry);
+ Log_print0(Diags_ENTRY | Diags_INFO, "Shared region entry configured...");
+
+ break;
+
+ case App_CMD_BIGDATA:
+#ifdef DEBUG
+ Log_print1(Diags_ENTRY | Diags_INFO, "msg->cmd=App_CMD_BIGDATA,msg->ptr=0x%x",
+ (IArg)msg->u.bigDataSharedDesc.sharedPtr);
+#endif
+
+ /* Translate to local descriptor */
+ retVal = bigDataXlatetoLocalAndSync(regionId1,
+ &msg->u.bigDataSharedDesc, &bigDataLocalDesc);
+ if (retVal) {
+ status = -1;
+ goto leave;
+ }
+ bigDataLocalPtr = (Uint32 *)bigDataLocalDesc.localPtr;
+#ifdef DEBUG
+ /* print message from buffer */
+ Log_print1(Diags_INFO, " Received message %d", msg->id);
+ Log_print1(Diags_INFO, " Local Pointer 0x%x", (UInt32)bigDataLocalPtr);
+ Log_print0(Diags_INFO, " First 8 bytes: ");
+ for ( j = 0; j < 8 && j < bigDataLocalDesc.size/sizeof(uint32_t); j+=4)
+ Log_print4(Diags_INFO, "0x%x, 0x%x, 0x%x, 0x%x",
+ bigDataLocalPtr[j], bigDataLocalPtr[j+1], bigDataLocalPtr[j+2], bigDataLocalPtr[j+3]);
+ Log_print0(Diags_INFO, " Last 8 bytes: ");
+ for ( j = (bigDataLocalDesc.size/sizeof(uint32_t))-8 ;
+ j < bigDataLocalDesc.size/sizeof(uint32_t); j+=4)
+ Log_print4(Diags_INFO, "0x%x, 0x%x, 0x%x, 0x%x",
+ bigDataLocalPtr[j], bigDataLocalPtr[j+1], bigDataLocalPtr[j+2], bigDataLocalPtr[j+3]);
+#endif
+ /* Check values to see expected results */
+ for( j=0; j < bigDataLocalDesc.size/sizeof(uint32_t); j++) {
+ if ( bigDataLocalPtr[j] != (msg->id+j) ) {
+ errorCount++;
+ }
+ }
+
+ /* Fill new data */
+ for ( j=0; j < bigDataLocalDesc.size/sizeof(uint32_t); j++)
+ bigDataLocalPtr[j] = msg->id + 10 +j;
+
+ /* Translate to Shared Descriptor and Sync */
+ retVal = bigDataXlatetoGlobalAndSync(regionId1,
+ &bigDataLocalDesc, &msg->u.bigDataSharedDesc);
+ if (retVal) {
+ status = -1;
+ goto leave;
+ }
+ break;
+
+ case App_CMD_SHUTDOWN:
+ running = FALSE;
+ break;
+
+ default:
+ break;
+ }
+
+ /* process the message */
+ Log_print2(Diags_INFO, "Server_exec: processed id %d, cmd=0x%x", msg->id, msg->cmd);
+
+ /* send message back */
+ queId = MessageQ_getReplyQueue(msg);
+ MessageQ_put(queId, (MessageQ_Msg)msg);
+ } /* while (running) */
+
+leave:
+ /* Print error count if non-zero */
+ if (errorCount) {
+ Log_print1(Diags_INFO, "Server_exec: Error Count %d", errorCount);
+ status = -1;
+ }
+ else
+ Log_print0(Diags_INFO, "Server_exec: Data check clean");
+
+ Log_print1(Diags_EXIT, "<-- Server_exec: %d", (IArg)status);
+ return(status);
+}
+
+/*
+ * ======== Server_delete ========
+ */
+
+Int Server_delete()
+{
+ Int status;
+
+ Log_print0(Diags_ENTRY, "--> Server_delete:");
+
+ /* delete the video message queue */
+ status = MessageQ_delete(&Module.slaveQue);
+
+ if (status < 0) {
+ goto leave;
+ }
+
+leave:
+ if (status < 0) {
+ Log_error1("Server_finish: error=0x%x", (IArg)status);
+ }
+
+ /* disable log events */
+ Log_print1(Diags_EXIT, "<-- Server_delete: %d", (IArg)status);
+ Diags_setMask(MODULE_NAME"-EXF");
+
+ return(status);
+}
+
+/*
+ * ======== Server_exit ========
+ */
+
+Void Server_exit(Void)
+{
+ /*
+ * Note that there isn't a Registry_removeModule() yet:
+ * https://bugs.eclipse.org/bugs/show_bug.cgi?id=315448
+ *
+ * ... but this is where we'd call it.
+ */
+}
diff --git a/host_linux/simple_buffer_example/dsp/Server.h b/host_linux/simple_buffer_example/dsp/Server.h
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+# Copyright (c) 2012-2017 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======== Server.h ========
+ */
+
+#ifndef Server__include
+#define Server__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+Void Server_init(Void);
+Void Server_exit(Void);
+
+Int Server_create(Void);
+Int Server_exec(Void);
+Int Server_delete(Void);
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+#endif /* Server__include */
diff --git a/host_linux/simple_buffer_example/dsp/makefile b/host_linux/simple_buffer_example/dsp/makefile
--- /dev/null
@@ -0,0 +1,164 @@
+#
+# Copyright (c) 2017 Texas Instruments Incorporated - http://www.ti.com
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Texas Instruments Incorporated nor the names of
+# its contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# ======== makefile ========
+#
+
+EXBASE = ..
+include $(EXBASE)/products.mak
+
+srcs = MainDsp.c Server.c
+objs = $(addprefix bin/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.oe66,$(srcs)))
+CONFIG = bin/$(PLATFORM)/$(PROFILE)/configuro
+
+locallibsrcs = shared/bigdataxlat/bigdataxlat.c
+locallibobjs = $(addprefix bin/shared/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.oe66,$(locallibsrcs)))
+
+PKGPATH := $(BIOS_INSTALL_DIR)/packages
+PKGPATH := $(PKGPATH)+$(IPC_INSTALL_DIR)/packages
+PKGPATH := $(PKGPATH)+$(XDC_INSTALL_DIR)/packages
+
+-include $(addprefix bin/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.oe66.dep,$(srcs)))
+-include $(addprefix bin/shared/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.oe66.dep,$(locallibsrcs)))
+
+.PRECIOUS: %/compiler.opt %/linker.cmd
+.PHONY: release debug install server_dsp.x
+
+all: release
+
+debug:
+ $(MAKE) PROFILE=debug PROCLIST="$(PROCLIST)" server_dsp.x
+
+release:
+ $(MAKE) PROFILE=release PROCLIST="$(PROCLIST)" server_dsp.x
+
+server_dsp.x: bin/$(PLATFORM)/$(PROFILE)/server_dsp.xe66
+
+bin/$(PLATFORM)/$(PROFILE)/server_dsp.xe66: $(objs) $(locallibobjs) $(libs) $(CONFIG)/linker.cmd
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+ $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+bin/$(PLATFORM)/$(PROFILE)/obj/%.oe66: %.c $(CONFIG)/compiler.opt
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+ $(CC) $(CPPFLAGS) $(CFLAGS) --output_file=$@ -fc $<
+
+bin/shared/$(PLATFORM)/$(PROFILE)/obj/%.oe66: ../%.c $(CONFIG)/compiler.opt
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+ $(CC) $(CPPFLAGS) $(CFLAGS) --output_file=$@ -fc $<
+
+%/compiler.opt %/linker.cmd: Dsp.cfg ../shared/$(PLATFORM)/config.bld
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+ $(XDC_INSTALL_DIR)/xs --xdcpath="$(subst +,;,$(PKGPATH))" \
+ xdc.tools.configuro -o $(CONFIG) \
+ -t ti.targets.elf.C66 \
+ -c $(ti.targets.elf.C66) \
+ -p $(DSP_PLATFORM) \
+ -b ../shared/$(PLATFORM)/config.bld -r $(PROFILE) \
+ --cfgArgs "{ \
+ procnamelist: [$(PROC_NAME_LIST)], \
+ procname: \"$(PROC_DSP_NAME)\", \
+ profile: \"$(PROFILE)\" \
+ }" \
+ Dsp.cfg
+
+install:
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+# @$(MKDIR) $(EXEC_DIR)/debug
+# $(CP) bin/$(PLATFORM)/debug/server_dsp.xe66 $(EXEC_DIR)/debug
+ @$(MKDIR) $(EXEC_DIR)/release
+ $(CP) bin/$(PLATFORM)/release/server_dsp.xe66 $(EXEC_DIR)/release
+
+help:
+ @$(ECHO) "make # build executable"
+ @$(ECHO) "make clean # clean everything"
+
+clean::
+ $(RMDIR) bin
+
+# ======== install validation ========
+ifeq (install,$(MAKECMDGOALS))
+ifeq (,$(EXEC_DIR))
+$(error must specify EXEC_DIR)
+endif
+endif
+
+# ======== toolchain macros ========
+CGTOOLS = $(ti.targets.elf.C66)
+
+CC = $(CGTOOLS)/bin/cl6x -c
+LD = $(CGTOOLS)/bin/cl6x -z
+
+CPPFLAGS =
+CFLAGS = -qq -pdsw225 -ppd=$@.dep -ppa $(CCPROFILE_$(PROFILE)) -@$(CONFIG)/compiler.opt -I.
+CFLAGS += -I../shared/$(PLATFORM) -I../shared/bigdataxlat -I../shared/bigdataxlat/bios
+
+# entry point is set to an aligned address so that IPC can load the slave
+LDFLAGS = -w -q -u _c_int00 -c -m $(@D)/obj/$(@F).map
+LDLIBS = -l $(CGTOOLS)/lib/libc.a
+
+CCPROFILE_debug = -D_DEBUG_=1 --symdebug:dwarf
+CCPROFILE_release = -O2
+
+# ======== standard macros ========
+ifneq (,$(wildcard $(XDC_INSTALL_DIR)/xdc.exe))
+ # use these on Windows
+ CP = $(XDC_INSTALL_DIR)/bin/cp
+ ECHO = $(XDC_INSTALL_DIR)/bin/echo
+ MKDIR = $(XDC_INSTALL_DIR)/bin/mkdir -p
+ RM = $(XDC_INSTALL_DIR)/bin/rm -f
+ RMDIR = $(XDC_INSTALL_DIR)/bin/rm -rf
+else
+ # use these on Linux
+ CP = cp
+ ECHO = echo
+ MKDIR = mkdir -p
+ RM = rm -f
+ RMDIR = rm -rf
+endif
+
+# ======== create output directories ========
+ifneq (clean,$(MAKECMDGOALS))
+ifneq (,$(PROFILE))
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj))
+ $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj)
+endif
+ifeq (,$(wildcard bin/shared/$(PLATFORM)/$(PROFILE)/obj/shared/bigdataxlat/bios))
+ $(shell $(MKDIR) -p bin/shared/$(PLATFORM)/$(PROFILE)/obj/shared/bigdataxlat/bios)
+endif
+endif
+endif
diff --git a/host_linux/simple_buffer_example/host/App.c b/host_linux/simple_buffer_example/host/App.c
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2013-2017, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======== App.c ========
+ *
+ */
+
+/* host header files */
+#include <stdio.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <ti/cmem.h>
+
+/* package header files */
+#include <ti/ipc/Std.h>
+#include "Std.h"
+#include <ti/ipc/MessageQ.h>
+#include "HeapMem.h"
+#include "SharedRegion.h"
+#include "MemoryDefs.h"
+
+/* local header files */
+#include "../shared/AppCommon.h"
+#include "App.h"
+
+/* Application specific defines */
+#define BIG_DATA_POOL_SIZE 0x1000000
+
+/* round up the value 'size' to the next 'align' boundary */
+#define ROUNDUP(size, align) \
+ (UInt32)(((UInt32)(size) + ((UInt32)(align) - 1)) & ~((UInt32)(align) - 1))
+
+/* module structure */
+typedef struct {
+ MessageQ_Handle hostQue; // created locally
+ MessageQ_QueueId slaveQue; // opened remotely
+ UInt16 heapId; // MessageQ heapId
+ UInt32 msgSize;
+} App_Module;
+
+/* private data */
+static App_Module Module;
+
+/*
+ * ======== App_create ========
+ */
+
+Int App_create(UInt16 remoteProcId)
+{
+ Int status = 0;
+ MessageQ_Params msgqParams;
+ char msgqName[32];
+
+ printf("--> App_create:\n");
+
+ /* setting default values */
+ Module.hostQue = NULL;
+ Module.slaveQue = MessageQ_INVALIDMESSAGEQ;
+ Module.heapId = App_MsgHeapId;
+ Module.msgSize = sizeof(App_Msg);
+
+ /* create local message queue (inbound messages) */
+ MessageQ_Params_init(&msgqParams);
+
+ Module.hostQue = MessageQ_create(App_HostMsgQueName, &msgqParams);
+
+ if (Module.hostQue == NULL) {
+ printf("App_create: Failed creating MessageQ\n");
+ status = -1;
+ goto leave;
+ }
+
+ /* open the remote message queue */
+ sprintf(msgqName, App_SlaveMsgQueName, MultiProc_getName(remoteProcId));
+
+ do {
+ status = MessageQ_open(msgqName, &Module.slaveQue);
+ sleep(1);
+ } while (status == MessageQ_E_NOTFOUND);
+
+ if (status < 0) {
+ printf("App_create: Failed opening MessageQ\n");
+ goto leave;
+ }
+
+ printf("App_create: Host is ready\n");
+
+leave:
+ printf("<-- App_create:\n");
+ return(status);
+}
+
+/*
+ * ======== App_delete ========
+ */
+Int App_delete(Void)
+{
+ Int status;
+
+ printf("--> App_delete:\n");
+
+ /* close remote resources */
+ status = MessageQ_close(&Module.slaveQue);
+
+ if (status < 0) {
+ goto leave;
+ }
+
+ /* delete the host message queue */
+ status = MessageQ_delete(&Module.hostQue);
+
+ if (status < 0) {
+ goto leave;
+ }
+
+leave:
+ printf("<-- App_delete:\n");
+ return(status);
+}
+
+/*
+ * ======== App_exec ========
+ */
+Int App_exec(Void)
+{
+ Int status;
+ App_Msg * msg;
+ UInt32 *bigDataLocalPtr;
+ Int i,j;
+ UInt16 regionId1=1;
+ SharedRegion_Entry *pSrEntry;
+ void *sharedRegionAllocPtr=NULL;
+ Int pool_id;
+ CMEM_AllocParams cmemAttrs;
+ HeapMem_Handle sr1Heap;
+ UInt16 regionId;
+ UInt32 errorCount=0;
+ Int retVal;
+ bigDataLocalDesc_t bigDataLocalDesc;
+ SharedRegion_Config sharedRegionConfig;
+ SharedRegion_Entry srEntry;
+ HeapMem_Config HeapMemConfig;
+ HeapMem_Params heapMem_params;
+ Memory_Stats stats;
+ HeapMem_ExtendedStats extStats;
+
+ printf("--> App_exec:\n");
+
+ /* CMEM: contiguous memory manager for HLOS */
+ /* initialised here */
+ status = CMEM_init();
+
+ if (status < 0) {
+ printf("CMEM_init failed\n");
+ goto leave;
+ }
+ else {
+ printf("CMEM_init success\n");
+ }
+
+ pool_id = CMEM_getPool(BIG_DATA_POOL_SIZE);
+ if (pool_id < 0) {
+ printf("CMEM_getPool failed\n");
+ goto leave;
+ }
+ printf("CMEM_getPool success\n");
+
+ cmemAttrs.type = CMEM_HEAP;
+ cmemAttrs.flags = CMEM_CACHED;
+ cmemAttrs.alignment = 0;
+ sharedRegionAllocPtr = CMEM_allocPool(pool_id, &cmemAttrs);
+ if (sharedRegionAllocPtr == NULL) {
+ printf("CMEM_allocPool failed\n");
+ goto leave;
+ }
+ printf("CMEM_allocPool success: Allocated buffer %p\n", sharedRegionAllocPtr);
+
+ /* Create shared region */
+ SharedRegion_getConfig (&sharedRegionConfig);
+ status = SharedRegion_setup (&sharedRegionConfig);
+ if (status < 0) {
+ printf("SharedRegion_setup failed\n");
+ goto leave;
+ }
+ printf("SharedRegion_setup success\n");
+
+ /* Configure srEntry */
+ srEntry.base = sharedRegionAllocPtr;
+ srEntry.len = BIG_DATA_POOL_SIZE;
+ srEntry.ownerProcId = MultiProc_self();
+ /* Make sure this is enabled if using Cached memory */
+ srEntry.isValid = TRUE;
+ srEntry.cacheEnable = TRUE;
+ srEntry.createHeap = FALSE;
+ srEntry.cacheLineSize = 128;
+ srEntry.name = "SR1";
+
+ status = SharedRegion_setEntry (regionId1, &srEntry);
+
+ pSrEntry = SharedRegion_getEntryPtr(regionId1);
+ printf("App_taskFxn: SR_1, base 0x%x, len=%x\n", (UInt32)pSrEntry->base, pSrEntry->len);
+
+ regionId = regionId1;
+
+ /* Setup HeapMem module */
+ HeapMem_getConfig (&HeapMemConfig);
+ status = HeapMem_setup (&HeapMemConfig);
+ if (status < 0) {
+ printf("HeapMem_setup failed\n");
+ goto leave;
+ }
+ printf("HeapMem_setup success\n");
+
+ /* Create HeapMP at run-time:
+ This heap is intended to be used for big data ipc */
+ HeapMem_Params_init(&heapMem_params);
+ heapMem_params.name = "sr1HeapMem";
+ heapMem_params.sharedAddr = pSrEntry->base;
+ heapMem_params.sharedBufSize = ROUNDUP(pSrEntry->len, pSrEntry->cacheLineSize);
+ heapMem_params.gate = NULL;
+ sr1Heap = HeapMem_create(&heapMem_params);
+ if (!sr1Heap) {
+ printf("sr1Heap creation failed\n");
+ status = -1;
+ goto leave;
+ }
+ printf("HeapMem_create success\n");
+ HeapMem_getStats((HeapMem_Handle)sr1Heap, &stats);
+ printf("App_taskFxn: SR_1 heap, totalSize=%d,totalFreeSize=%d,largestFreeSize=%d\n", stats.totalSize, stats.totalFreeSize, stats.largestFreeSize);
+ HeapMem_getExtendedStats((HeapMem_Handle)sr1Heap, &extStats);
+ printf("App_taskFxn: SR_1 heap, buf=0x%p,size=%d\n", extStats.buf, extStats.size);
+
+ /* fill process pipeline */
+ for (i = 1; i <= 3; i++) {
+ printf("App_exec: sending message %d\n", i);
+
+ /* allocate message */
+ msg = (App_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
+
+ if (msg == NULL) {
+ status = -1;
+ goto leave;
+ }
+
+ /* set the return address in the message header */
+ MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
+
+ if ( i == 1) {
+ /* fill in message payload for Shared region init*/
+ msg->cmd = App_CMD_SHARED_REGION_INIT;
+ msg->id = i;
+ msg->regionId = regionId;
+ /* Passing the local shared memory address to the remote */
+ /* Actually this can be any allocated buffer for the used for the heap */
+ msg->u.sharedRegionInitCfg.base = CMEM_getPhys(pSrEntry->base);
+ printf("Shared memory phys Addr %llx\n", msg->u.sharedRegionInitCfg.base);
+ if (!msg->u.sharedRegionInitCfg.base) {
+ printf("CMEM_getPhys failed\n");
+ }
+ msg->u.sharedRegionInitCfg.size = (UInt64)(pSrEntry->len);
+ } else {
+ /* fill in message payload */
+ msg->cmd = App_CMD_NOP;
+ msg->id = i;
+ }
+
+ /* send message */
+ MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
+ }
+
+ /* process steady state (keep pipeline full) */
+ for (i = 4; i <= 16; i++) {
+
+ /* Now this section of code starts receiving messages
+ See the next section for the code for sending further messages */
+ /* Receive messages: Start <======================================= */
+
+ /* wait for return message */
+ status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
+ MessageQ_FOREVER);
+
+ if (status < 0) {
+ goto leave;
+ }
+
+ /* extract message payload */
+
+ if (msg->cmd == App_CMD_BIGDATA) {
+
+ retVal = bigDataXlatetoLocalAndSync(msg->regionId,
+ &msg->u.bigDataSharedDesc, &bigDataLocalDesc);
+ if (retVal) {
+ status = -1;
+ goto leave;
+ }
+ bigDataLocalPtr = (UInt32 *)bigDataLocalDesc.localPtr;
+#ifdef DEBUG
+ /* print data from big data buffer */
+ printf(" Received back buffer %d\n", msg->id);
+ printf(" First 8 bytes: \n");
+ for ( j = 0; j < 8 && j < bigDataLocalDesc.size/sizeof(uint32_t); j+=4)
+ printf("0x%x, 0x%x, 0x%x, 0x%x\n",
+ bigDataLocalPtr[j], bigDataLocalPtr[j+1], bigDataLocalPtr[j+2], bigDataLocalPtr[j+3]);
+ printf(" Last 8 bytes: \n");
+ for ( j = (bigDataLocalDesc.size/sizeof(uint32_t))-8 ;
+ j < bigDataLocalDesc.size/sizeof(uint32_t); j+=4)
+ printf("0x%x, 0x%x, 0x%x, 0x%x\n",
+ bigDataLocalPtr[j], bigDataLocalPtr[j+1], bigDataLocalPtr[j+2], bigDataLocalPtr[j+3]);
+#endif
+ /* Check values to see expected results */
+ for( j=0; j < bigDataLocalDesc.size/sizeof(uint32_t); j++) {
+ if ( bigDataLocalPtr[j] != (msg->id+10+j) ) {
+ errorCount++;
+ }
+ }
+
+ /* Free big data buffer */
+ HeapMem_free(sr1Heap, bigDataLocalPtr, bigDataLocalDesc.size);
+ }
+
+ printf("App_exec: message received %d\n", msg->id);
+
+ /* free the message */
+ MessageQ_free((MessageQ_Msg)msg);
+
+ printf("App_exec: Preparing message %d\n", i);
+
+ /* Receive messages: End =======================================> */
+
+ /* Send messages: Start <======================================= */
+
+ /* allocate message */
+ msg = (App_Msg *)MessageQ_alloc(Module.heapId, Module.msgSize);
+
+ if (msg == NULL) {
+ status = -1;
+ printf("MessageQ_alloc failed\n");
+ goto leave;
+ }
+
+ /* set the return address in the message header */
+ MessageQ_setReplyQueue(Module.hostQue, (MessageQ_Msg)msg);
+
+ /* fill in message payload */
+ if (i < 14) {
+
+ /* Send Big data messages */
+
+ msg->cmd = App_CMD_BIGDATA;
+ msg->id = i;
+
+ /* Allocate buffer from HeapMem */
+ bigDataLocalPtr = (UInt32 *)(HeapMem_alloc(sr1Heap, BIGDATA_BUF_SIZE, BIGDATA_BUF_ALIGN));
+
+ if (!bigDataLocalPtr) {
+ status = -1;
+ printf("HeapMem_alloc failed\n");
+ goto leave;
+ }
+
+ /* Fill Big data buffer */
+ for(j=0; j< BIGDATA_BUF_SIZE/sizeof(uint32_t); j++) {
+ bigDataLocalPtr[j] = j+i;
+ }
+
+ /* Populate the Local descriptor */
+ bigDataLocalDesc.localPtr = (Ptr)bigDataLocalPtr;
+ bigDataLocalDesc.size = BIGDATA_BUF_SIZE;
+
+ retVal = bigDataXlatetoGlobalAndSync(regionId,
+ &bigDataLocalDesc, &msg->u.bigDataSharedDesc);
+ if (retVal) {
+ status = -1;
+ printf("bigDataXlatetoGlobalAndSync failed\n");
+ goto leave;
+ }
+ msg->regionId = regionId;
+ } else {
+ if (i == 16) {
+ /* Last message will tell the slave to shutdown */
+ msg->cmd = App_CMD_SHUTDOWN;
+ msg->id = i;
+ } else {
+ /* Send dummy NOP messages before shutdown */
+ msg->cmd = App_CMD_NOP;
+ msg->id = i;
+ }
+ }
+ printf("App_exec: Sending message %d\n", i);
+
+ /* send message */
+ MessageQ_put(Module.slaveQue, (MessageQ_Msg)msg);
+
+ /* Send messages: End =======================================> */
+
+ }
+
+ /* drain process pipeline */
+ for (i = 1; i <= 3; i++) {
+
+ /* wait for return message */
+ status = MessageQ_get(Module.hostQue, (MessageQ_Msg *)&msg,
+ MessageQ_FOREVER);
+
+ if (status < 0) {
+ printf("MessageQ_get failed\n");
+ goto leave;
+ }
+ printf("App_exec: message received: %d\n", msg->id);
+
+ /* extract message payload */
+
+ /* free the message */
+ MessageQ_free((MessageQ_Msg)msg);
+ }
+
+leave:
+ if (sr1Heap) {
+ HeapMem_delete(&sr1Heap);
+ }
+ if (sharedRegionAllocPtr) {
+ /* free the message */
+ CMEM_free(sharedRegionAllocPtr, &cmemAttrs);
+ }
+ /* Print error count if non-zero */
+ if (errorCount) {
+ printf("App_exec: Error Count %d\n", errorCount);
+ status = -1;
+ }
+ else
+ printf("App_exec: Data check clean\n");
+
+ printf("<-- App_exec: %d\n", status);
+ return(status);
+}
diff --git a/host_linux/simple_buffer_example/host/App.h b/host_linux/simple_buffer_example/host/App.h
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2013-2017, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======== App.h ========
+ *
+ */
+
+#ifndef App__include
+#define App__include
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+Int App_create(UInt16 remoteProcId);
+Int App_delete();
+Int App_exec();
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+#endif /* App__include */
diff --git a/host_linux/simple_buffer_example/host/GateMutex.h b/host_linux/simple_buffer_example/host/GateMutex.h
--- /dev/null
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======== GateMutex.h ========
+ *
+ * Gate based on Mutex
+ *
+ */
+
+#ifndef GATEMUTEX_H_0x72D0
+#define GATEMUTEX_H_0x72D0
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* =============================================================================
+ * Status codes
+ * =============================================================================
+ */
+/*!
+ * @def GateMutex_E_INVALIDARG
+ * @brief Argument passed to a function is invalid.
+ */
+#define GateMutex_E_INVALIDARG -1
+
+/*!
+ * @def GateMutex_E_MEMORY
+ * @brief Memory allocation failed.
+ */
+#define GateMutex_E_MEMORY -2
+
+/*!
+ * @def GateMutex_E_BUSY
+ * @brief The name is already registered or not.
+ */
+#define GateMutex_E_BUSY -3
+
+/*!
+ * @def GateMutex_E_FAIL
+ * @brief Generic failure.
+ */
+#define GateMutex_E_FAIL -4
+
+/*!
+ * @def GateMutex_E_NOTFOUND
+ * @brief Name not found in the nameserver.
+ */
+#define GateMutex_E_NOTFOUND -5
+
+/*!
+ * @def GateMutex_E_INVALIDSTATE
+ * @brief Module is not initialized.
+ */
+#define GateMutex_E_INVALIDSTATE -6
+
+/*!
+ * @def GateMutex_E_INUSE
+ * @brief Indicates that the instance is in use.
+ */
+#define GateMutex_E_INUSE -7
+
+/*!
+ * @def GateMutex_S_SUCCESS
+ * @brief Operation successful.
+ */
+#define GateMutex_S_SUCCESS 0
+
+
+/* =============================================================================
+ * Macros and types
+ * =============================================================================
+ */
+/*! @brief Object for Gate Mutex */
+typedef struct GateMutex_Object GateMutex_Object;
+
+/*! @brief Handle for Gate Mutex */
+typedef struct GateMutex_Object * GateMutex_Handle;
+
+/*! No parameters for GateMutex creation */
+typedef Void GateMutex_Params;
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+/* Function to create a GateMutex */
+GateMutex_Handle
+GateMutex_create (const GateMutex_Params * params, Error_Block *eb);
+
+/* Function to delete a Gate Mutex */
+Int GateMutex_delete (GateMutex_Handle * gmHandle);
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* GATEMUTEX_H_0x72D0 */
diff --git a/host_linux/simple_buffer_example/host/HeapMem/HeapMem.h b/host_linux/simple_buffer_example/host/HeapMem/HeapMem.h
--- /dev/null
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**
+ * @file ti/ipc/HeapMem.h
+ *
+ * @brief Multi-processor variable size buffer heap implementation
+ *
+ * @note HeapMem is currently only available for SYS/BIOS.
+ *
+ * HeapMem is a heap implementation that manages variable size buffers that
+ * can be used in a multiprocessor system with shared memory. HeapMem
+ * manages a single buffer in shared memory from which blocks of user-
+ * specified length are allocated and freed.
+ *
+ * The HeapMem module uses a NameServer instance to
+ * store instance information when an instance is created. The name supplied
+ * must be unique for all HeapMem instances.
+ *
+ * HeapMem_create() initializes the shared memory as needed. Once an
+ * instance is created, HeapMem_open() can be called. The
+ * open is used to gain access to the same HeapMem instance.
+ * Generally an instance is created on one processor and opened on the
+ * other processor(s).
+ *
+ * The open returns a HeapMem instance handle like the create,
+ * however the open does not modify the shared memory.
+ *
+ * Because HeapMem is a variable-size heap implementation, it is also used
+ * by the SharedRegion module to manage shared memory in each shared
+ * region. When any shared memory IPC instance is created in a
+ * particular shared region, the HeapMem that manages shared memory in the
+ * shared region allocates shared memory for the instance.
+ *
+ * The HeapMem header should be included in an application as follows:
+ * @code
+ * #include <ti/ipc/HeapMem.h>
+ * @endcode
+ */
+
+#ifndef ti_ipc_HeapMem__include
+#define ti_ipc_HeapMem__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+#include <ti/ipc/GateMP.h>
+
+/* =============================================================================
+ * All success and failure codes for the module
+ * =============================================================================
+ */
+
+/*!
+ * @brief The resource is still in use
+ */
+#define HeapMem_S_BUSY 2
+
+/*!
+ * @brief The module has been already setup
+ */
+#define HeapMem_S_ALREADYSETUP 1
+
+/*!
+ * @brief Operation is successful.
+ */
+#define HeapMem_S_SUCCESS 0
+
+/*!
+ * @brief Generic failure.
+ */
+#define HeapMem_E_FAIL -1
+
+/*!
+ * @brief Argument passed to function is invalid.
+ */
+#define HeapMem_E_INVALIDARG -2
+
+/*!
+ * @brief Operation resulted in memory failure.
+ */
+#define HeapMem_E_MEMORY -3
+
+/*!
+ * @brief The specified entity already exists.
+ */
+#define HeapMem_E_ALREADYEXISTS -4
+
+/*!
+ * @brief Unable to find the specified entity.
+ */
+#define HeapMem_E_NOTFOUND -5
+
+/*!
+ * @brief Operation timed out.
+ */
+#define HeapMem_E_TIMEOUT -6
+
+/*!
+ * @brief Module is not initialized.
+ */
+#define HeapMem_E_INVALIDSTATE -7
+
+/*!
+ * @brief A failure occurred in an OS-specific call */
+#define HeapMem_E_OSFAILURE -8
+
+/*!
+ * @brief Specified resource is not available */
+#define HeapMem_E_RESOURCE -9
+
+/*!
+ * @brief Operation was interrupted. Please restart the operation */
+#define HeapMem_E_RESTART -10
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+
+/*!
+ * @brief HeapMem_Handle type
+ */
+typedef struct HeapMem_Object *HeapMem_Handle;
+
+/*!
+ * @brief Structure defining parameters for the HeapMem module.
+ *
+ * @sa HeapMem_create()
+ */
+typedef struct HeapMem_Params {
+ String name;
+ /*!< Name of this instance.
+ *
+ * The name (if not NULL) must be unique among all HeapMem
+ * instances in the entire system. When creating a new
+ * heap, it is necessary to supply an instance name.
+ *
+ * The name does not have to be persistent. The supplied string is copied
+ * into persistent memory.
+ */
+
+ UInt16 regionId;
+ /*!< Shared region ID
+ *
+ * The index corresponding to the shared region from which shared memory
+ * will be allocated.
+ */
+
+ /*! @cond */
+ Ptr sharedAddr;
+ /*!< Physical address of the shared memory
+ *
+ * This value can be left as 'null' unless it is required to place the
+ * heap at a specific location in shared memory. If sharedAddr is null,
+ * then shared memory for a new instance will be allocated from the
+ * heap belonging to the region identified by #HeapMem_Params.regionId.
+ */
+ /*! @endcond */
+
+ SizeT sharedBufSize;
+ /*!< Size of shared buffer
+ *
+ * This is the size of the buffer to be used in the HeapMem instance.
+ * The actual buffer size in the created instance might actually be less
+ * than the value supplied in 'sharedBufSize' because of alignment
+ * constraints.
+ *
+ * It is important to note that the total amount of shared memory required
+ * for a HeapMem instance will be greater than the size supplied here.
+ * Additional space will be consumed by shared instance attributes and
+ * alignment-related padding.
+ */
+
+ GateMP_Handle gate;
+ /*!< GateMP used for critical region management of the shared memory
+ *
+ * Using the default value of NULL will result in use of the GateMP
+ * system gate for context protection.
+ */
+
+} HeapMem_Params;
+
+/*!
+ * @brief Stats structure for HeapMem_getExtendedStats()
+ *
+ * @sa HeapMem_getExtendedStats()
+ */
+typedef struct HeapMem_ExtendedStats {
+ Ptr buf;
+ /*!< Local address of the shared buffer */
+
+ SizeT size;
+ /*!< Size of the shared buffer */
+} HeapMem_ExtendedStats;
+
+/*!
+ * @brief Structure defining config parameters for the HeapMem module.
+ */
+typedef struct HeapMem_Config_tag {
+ UInt32 maxNameLen;
+ /*!< Maximum length of name */
+ UInt32 maxRunTimeEntries;
+ /*!< Maximum number of entries */
+} HeapMem_Config;
+
+/* =============================================================================
+ * HeapMem Module-wide Functions
+ * =============================================================================
+ */
+/*!
+ * @brief Get the default configuration for the HeapMem module.
+ *
+ * This function can be called by the application to get their
+ * configuration parameter to HeapMem_setup filled in by
+ * the HeapMem module with the default parameters. If the
+ * user does not wish to make any change in the default parameters,
+ * this API is not required to be called.
+ *
+ * @param cfgParams Pointer to the HeapMem module configuration
+ * structure in which the default config is to be
+ * returned.
+ *
+ * @sa HeapMem_setup
+ */
+Void HeapMem_getConfig (HeapMem_Config * cfgParams);
+
+/*!
+ * @brief Setup the HeapMem module.
+ *
+ * This function sets up the HeapMem module. This function
+ * must be called before any other instance-level APIs can be
+ * invoked.
+ * Module-level configuration needs to be provided to this
+ * function. If the user wishes to change some specific config
+ * parameters, then HeapMem_getConfig can be called to get
+ * the configuration filled with the default values. After this,
+ * only the required configuration values can be changed. If the
+ * user does not wish to make any change in the default parameters,
+ * the application can simply call HeapMem_setup with NULL
+ * parameters. The default parameters would get automatically used.
+ *
+ * @param cfg Optional HeapMem module configuration. If provided
+ * as NULL, default configuration is used.
+ *
+ * @sa HeapMem_destroy
+ * HeapMem_getConfig
+ * NameServer_create
+ * NameServer_delete
+ * GateMutex_delete
+ */
+Int HeapMem_setup (const HeapMem_Config * config);
+
+/*!
+ * @brief Close a HeapMem instance
+ *
+ * Closing an instance will free local memory consumed by the opened
+ * instance. All opened instances should be closed before the instance
+ * is deleted.
+ *
+ * @param[in,out] handlePtr Pointer to handle returned from
+ * HeapMem_open()
+ *
+ * @return HeapMem status:
+ * - #HeapMem_S_SUCCESS: Heap successfully closed
+ *
+ * @sa HeapMem_open()
+ */
+Int HeapMem_close(HeapMem_Handle *handlePtr);
+
+/*!
+ * @brief Create a HeapMem instance
+ *
+ * @param[in] params HeapMem parameters
+ *
+ * @return HeapMem Handle
+ *
+ * @sa HeapMem_delete()
+ */
+HeapMem_Handle HeapMem_create(const HeapMem_Params *params);
+
+/*!
+ * @brief Delete a created HeapMem instance
+ *
+ * @param[in,out] handlePtr Pointer to handle to delete.
+ *
+ * @return HeapMem status:
+ * - #HeapMem_S_SUCCESS: Heap successfully deleted
+ *
+ * @sa HeapMem_create()
+ */
+Int HeapMem_delete(HeapMem_Handle *handlePtr);
+
+/*!
+ * @brief Open a created HeapMem instance
+ *
+ * Once an instance is created, an open can be performed. The
+ * open is used to gain access to the same HeapMem instance.
+ * Generally an instance is created on one processor and opened on the
+ * other processor.
+ *
+ * The open returns a HeapMem instance handle like the create,
+ * however the open does not initialize the shared memory. The supplied
+ * name is used to identify the created instance.
+ *
+ * Call #HeapMem_close when the opened instance is not longer needed.
+ *
+ * @param[in] name Name of created HeapMem instance
+ * @param[out] handlePtr Pointer to HeapMem handle to be opened
+ *
+ * @return HeapMem status:
+ * - #HeapMem_S_SUCCESS: Heap successfully opened
+ * - #HeapMem_E_NOTFOUND: Heap is not yet ready to be opened.
+ * - #HeapMem_E_FAIL: A general failure has occurred
+ *
+ * @sa HeapMem_close
+ */
+Int HeapMem_open(String name, HeapMem_Handle *handlePtr);
+
+/*! @cond */
+Int HeapMem_openByAddr(Ptr sharedAddr, HeapMem_Handle *handlePtr);
+
+/*! @endcond */
+
+/*!
+ * @brief Initialize a HeapMem parameters struct
+ *
+ * @param[out] params Pointer to creation parameters
+ *
+ * @sa HeapMem_create()
+ */
+Void HeapMem_Params_init(HeapMem_Params *params);
+
+/*! @cond */
+/*!
+ * @brief Amount of shared memory required for creation of each instance
+ *
+ * @param[in] params Pointer to the parameters that will be used in
+ * the create.
+ *
+ * @return Number of MAUs needed to create the instance.
+ */
+SizeT HeapMem_sharedMemReq(const HeapMem_Params *params);
+
+/*! @endcond */
+
+/* =============================================================================
+ * HeapMem Per-instance Functions
+ * =============================================================================
+ */
+
+/*!
+ * @brief Allocate a block of memory of specified size and alignment
+ *
+ * The actual block returned may be larger than requested to satisfy
+ * alignment requirements. NULL is returned if the alloc fails.
+ *
+ * HeapMem_alloc will lock the heap using the HeapMem gate
+ * while it traverses the list of free blocks to find a large enough block
+ * for the request.
+ *
+ * Guidelines for using large heaps and multiple alloc() calls.
+ * - If possible, allocate larger blocks first. Previous allocations
+ * of small memory blocks can reduce the size of the blocks
+ * available for larger memory allocations.
+ * - Realize that allocation can fail even if the heap contains a
+ * sufficient absolute amount of unallocated space. This is
+ * because the largest free memory block may be smaller than
+ * total amount of unallocated memory.
+ *
+ * @param[in] handle Handle to previously created/opened instance.
+ * @param[in] size Size to be allocated (in MADUs)
+ * @param[in] align Alignment for allocation (power of 2)
+ *
+ * @sa HeapMem_free()
+ */
+Void *HeapMem_alloc(HeapMem_Handle handle, SizeT size, SizeT align);
+
+/*!
+ * @brief Frees a block of memory.
+ *
+ * HeapMem_free() places the memory block specified by addr and size back
+ * into the free pool of the heap specified. The newly freed block is combined
+ * with any adjacent free blocks. The space is then available for future
+ * allocations.
+ *
+ * HeapMem_free() will lock the heap using the HeapMem gate if one is
+ * specified or the system GateMP if not.
+ *
+ * @param[in] handle Handle to previously created/opened instance.
+ * @param[in] block Block of memory to be freed.
+ * @param[in] size Size to be freed (in MADUs)
+ *
+ * @sa HeapMem_alloc()
+ */
+Void HeapMem_free(HeapMem_Handle handle, Ptr block, SizeT size);
+
+/*!
+ * @brief Get extended memory statistics
+ *
+ * This function retrieves extended statistics for a HeapMem
+ * instance. Refer to #HeapMem_ExtendedStats for more information
+ * regarding what information is returned.
+ *
+ * @param[in] handle Handle to previously created/opened instance.
+ * @param[out] stats ExtendedStats structure
+ *
+ * @sa HeapMem_getStats
+ */
+Void HeapMem_getExtendedStats(HeapMem_Handle handle,
+ HeapMem_ExtendedStats *stats);
+
+/*!
+ * @brief Get memory statistics
+ *
+ * @param[in] handle Handle to previously created/opened instance.
+ * @param[out] stats Memory statistics structure
+ *
+ * @sa HeapMem_getExtendedStats()
+ */
+Void HeapMem_getStats(HeapMem_Handle handle, Ptr stats);
+
+/*!
+ * @brief Restore an instance to it's original created state.
+ *
+ * This function restores an instance to
+ * its original created state. Any memory previously allocated from the
+ * heap is no longer valid after this API is called. This function
+ * does not check whether there is allocated memory or not.
+ *
+ * @param[in] handle Handle to previously created/opened instance.
+ */
+Void HeapMem_restore(HeapMem_Handle handle);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+#endif /* ti_ipc_HeapMem__include */
diff --git a/host_linux/simple_buffer_example/host/HeapMem/src/HeapMem.c b/host_linux/simple_buffer_example/host/HeapMem/src/HeapMem.c
--- /dev/null
@@ -0,0 +1,2371 @@
+/*
+ * @file HeapMem.c
+ *
+ * @brief Defines HeapMem based memory allocator.
+ *
+ * HeapMem is a heap implementation that manages variable size buffers that
+ * can be used in a multiprocessor system with shared memory. HeapMem
+ * manages a single buffer in shared memory from which blocks of user-
+ * specified length are allocated and freed.
+ *
+ * The HeapMem module uses a NameServerinstance to
+ * store instance information when an instance is created. The name supplied
+ * must be unique for all HeapMem instances.
+ *
+ * The create initializes the shared memory as needed. Once an
+ * instance is created, an open can be performed. The
+ * open is used to gain access to the same HeapMem instance.
+ * Generally an instance is created on one processor and opened on the
+ * other processor(s).
+ *
+ * The open returns a HeapMem instance handle like the create,
+ * however the open does not modify the shared memory.
+ *
+ * Because HeapMem is a variable-size heap implementation, it is also used
+ * by Shared Region to manage shared memory in each shared
+ * region. When any shared memory IPC instance is created in a
+ * particular shared region, the HeapMem that manages shared memory in the
+ * shared region allocates shared memory for the instance.
+ *
+ *
+ *
+ * ============================================================================
+ *
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Contact information for paper mail:
+ * Texas Instruments
+ * Post Office Box 655303
+ * Dallas, Texas 75265
+ * Contact information:
+ * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ * ============================================================================
+ *
+ */
+
+/* Standard headers */
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* IPC headers */
+#include <ti/ipc/Std.h>
+#include "Std.h"
+#include <ti/ipc/MultiProc.h>
+#include <SharedRegion.h>
+#include <IGateProvider.h>
+#include <GateMutex.h>
+
+#include "List.h"
+#include "HeapMem.h"
+#include "Memory.h"
+#include "Cache.h"
+
+#include "_SharedRegion.h"
+
+//#define ENABLE_LOCAL_LOCK
+
+/* Module level headers */
+#include <_HeapMem.h>
+/* round up the value 'size' to the next 'align' boundary */
+#define ROUNDUP(size, align) \
+ (UInt32)(((UInt32)(size) + ((UInt32)(align) - 1)) & ~((UInt32)(align) - 1))
+
+#define SYSLINK_BUILD_OPTIMIZE
+
+/* =============================================================================
+ * Globals
+ * =============================================================================
+ */
+/*!
+ * @var HeapMem_nameServer
+ *
+ * @brief Name of the reserved NameServer used for HeapMem.
+ */
+#define HeapMem_NAMESERVER "HeapMem"
+
+/*! @brief Macro to make a correct module magic number with refCount */
+#define HeapMem_MAKE_MAGICSTAMP(x) ((HeapMem_MODULEID << 12u) | (x))
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+/*!
+ * @brief Structure defining processor related information for the
+ * module.
+ */
+typedef struct HeapMem_ProcAttrs_tag {
+ Bool creator; /*!< Creatoror opener */
+ UInt16 procId; /*!< Processor Identifier */
+ UInt32 openCount; /*!< How many times it is opened on a processor */
+} HeapMem_ProcAttrs;
+
+/* Header */
+typedef struct HeapMem_Header_tag {
+ SharedRegion_SRPtr next;
+ /* SRPtr to next header (Header *) */
+ Bits32 size;
+ /* Size of this segment (Memory.size) */
+} HeapMem_Header;
+
+/*! Structure of attributes in shared memory */
+typedef struct HeapMem_Attrs_tag {
+ Bits32 status;
+ /* Module status */
+ SharedRegion_SRPtr bufPtr;
+ /* Memory managed by instance */
+ HeapMem_Header head;
+ /* HeapMem head */
+ SharedRegion_SRPtr gateMPAddr;
+ /* GateMP SRPtr (shm safe) */
+} HeapMem_Attrs;
+
+/*!
+ * Structure for HeapMem module state
+ */
+typedef struct HeapMem_ModuleObject {
+ UInt32 refCount;
+ /*!< Reference count */
+ IGateProvider_Handle localLock;
+ /*!< Handle to lock for protecting objList */
+ List_Object objList;
+ /*!< List holding created objects */
+ HeapMem_Config cfg;
+ /*!< Current config values */
+ HeapMem_Config defaultCfg;
+ /*!< Default config values */
+ HeapMem_Params defaultInstParams;
+ /*!< Default instance creation parameters */
+} HeapMem_ModuleObject;
+
+/*!
+ * @brief Structure for the Handle for the HeapMem.
+ */
+typedef struct HeapMem_Obj_tag {
+ List_Elem listElem;
+ /* Used for creating a linked list */
+ volatile HeapMem_Attrs * attrs;
+ /* Local pointer to attrs */
+ GateMP_Handle gate;
+ /* Gate for critical regions */
+ Ptr nsKey;
+ /* Used to remove NS entry */
+ Bool cacheEnabled;
+ /* Whether to do cache calls */
+ UInt16 regionId;
+ /* SharedRegion index */
+ UInt32 allocSize;
+ /* Shared memory allocated */
+ Char * buf;
+ /* Local pointer to buf */
+ UInt32 minAlign;
+ /* Minimum alignment required */
+ UInt32 bufSize;
+ /* Buffer Size */
+ HeapMem_ProcAttrs owner;
+ /* Processor related information for owner processor */
+ Ptr top;
+ /* Pointer to the top Object */
+ HeapMem_Params params;
+ /* instance creation parameters */
+} HeapMem_Obj;
+
+/* =============================================================================
+ * Globals
+ * =============================================================================
+ */
+#if !defined(SYSLINK_BUILD_DEBUG)
+static
+#endif /* if !defined(SYSLINK_BUILD_DEBUG) */
+HeapMem_ModuleObject HeapMem_state =
+{
+ .defaultCfg.maxNameLen = 32u,
+ .defaultCfg.maxRunTimeEntries = 32u,
+ .defaultInstParams.gate = NULL,
+ .defaultInstParams.name = NULL,
+ .defaultInstParams.regionId = 0u,
+ .defaultInstParams.sharedAddr = NULL,
+ .defaultInstParams.sharedBufSize = 0,
+};
+
+/*!
+ * @var HeapMem_module
+ *
+ * @brief Pointer to the HeapMem module state.
+ */
+#if !defined(SYSLINK_BUILD_DEBUG)
+static
+#endif /* if !defined(SYSLINK_BUILD_DEBUG) */
+HeapMem_ModuleObject * HeapMem_module = &HeapMem_state;
+
+/* =============================================================================
+ * Forward declaration of internal function
+ * =============================================================================
+ */
+/*!
+ * @brief Creates a new instance of HeapMem module.
+ * This is an internal function as both HeapMem_create
+ * and HeapMem_open use the functionality.
+ *
+ * @param handlePtr Return value: Handle
+ * @param params Instance config-params structure.
+ * @param createFlag Indicates whether this is a create or open call.
+ *
+ * @sa HeapMem_delete,
+ * ListMP_Params_init
+ * ListMP_sharedMemReq
+ * Gate_enter
+ * Gate_leave
+ * GateMutex_delete
+ * NameServer_addUInt32
+ */
+Int _HeapMem_create ( HeapMem_Handle * handlePtr,
+ const HeapMem_Params * params,
+ Bool createFlag);
+
+/* slice and dice the buffer */
+Int HeapMem_postInit (HeapMem_Object * handle);
+
+/* =============================================================================
+ * APIS
+ * =============================================================================
+ */
+/* Get the default configuration for the HeapMem module. */
+Void
+HeapMem_getConfig (HeapMem_Config * cfgParams)
+{
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_getConfig", cfgParams);
+
+ GT_assert (curTrace, (cfgParams != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (cfgParams == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getConfig",
+ HeapMem_E_INVALIDARG,
+ "Argument of type (HeapMem_Config *) passed "
+ "is null!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ if ((HeapMem_module->refCount & HeapMem_MAKE_MAGICSTAMP(0)) <
+ HeapMem_MAKE_MAGICSTAMP(1)) {
+ memcpy (cfgParams,
+ &HeapMem_module->defaultCfg,
+ sizeof (HeapMem_Config));
+ }
+ else {
+ memcpy (cfgParams,
+ &HeapMem_module->cfg,
+ sizeof (HeapMem_Config));
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_ENTER, "HeapMem_getConfig");
+}
+
+/* Setup the HeapMem module. */
+Int
+HeapMem_setup (const HeapMem_Config * cfg)
+{
+ Int status = HeapMem_S_SUCCESS;
+ Error_Block eb;
+ HeapMem_Config tmpCfg;
+
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_setup", cfg);
+ Error_init (&eb);
+
+ if (cfg == NULL) {
+ HeapMem_getConfig (&tmpCfg);
+ cfg = &tmpCfg;
+ }
+
+ if (cfg == NULL) {
+ HeapMem_getConfig (&tmpCfg);
+ cfg = &tmpCfg;
+ }
+
+ /* This sets the refCount variable is not initialized, upper 16 bits is
+ * written with module Id to ensure correctness of refCount variable.
+ */
+ if((HeapMem_module->refCount & HeapMem_MAKE_MAGICSTAMP(0))
+ != HeapMem_MAKE_MAGICSTAMP(0)) {
+ HeapMem_module->refCount = HeapMem_MAKE_MAGICSTAMP(0);
+ }
+ if ( ++HeapMem_module->refCount
+ != HeapMem_MAKE_MAGICSTAMP(1u)) {
+ status = HeapMem_S_ALREADYSETUP;
+ GT_0trace (curTrace,
+ GT_2CLASS,
+ "HeapMem Module already initialized!");
+ }
+ else {
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (cfg->maxNameLen == 0) {
+ /*! @retval HeapMem_E_INVALIDARG cfg->maxNameLen passed is 0 */
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_setup",
+ status,
+ "cfg->maxNameLen passed is 0!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ /* Construct the list object */
+ List_construct (&HeapMem_module->objList, NULL);
+ /* Copy the cfg */
+ memcpy ((Ptr) &HeapMem_module->cfg,
+ (Ptr) cfg,
+ sizeof (HeapMem_Config));
+#ifdef ENABLE_LOCAL_LOCK
+ /* Create a lock for protecting list object */
+ HeapMem_module->localLock = (IGateProvider_Handle)
+ GateMutex_create ((GateMutex_Params*)NULL, &eb);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (HeapMem_module->localLock == NULL) {
+ /*! @retval HeapMem_E_FAIL Failed to create the localLock*/
+ status = HeapMem_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_setup",
+ HeapMem_E_FAIL,
+ "Failed to create the localLock!");
+ HeapMem_destroy ();
+ }
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_setup", status);
+
+ /*! @retval HeapMem_S_SUCCESS Operation successful */
+ return status;
+}
+
+/* Function to destroy the HeapMem module. */
+Int
+HeapMem_destroy (void)
+{
+ Int status = HeapMem_S_SUCCESS;
+ List_Elem * elem;
+
+ GT_0trace (curTrace, GT_ENTER, "HeapMem_destroy");
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ /*! @retval HeapMem_E_INVALIDSTATE Module was not initialized */
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_destroy",
+ status,
+ "Module was not initialized!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ if ( --HeapMem_module->refCount
+ == HeapMem_MAKE_MAGICSTAMP(0)) {
+ /* Temporarily increment refCount here. */
+ HeapMem_module->refCount =
+ HeapMem_MAKE_MAGICSTAMP(1);
+ /* Check if any HeapMem instances have not been deleted so far.
+ * If not, delete them.
+ */
+ List_traverse (elem, (List_Handle) &HeapMem_module->objList) {
+ if ( ( ((HeapMem_Obj *) elem)->owner.procId
+ == MultiProc_self ())) {
+ status = HeapMem_delete ((HeapMem_Handle*)
+ &(((HeapMem_Obj *) elem)->top));
+ }
+ else {
+ status = HeapMem_close ((HeapMem_Handle *)
+ &(((HeapMem_Obj *) elem)->top));
+ }
+ }
+
+ /* Decrease the refCount */
+ HeapMem_module->refCount =
+ HeapMem_MAKE_MAGICSTAMP(0);
+
+ /* Destruct the list object */
+ List_destruct (&HeapMem_module->objList);
+#ifdef ENABLE_LOCAL_LOCK
+ /* Delete the list lock */
+ if (HeapMem_module->localLock != NULL) {
+ status = GateMutex_delete ((GateMutex_Handle *)
+ &HeapMem_module->localLock);
+ GT_assert (curTrace, (status >= 0));
+ if (status < 0) {
+ /* Override the status to return a HeapMem status code. */
+ status = HeapMem_E_FAIL;
+ }
+ }
+#endif
+ memset (&HeapMem_module->cfg, 0, sizeof (HeapMem_Config));
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_destroy", status);
+
+ /*! @retval HeapMem_S_SUCCESS Operation successful */
+ return status;
+}
+
+/* Initialize this config-params structure with supplier-specified
+ * defaults before instance creation.
+ */
+Void
+HeapMem_Params_init (HeapMem_Params * params)
+{
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_Params_init", params);
+
+ GT_assert (curTrace, (params != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_Params_init",
+ HeapMem_E_INVALIDSTATE,
+ "Module was not initialized!");
+ }
+ else if (params == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_Params_init",
+ HeapMem_E_INVALIDARG,
+ "Argument of type (HeapMem_Params *) is "
+ "NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ memcpy (params,
+ &(HeapMem_module->defaultInstParams),
+ sizeof (HeapMem_Params));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "HeapMem_Params_init");
+}
+
+/*!
+ * @brief Creates a new instance of HeapMem module.
+ *
+ * @param params Instance config-params structure.
+ *
+ * @sa HeapMem_delete,
+ * ListMP_Params_init
+ * ListMP_sharedMemReq
+ * Gate_enter
+ * Gate_leave
+ * NameServer_addUInt32
+ */
+HeapMem_Handle
+HeapMem_create (const HeapMem_Params * params)
+{
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ Int status = HeapMem_S_SUCCESS;
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ HeapMem_Object * handle = NULL;
+ HeapMem_Params sparams;
+
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_create", params);
+
+ GT_assert (curTrace, (params != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ /*! @retval NULL if Module was not initialized */
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_create",
+ status,
+ "Module was not initialized!");
+ }
+ else if (params == NULL) {
+ /*! @retval NULL if params pointer passed is NULL */
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_create",
+ status,
+ "params pointer passed is NULL!");
+ }
+ else if (params->sharedBufSize == 0) {
+ /*! @retval HeapMem_E_INVALIDARG if Shared Buffer size cannot be 0
+ */
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_create",
+ status,
+ "Shared buffer size is 0!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ memcpy (&sparams,
+ (Ptr)params,
+ sizeof (HeapMem_Params));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ status =
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ _HeapMem_create ((HeapMem_Handle *) &handle, &sparams, TRUE);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (status < 0) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_create",
+ status,
+ "_HeapMem_create failed in HeapMem_create!");
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_create", handle);
+
+ /*! @retval Valid-Handle Operation successful*/
+ return (HeapMem_Handle) handle;
+}
+
+/* Deletes an instance of HeapMem module. */
+Int
+HeapMem_delete (HeapMem_Handle * handlePtr)
+{
+ Int status = HeapMem_S_SUCCESS;
+ HeapMem_Object * handle = NULL;
+ HeapMem_Obj * obj = NULL;
+ HeapMem_Params * params = NULL;
+ HeapMem_Handle * regionHeap = NULL;
+#ifdef ENABLE_GATEMP
+ IArg key = 0;
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key1 = 0;
+#endif
+
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_delete", handlePtr);
+
+ GT_assert (curTrace, (handlePtr != NULL));
+ GT_assert (curTrace, ((handlePtr != NULL) && (*handlePtr != NULL)));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_delete",
+ status,
+ "Module was not initialized!");
+ }
+ else if (handlePtr == NULL) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_delete",
+ status,
+ "The parameter handlePtr i.e. pointer to handle "
+ "passed is NULL!");
+ }
+ else if (*handlePtr == NULL) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_delete",
+ status,
+ "Handle passed is NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ handle = (HeapMem_Object *) (*handlePtr);
+
+ obj = (HeapMem_Obj *) handle->obj;
+
+ if (obj != NULL) {
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ /* Check if we have created the HeapMem or not */
+ if (obj->owner.procId != MultiProc_self ()) {
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_delete",
+ status,
+ "Instance was not created on this processor!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_GATEMP
+ /* Take the local lock */
+ key = GateMP_enter (obj->gate);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj->owner.openCount > 1) {
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_delete",
+ status,
+ "Unmatched open/close calls!");
+#ifdef ENABLE_GATEMP
+ /* Release the global lock */
+ GateMP_leave (obj->gate, key);
+#endif
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_LOCAL_LOCK
+ /* Remove from the local list */
+ key1 = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+ List_remove ((List_Handle) &HeapMem_module->objList,
+ &obj->listElem);
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (HeapMem_module->localLock, key1);
+#endif
+
+ params = (HeapMem_Params *) &obj->params;
+
+ if (EXPECT_TRUE(params->name != NULL)) {
+
+ Memory_free (NULL,
+ obj->params.name,
+ strlen(obj->params.name) + 1u);
+ }
+
+ /* Set status to 'not created' */
+ if (obj->attrs != NULL) {
+ obj->attrs->status = 0;
+ if (obj->cacheEnabled) {
+ Cache_wbInv ((Ptr) obj->attrs,
+ sizeof (HeapMem_Attrs),
+ Cache_Type_ALL,
+ TRUE);
+ }
+ }
+
+#ifdef ENABLE_GATEMP
+ /* Release the shared lock */
+ GateMP_leave (obj->gate, key);
+#endif
+
+ /* If necessary, free shared memory if memory is internally
+ * allocated
+ */
+ regionHeap = SharedRegion_getHeap (obj->regionId);
+
+ if ( (regionHeap != NULL)
+ && (obj->params.sharedAddr == NULL)
+ && (obj->attrs != NULL)){
+ Memory_free ((IHeap_Handle) regionHeap,
+ (Ptr) obj->attrs,
+ obj->allocSize);
+ }
+
+ /* Now free the handle */
+ Memory_free (NULL, obj, sizeof (HeapMem_Obj));
+ Memory_free (NULL, handle, sizeof (HeapMem_Object));
+ *handlePtr = NULL;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+ else {
+ Memory_free (NULL, handle, sizeof (HeapMem_Object));
+ *handlePtr = NULL;
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_delete", status);
+
+ return status;
+}
+
+/* Opens a created instance of HeapMem module. */
+Int
+HeapMem_open (String name,
+ HeapMem_Handle * handlePtr)
+{
+ Int status = HeapMem_S_SUCCESS;
+ SharedRegion_SRPtr sharedShmBase = SharedRegion_INVALIDSRPTR;
+ Ptr sharedAddr = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key = 0;
+#endif
+ Bool doneFlag = FALSE;
+ List_Elem * elem = NULL;
+
+ GT_2trace (curTrace, GT_ENTER, "HeapMem_open", name, handlePtr);
+
+ GT_assert (curTrace, (name != NULL));
+ GT_assert (curTrace, (handlePtr != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_open",
+ status,
+ "Module was not initialized!");
+ }
+ else if (name == NULL) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_open",
+ status,
+ "name passed is NULL!");
+ }
+ else if (handlePtr == NULL) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_open",
+ status,
+ "Pointer to handle instance passed is NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* First check in the local list */
+ List_traverse (elem, (List_Handle) &HeapMem_module->objList) {
+ if (((HeapMem_Obj *) elem)->params.name != NULL) {
+ if (strcmp ( ((HeapMem_Obj *)elem)->params.name, name)
+ == 0) {
+#ifdef ENABLE_LOCAL_LOCK
+ key = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+ /* Check if we have created the HeapMem or not */
+ if ( ((HeapMem_Obj *) elem)->owner.procId
+ == MultiProc_self ()) {
+ ((HeapMem_Obj *) elem)->owner.openCount++;
+ }
+
+ *handlePtr = (((HeapMem_Obj *) elem)->top);
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (HeapMem_module->localLock, key);
+#endif
+ doneFlag = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (EXPECT_TRUE (doneFlag == FALSE)) {
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ else if (EXPECT_FALSE (status < 0)) {
+ /* Override the status to return a HeapMem status code. */
+ status = HeapMem_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_open",
+ status,
+ "Failure in NameServer_get!");
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ {
+ /* Convert from shared region pointer to local address*/
+ sharedAddr = SharedRegion_getPtr (sharedShmBase);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE (sharedAddr == NULL)) {
+ status = HeapMem_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_open",
+ status,
+ "Invalid pointer received from"
+ "NameServer!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ status = HeapMem_openByAddr (sharedAddr, handlePtr);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE (status < 0)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_open",
+ status,
+ "Failed to open HeapMem handle!");
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_open", status);
+
+ return status;
+}
+
+/* Closes previously opened instance of HeapMem module. */
+Int
+HeapMem_close (HeapMem_Handle * handlePtr)
+{
+ Int status = HeapMem_S_SUCCESS;
+ HeapMem_Object * handle = NULL;
+ HeapMem_Obj * obj = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key = 0;
+#endif
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_close", handlePtr);
+
+ GT_assert (curTrace, (handlePtr != NULL));
+ GT_assert (curTrace, ((handlePtr != NULL) && (*handlePtr != NULL)));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_close",
+ status,
+ "Module was not initialized!");
+ }
+ else if (handlePtr == NULL) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_close",
+ status,
+ "The parameter handlePtr i.e. pointer to handle "
+ "passed is NULL!");
+ }
+ else if (*handlePtr == NULL) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_close",
+ status,
+ "*handlePtr passed is NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ handle = (HeapMem_Object *) (*handlePtr);
+ obj = (HeapMem_Obj *) handle->obj;
+ if (obj != NULL) {
+#ifdef ENABLE_LOCAL_LOCK
+ key = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+ if (obj->owner.procId == MultiProc_self ()) {
+ obj->owner.openCount--;
+ }
+
+ /* Check if HeapMem is opened on same processor and this is the
+ * last closure.
+ */
+ if ( (obj->owner.creator == FALSE)
+ && (obj->owner.openCount == 0)) {
+ List_remove ((List_Handle) &HeapMem_module->objList,
+ &obj->listElem);
+
+ if (obj->gate != NULL) {
+#ifdef ENABLE_GATEMP
+ /* Close the instance gate*/
+ GateMP_close (&obj->gate);
+#endif
+ }
+
+ /* Now free the handle */
+ Memory_free (NULL, obj, sizeof (HeapMem_Obj));
+ obj = NULL;
+ Memory_free (NULL, handle, sizeof (HeapMem_Object));
+ *handlePtr = NULL;
+ }
+
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (HeapMem_module->localLock, key);
+#endif
+ }
+ else {
+ Memory_free (NULL, handle, sizeof (HeapMem_Object));
+ *handlePtr = NULL;
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_close", status);
+
+ return status;
+}
+
+/*
+ * NOTE:
+ * Embedded within the code for HeapMem_alloc and HeapMem_free are comments
+ * that can be used to match a shared memory reference with its required
+ * cache call. This is done because the code for alloc and free is complex.
+ * These two-character comments indicate
+ * 1) The type of cache operation that is being performed {A, B}
+ * A = Cache_inv
+ * B = Cache_wbInv
+ * 2) A numerical id of the specific cache call that is performed.
+ * 1, 2, 3
+ * For example, the comment 'A2' indicates that the corresponding cache call
+ * is a Cache_inv operation identified by the number '2'
+ */
+
+/*
+ * ======== HeapMem_alloc ========
+ * HeapMem is implemented such that all of the memory and blocks it works
+ * with have an alignment that is a multiple of the minimum alignment and have
+ * a size which is a multiple of the minAlign. Maintaining this requirement
+ * throughout the implementation ensures that there are never any odd
+ * alignments or odd block sizes to deal with.
+ *
+ * Specifically:
+ * The buffer managed by HeapMem:
+ * 1. Is aligned on a multiple of obj->minAlign
+ * 2. Has an adjusted size that is a multiple of obj->minAlign
+ * All blocks on the freelist:
+ * 1. Are aligned on a multiple of obj->minAlign
+ * 2. Have a size that is a multiple of obj->minAlign
+ * All allocated blocks:
+ * 1. Are aligned on a multiple of obj->minAlign
+ * 2. Have a size that is a multiple of obj->minAlign
+ *
+ */
+
+/* Allocs a block */
+Void *
+HeapMem_alloc (HeapMem_Handle handle,
+ UInt32 reqSize,
+ UInt32 reqAlign)
+{
+ HeapMem_Obj * obj = NULL;
+ Char * allocAddr = NULL;
+#ifdef ENABLE_GATEMP
+ IArg key = 0;
+#endif
+ HeapMem_Header * prevHeader;
+ HeapMem_Header * newHeader;
+ HeapMem_Header * curHeader;
+ UInt32 curSize;
+ UInt32 adjSize;
+ UInt32 remainSize; /* free memory after allocated memory */
+ UInt32 adjAlign;
+ UInt32 offset;
+
+ GT_3trace (curTrace, GT_ENTER, "HeapMem_alloc",
+ handle, reqSize, reqAlign);
+
+ GT_assert (curTrace, (handle != NULL));
+ GT_assert (curTrace, (reqSize != 0u));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_alloc",
+ HeapMem_E_INVALIDSTATE,
+ "Module was not initialized!");
+ }
+ else if (EXPECT_FALSE (handle == NULL)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_alloc",
+ HeapMem_E_INVALIDARG,
+ "Invalid NULL handle pointer specified!");
+ }
+ else if (EXPECT_FALSE ((reqAlign & (reqAlign - 1)) != 0)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_alloc",
+ HeapMem_E_MEMORY,
+ "Requested reqAlign is not a power of 2!");
+ }
+ else if (EXPECT_FALSE (reqSize == 0)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_alloc",
+ HeapMem_E_INVALIDARG,
+ "Requested block size is zero!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj = (HeapMem_Obj *) ((HeapMem_Object *) handle)->obj;
+ GT_assert (curTrace, (obj != NULL));
+
+ adjSize = (UInt32) reqSize;
+
+ /* Make size requested a multiple of obj->minAlign */
+ if ((offset = (adjSize & (obj->minAlign - 1))) != 0) {
+ adjSize = adjSize + (obj->minAlign - offset);
+ }
+
+ /*
+ * Make sure the alignment is at least as large as obj->minAlign
+ * Note: adjAlign must be a power of 2 (by function constraint) and
+ * obj->minAlign is also a power of 2,
+ */
+ adjAlign = reqAlign;
+ if (adjAlign == 0) {
+ adjAlign = obj->minAlign;
+ }
+
+ if (adjAlign & (obj->minAlign - 1)) {
+ /* adjAlign is less than obj->minAlign */
+ adjAlign = obj->minAlign;
+ }
+
+ /* No need to Cache_inv Attrs- 'head' should be constant */
+ prevHeader = (HeapMem_Header *) &obj->attrs->head;
+
+#ifdef ENABLE_GATEMP
+ key = GateMP_enter (obj->gate);
+#endif
+
+ /*
+ * The block will be allocated from curHeader. Maintain a pointer to
+ * prevHeader so prevHeader->next can be updated after the alloc.
+ */
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_inv (prevHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE); /* A1 */
+ }
+ curHeader = (HeapMem_Header *) SharedRegion_getPtr (prevHeader->next);
+ /* A1 */
+
+ /* Loop over the free list. */
+ while (curHeader != NULL) {
+ /* Invalidate curHeader */
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_inv (curHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE); /* A2 */
+ }
+
+ curSize = curHeader->size;
+
+ /*
+ * Determine the offset from the beginning to make sure
+ * the alignment request is honored.
+ */
+ offset = (UInt32)curHeader & (adjAlign - 1);
+ if (offset) {
+ offset = adjAlign - offset;
+ }
+
+ /* Internal Assert that offset is a multiple of obj->minAlign */
+ if (((offset & (obj->minAlign - 1)) != 0)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_alloc",
+ HeapMem_E_FAIL,
+ "offset is not a multiple of"
+ " obj->minAlign!");
+ }
+ else {
+ /* big enough? */
+ if (curSize >= (adjSize + offset)) {
+ /* Set the pointer that will be returned. Alloc from front */
+ allocAddr = (Char *) ((UInt32) curHeader + offset);
+
+ /*
+ * Determine the remaining memory after the allocated block.
+ * Note: this cannot be negative because of above comparison.
+ */
+ remainSize = curSize - adjSize - offset;
+
+ /* Internal Assert that remainSize is a multiple of
+ * obj->minAlign
+ */
+ if (((remainSize & (obj->minAlign - 1)) != 0)) {
+ allocAddr = NULL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_alloc",
+ HeapMem_E_FAIL,
+ "remainSize is not a multiple of"
+ " obj->minAlign!");
+ break;
+ }
+ else {
+ /*
+ * If there is memory at the beginning (due to alignment
+ * requirements), maintain it in the list.
+ *
+ * offset and remainSize must be multiples of
+ * sizeof(HeapMem_Header). Therefore the address of the newHeader
+ * below must be a multiple of the sizeof(HeapMem_Header), thus
+ * maintaining the requirement.
+ */
+ if (offset) {
+ /* Adjust the curHeader size accordingly */
+ curHeader->size = offset; /* B2 */
+ /* Cache wb at end of this if block */
+
+ /*
+ * If there is remaining memory, add into the free list.
+ * Note: no need to coalesce and we have HeapMem locked so
+ * it is safe.
+ */
+ if (remainSize) {
+ newHeader = (HeapMem_Header *)
+ ((UInt32) allocAddr + adjSize);
+
+ /* curHeader has been inv at top of 'while' loop */
+ newHeader->next = curHeader->next; /* B1 */
+ newHeader->size = remainSize; /* B1 */
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ /* Writing back curHeader will cache-wait */
+ Cache_wbInv (newHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ FALSE); /* B1 */
+ }
+
+ curHeader->next = SharedRegion_getSRPtr
+ (newHeader,
+ obj->regionId);
+ GT_assert (curTrace,
+ ( curHeader->next
+ != SharedRegion_INVALIDSRPTR));
+ }
+
+ /* Write back (and invalidate) newHeader and curHeader */
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ /* B2 */
+ Cache_wbInv (curHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE);
+ }
+ }
+ else {
+ /*
+ * If there is any remaining, link it in,
+ * else point to the next free block.
+ * Note: no need to coalesce and we have HeapMem locked so
+ * it is safe.
+ */
+ if (remainSize) {
+ newHeader = (HeapMem_Header *)
+ ((UInt32) allocAddr + adjSize);
+
+ newHeader->next = curHeader->next; /* A2, B3 */
+ newHeader->size = remainSize; /* B3 */
+
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ /* Writing back prevHeader will cache-wait */
+ Cache_wbInv (newHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ FALSE); /* B3 */
+ }
+
+ /* B4 */
+ prevHeader->next = SharedRegion_getSRPtr (newHeader,
+ obj->regionId);
+ }
+ else {
+ /* curHeader has been inv at top of 'while' loop */
+ prevHeader->next = curHeader->next; /* A2, B4 */
+ }
+
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ /* B4 */
+ Cache_wbInv (prevHeader,
+ sizeof(HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE);
+ }
+ }
+ }
+
+ /* Success, return the allocated memory */
+ break;
+
+ }
+ else {
+ prevHeader = curHeader;
+ curHeader = SharedRegion_getPtr (curHeader->next);
+ }
+ }
+ }
+
+#ifdef ENABLE_GATEMP
+ GateMP_leave (obj->gate, key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_alloc", allocAddr);
+
+ return allocAddr;
+}
+
+/* Frees a block */
+Void
+HeapMem_free (HeapMem_Handle handle,
+ Ptr addr,
+ UInt32 size)
+{
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ Int status = HeapMem_S_SUCCESS;
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ HeapMem_Obj * obj = NULL;
+#ifdef ENABLE_GATEMP
+ IArg key = 0;
+#endif
+ HeapMem_Header * curHeader = NULL;
+ HeapMem_Header * newHeader = NULL;
+ HeapMem_Header * nextHeader= NULL;
+ SizeT offset;
+
+ GT_3trace (curTrace, GT_ENTER, "HeapMem_free", handle, addr, size);
+
+ GT_assert (curTrace, (handle != NULL));
+ GT_assert (curTrace, (addr != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_free",
+ status,
+ "Module was not initialized!");
+ }
+ else if (EXPECT_FALSE (handle == NULL)) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_free",
+ status,
+ "Invalid NULL handle pointer specified!");
+ }
+ else if (EXPECT_FALSE (addr == NULL)) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_free",
+ status,
+ "Invalid NULL addr pointer specified!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj = (HeapMem_Obj *) ((HeapMem_Object *) handle)->obj;
+ GT_assert (curTrace, (obj != NULL));
+ GT_assert (curTrace, ((UInt32)addr % obj->minAlign == 0));
+
+ /*
+ * obj->attrs never changes, doesn't need Gate protection
+ * and Cache invalidate
+ */
+ curHeader = (HeapMem_Header *) &(obj->attrs->head);
+
+ /* Restore size to actual allocated size */
+ offset = size & (obj->minAlign - 1);
+ if (offset != 0) {
+ size += obj->minAlign - offset;
+ }
+
+#ifdef ENABLE_GATEMP
+ key = GateMP_enter (obj->gate);
+#endif
+
+ newHeader = (HeapMem_Header *) addr;
+
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ /* A1 */
+ Cache_inv (curHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE);
+ }
+ nextHeader = SharedRegion_getPtr (curHeader->next);
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ /* Make sure the entire buffer is in the range of the heap. */
+ if (EXPECT_FALSE (!( ((SizeT) newHeader >= (SizeT) obj->buf)
+ && ( (SizeT) newHeader + size
+ <= (SizeT) obj->buf + obj->bufSize)))) {
+ status = HeapMem_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_free",
+ status,
+ "Entire buffer is not in the range of the heap!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* Go down freelist and find right place for buf */
+ while ((nextHeader != NULL) && (nextHeader < newHeader)) {
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_inv (nextHeader,
+ sizeof(HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE); /* A2 */
+ }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ /* Make sure the addr is not in this free block */
+ if (EXPECT_FALSE ( (SizeT) newHeader
+ < ((SizeT) nextHeader + nextHeader->size))) {
+ /* A2 */
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_free",
+ status,
+ "Address is in this free block");
+ break;
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ curHeader = nextHeader;
+ /* A2 */
+ nextHeader = SharedRegion_getPtr (nextHeader->next);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_TRUE (status >= 0)) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* B2 */
+ newHeader->next = SharedRegion_getSRPtr (nextHeader,
+ obj->regionId);
+ newHeader->size = size;
+
+ /* B1, A1 */
+ curHeader->next = SharedRegion_getSRPtr (newHeader,
+ obj->regionId);
+
+ /* Join contiguous free blocks */
+ if (nextHeader != NULL) {
+ /*
+ * Verify the free size is not overlapping. Not all cases
+ * are detectable, but it is worth a shot. Note: only do
+ * this assert if nextHeader is non-NULL.
+ */
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( ((SizeT) newHeader + size)
+ > (SizeT) nextHeader)) {
+ /* A2 */
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_free",
+ status,
+ "Free size is overlapping");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* Join with upper block */
+ if (((UInt32) newHeader + size) == (UInt32)nextHeader) {
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_inv (nextHeader,
+ sizeof(HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE);
+ }
+ newHeader->next = nextHeader->next; /* A2, B2 */
+ newHeader->size += nextHeader->size; /* A2, B2 */
+
+ /* Correct size for following Cache_wbInv. Needed
+ * due to another cache line fill caused by
+ * reading nextHeader->next
+ */
+ size += obj->minAlign;
+
+ /* Don't Cache_wbInv, this will be done later */
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_TRUE (status >= 0)) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /*
+ * Join with lower block. Make sure to check to see if not the
+ * first block. No need to invalidate attrs since head shouldn't change.
+ */
+ if ( (curHeader != &obj->attrs->head)
+ && ( ((UInt32) curHeader + curHeader->size)
+ == (UInt32) newHeader)) {
+ /*
+ * Don't Cache_inv newHeader since newHeader has
+ * data that hasn't been written back yet (B2)
+ */
+ curHeader->next = newHeader->next; /* B1, B2 */
+ curHeader->size += newHeader->size; /* B1, B2 */
+ }
+
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_wbInv (curHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ FALSE); /* B1 */
+ /*
+ * Invalidate entire buffer being freed to ensure that
+ * stale cache data in block isn't evicted later.
+ */
+ Cache_wbInv (newHeader,
+ size,
+ Cache_Type_ALL,
+ TRUE); /* B2 */
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_GATEMP
+ GateMP_leave (obj->gate, key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "HeapMem_free");
+}
+
+/* Get memory statistics */
+Void
+HeapMem_getStats (HeapMem_Handle handle,
+ Ptr stats)
+{
+ HeapMem_Obj * obj = NULL;
+ HeapMem_Header * curHeader = NULL;
+ Memory_Stats * memStats = NULL;
+#ifdef ENABLE_GATEMP
+ IArg key = 0;
+#endif
+
+ GT_2trace (curTrace, GT_ENTER, "HeapMem_getStats", handle, stats);
+
+ GT_assert (curTrace, (handle != NULL));
+ GT_assert (curTrace, (stats != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getStats",
+ HeapMem_E_INVALIDARG,
+ "Module was not initialized!");
+ }
+ else if (EXPECT_FALSE (handle == NULL)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getStats",
+ HeapMem_E_INVALIDARG,
+ "handle passed is null!");
+ }
+ else if (EXPECT_FALSE (stats == NULL)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getStats",
+ HeapMem_E_INVALIDARG,
+ "Invalid NULL stats pointer specified!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj = (HeapMem_Obj *) ((HeapMem_Object *) handle)->obj;
+ GT_assert (curTrace, (obj != NULL));
+
+ memStats = (Memory_Stats *) stats;
+
+ memStats->totalSize = obj->bufSize;
+ memStats->totalFreeSize = 0; /* determined later */
+ memStats->largestFreeSize = 0; /* determined later */
+
+#ifdef ENABLE_GATEMP
+ key = GateMP_enter(obj->gate);
+#endif
+
+ /* Invalidate curHeader */
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_inv ((Ptr) &(obj->attrs->head),
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE);
+ }
+
+ curHeader = SharedRegion_getPtr ((SharedRegion_SRPtr)
+ obj->attrs->head.next);
+
+ while (curHeader != NULL) {
+ /* Invalidate curHeader */
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_inv (curHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE);
+ }
+
+ memStats->totalFreeSize += curHeader->size;
+ if (memStats->largestFreeSize < curHeader->size) {
+ memStats->largestFreeSize = curHeader->size;
+ }
+ /* This condition is required to avoid
+ * assertions during call to SharedRegion_getPtr because at the end
+ * of the calculation curHeader->next will become
+ * SharedRegion_INVALIDSRPTR.
+ */
+ if (curHeader->next != SharedRegion_INVALIDSRPTR) {
+ curHeader = SharedRegion_getPtr ((SharedRegion_SRPtr)
+ curHeader->next);
+ }
+ else {
+ curHeader = NULL;
+ }
+ }
+
+#ifdef ENABLE_GATEMP
+ GateMP_leave(obj->gate, key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "HeapMem_getStats");
+}
+
+/* Indicate whether the heap may block during an alloc or free call */
+Bool
+HeapMem_isBlocking (HeapMem_Handle handle)
+{
+ Bool isBlocking = FALSE;
+
+ GT_1trace (curTrace, GT_ENTER, "Heap_isBlocking", handle);
+
+ GT_assert (curTrace, (handle != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE (handle == NULL)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_isBlocking",
+ HeapMem_E_INVALIDARG,
+ "handle passed is null!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* TBD: Figure out how to determine whether the gate is blocking */
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_isBlocking", isBlocking);
+
+ return isBlocking;
+}
+
+/* Get extended statistics */
+Void
+HeapMem_getExtendedStats (HeapMem_Handle handle,
+ HeapMem_ExtendedStats * stats)
+{
+ HeapMem_Obj * obj = NULL;
+
+ GT_2trace (curTrace, GT_ENTER, "HeapMem_getExtendedStats", handle, stats);
+
+ GT_assert (curTrace, (handle != NULL));
+ GT_assert (curTrace, (stats != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getExtendedStats",
+ HeapMem_E_INVALIDSTATE,
+ "Module was not initialized!");
+ }
+ else if (EXPECT_FALSE (handle == NULL)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getExtendedStats",
+ HeapMem_E_INVALIDARG,
+ "Invalid NULL handle pointer specified!");
+ }
+ else if (EXPECT_FALSE (stats == NULL)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getExtendedStats",
+ HeapMem_E_INVALIDARG,
+ "Invalid NULL stats pointer specified!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj = (HeapMem_Obj *) ((HeapMem_Object *) handle)->obj;
+ GT_assert (curTrace, (obj != NULL));
+
+ stats->buf = obj->buf;
+ stats->size = obj->bufSize;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "HeapMem_getExtendedStats");
+}
+
+/* Returns the shared memory size requirement for a single instance. */
+SizeT
+HeapMem_sharedMemReq (const HeapMem_Params * params)
+{
+ SizeT memReq = 0;
+ UInt32 minAlign;
+ UInt16 regionId;
+
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_sharedMemReq", params);
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE (params == NULL)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_sharedMemReq",
+ HeapMem_E_INVALIDARG,
+ "Params pointer passed is NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ if (params->sharedAddr == NULL) {
+ regionId = params->regionId;
+ }
+ else {
+ regionId = SharedRegion_getId(params->sharedAddr);
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (regionId == SharedRegion_INVALIDREGIONID) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_sharedMemReq",
+ HeapMem_E_FAIL,
+ "params->sharedAddr is not in a"
+ " valid SharedRegion!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ minAlign = sizeof (HeapMem_Header);
+ if (SharedRegion_getCacheLineSize(regionId) > minAlign) {
+ minAlign = SharedRegion_getCacheLineSize (regionId);
+ }
+
+ /* Add size of HeapMem Attrs */
+ memReq = ROUNDUP (sizeof(HeapMem_Attrs), minAlign);
+
+ /* Add the buffer size */
+ memReq += params->sharedBufSize;
+
+ /* Make sure the size is a multiple of minAlign (round down) */
+ memReq = (memReq / minAlign) * minAlign;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_sharedMemReq", memReq);
+
+ return memReq;
+}
+
+/*!
+ * @brief Returns the HeapMem kernel object pointer.
+ *
+ * @param handle Handle to previousely created/opened instance.
+ *
+ */
+Void *
+HeapMem_getKnlHandle (HeapMem_Handle handle)
+{
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_getKnlHandle", handle);
+
+ GT_assert (curTrace, (handle != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ /*! @retval NULL Module was not initialized */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getKnlHandle",
+ HeapMem_E_INVALIDSTATE,
+ "Module was not initialized!");
+ }
+ else if (EXPECT_FALSE (handle == NULL)) {
+ /*! @retval NULL handle passed is NULL */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_getKnlHandle",
+ HeapMem_E_INVALIDARG,
+ "handle passed is NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* Nothing to be done for kernel-side implementation. */
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_getKnlHandle", handle);
+
+ /*! @retval Kernel-Object-handle Operation successfully completed. */
+ return (handle);
+}
+
+/* HeapMem open by address */
+Int
+HeapMem_openByAddr (Ptr sharedAddr,
+ HeapMem_Handle * handlePtr)
+{
+ Int status = HeapMem_S_SUCCESS;
+ Bool doneFlag = FALSE;
+ HeapMem_Attrs * attrs = NULL;
+ List_Elem * elem = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+ UInt16 id;
+ HeapMem_Params params;
+
+ GT_2trace (curTrace, GT_ENTER, "HeapMem_openByAddr",
+ sharedAddr, handlePtr);
+
+ GT_assert (curTrace, (handlePtr != NULL));
+ GT_assert (curTrace, (sharedAddr != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( Atomic_cmpmask_and_lt (&(HeapMem_module->refCount),
+ HeapMem_MAKE_MAGICSTAMP(0),
+ HeapMem_MAKE_MAGICSTAMP(1))
+ == TRUE)) {
+ status = HeapMem_E_INVALIDSTATE;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_openByAddr",
+ status,
+ "Module was not initialized!");
+ }
+ else if (EXPECT_FALSE (handlePtr == NULL)) {
+ status = HeapMem_E_INVALIDARG;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_openByAddr",
+ status,
+ "handlePtr pointer passed is NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* First check in the local list */
+ List_traverse (elem, (List_Handle) &HeapMem_module->objList) {
+ if (((HeapMem_Obj *) elem)->params.sharedAddr == sharedAddr) {
+#ifdef ENABLE_LOCAL_LOCK
+ key = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+ if ( ((HeapMem_Obj *)elem)->owner.procId
+ == MultiProc_self ()) {
+ ((HeapMem_Obj *)elem)->owner.openCount++;
+ }
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (HeapMem_module->localLock, key);
+#endif
+ *handlePtr = (((HeapMem_Obj *)elem)->top);
+ doneFlag = TRUE;
+ break;
+ }
+ }
+
+ /* If not already existing locally, create object locally for open. */
+ if (EXPECT_FALSE (doneFlag == FALSE)) {
+ HeapMem_Params_init(¶ms);
+ params.sharedAddr = sharedAddr;
+ attrs = (HeapMem_Attrs *) sharedAddr;
+ id = SharedRegion_getId (sharedAddr);
+
+ if (EXPECT_FALSE (SharedRegion_isCacheEnabled (id))) {
+ Cache_inv (attrs,
+ sizeof (HeapMem_Attrs),
+ Cache_Type_ALL,
+ TRUE);
+ }
+
+ if (EXPECT_FALSE (attrs->status != HeapMem_CREATED)) {
+ *handlePtr = NULL;
+ status = HeapMem_E_NOTFOUND;
+ /* Don't set failure reason since this is an expected
+ * run-time failure.
+ */
+ GT_1trace (curTrace,
+ GT_3CLASS,
+ "HeapMem Instance is not created yet at the "
+ "provided shared addr.\n"
+ " sharedAddr [0x%x]!",
+ sharedAddr);
+ }
+ else {
+ status = _HeapMem_create (handlePtr, ¶ms, FALSE);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE (status < 0)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_openByAddr",
+ status,
+ "_HeapMem_create failed!");
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_openByAddr", status);
+
+ return (status);
+}
+
+/* =============================================================================
+ * Internal function
+ * =============================================================================
+ */
+GateMP_Handle HeapMem_getGate(HeapMem_Handle handle)
+{
+ HeapMem_Object * object;
+ HeapMem_Obj * obj;
+
+ object = (HeapMem_Object *)handle;
+ obj = (HeapMem_Obj *)(object->obj);
+ return(obj->gate);
+}
+
+/* Creates a new instance of HeapMem module.
+ * This is an internal function as both HeapMem_create
+ * and HeapMem_open use the functionality.
+ */
+Int
+_HeapMem_create ( HeapMem_Handle * handlePtr,
+ const HeapMem_Params * params,
+ Bool createFlag)
+{
+ Int status = HeapMem_S_SUCCESS;
+ HeapMem_Obj * obj = NULL;
+ HeapMem_Object * handle = NULL;
+#ifdef ENABLE_GATEMP
+ GateMP_Handle gateHandle = NULL;
+ Ptr localAddr = NULL;
+ SharedRegion_SRPtr sharedShmBase;
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+
+ GT_3trace (curTrace, GT_ENTER, "_HeapMem_create",
+ handlePtr, params, createFlag);
+
+ GT_assert (curTrace, (handlePtr != NULL));
+ GT_assert (curTrace, (params != NULL));
+
+ /* No need for parameter checks, since this is an internal function. */
+
+ /* Create the generic handle */
+ handle = (HeapMem_Object *) Memory_calloc (NULL,
+ sizeof (HeapMem_Object),
+ 0u,
+ NULL);
+ *handlePtr = (HeapMem_Handle) handle;
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (handle == NULL) {
+ /*! @retval HeapMem_E_MEMORY Memory allocation failed for pointer of
+ * type HeapMem_Object
+ */
+ status = HeapMem_E_MEMORY;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "_HeapMem_create",
+ status,
+ "Memory allocation failed for pointer"
+ " of type HeapMem_Object!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* Create the Heap Buf specific handle */
+ obj = (HeapMem_Obj *) Memory_calloc (NULL,
+ sizeof (HeapMem_Obj),
+ 0u,
+ NULL);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj == NULL) {
+ /*! @retval HeapMem_E_MEMORY Memory allocation failed for pointer
+ * of type HeapMem_Obj
+ */
+ status = HeapMem_E_MEMORY;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "_HeapMem_create",
+ status,
+ "Memory allocation failed for pointer"
+ " of type HeapMem_Obj");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ handle->obj = (HeapMem_Obj *) obj ;
+ handle->alloc = (IHeap_allocFxn) &HeapMem_alloc;
+ handle->free = (IHeap_freeFxn) &HeapMem_free;
+ handle->getStats = (IHeap_getStatsFxn) &HeapMem_getStats;
+ handle->getKnlHandle = (IHeap_getKnlHandleFxn)
+ &HeapMem_getKnlHandle;
+ handle->isBlocking = (IHeap_isBlockingFxn) &HeapMem_isBlocking;
+
+ obj->nsKey = NULL;
+ obj->allocSize = 0;
+
+ /* Put in the local list */
+#ifdef ENABLE_LOCAL_LOCK
+ key = IGateProvider_enter (HeapMem_module->localLock);
+#endif
+ List_elemClear (&obj->listElem);
+ List_put ((List_Handle) &HeapMem_module->objList, &obj->listElem);
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (HeapMem_module->localLock, key);
+#endif
+
+ if (createFlag == FALSE) {
+ obj->owner.creator = FALSE;
+ obj->owner.openCount = 0u;
+ obj->owner.procId = MultiProc_INVALIDID;
+ obj->top = handle;
+
+ obj->attrs = (HeapMem_Attrs *) params->sharedAddr;
+
+ /* No need to Cache_inv- already done in openByAddr() */
+ obj->buf = (Char *) SharedRegion_getPtr ((SharedRegion_SRPtr)
+ obj->attrs->bufPtr);
+ obj->bufSize = obj->attrs->head.size;
+ obj->regionId = SharedRegion_getId (obj->buf);
+ GT_assert (curTrace,
+ (obj->regionId != SharedRegion_INVALIDSRPTR));
+ obj->cacheEnabled = SharedRegion_isCacheEnabled (obj->regionId);
+
+ /* Set minAlign */
+ obj->minAlign = sizeof (HeapMem_Header); /* 64 bits = 8 bytes */
+ if ( SharedRegion_getCacheLineSize (obj->regionId)
+ > obj->minAlign) {
+ obj->minAlign = SharedRegion_getCacheLineSize (
+ obj->regionId);
+ }
+
+#ifdef ENABLE_GATEMP
+ localAddr = SharedRegion_getPtr (obj->attrs->gateMPAddr);
+ status = GateMP_openByAddr (localAddr, &gateHandle);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (status < 0) {
+ /* Override the status with a HeapMem status code. */
+ status = HeapMem_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "_HeapMem_create",
+ status,
+ "Failed to open GateMP!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj->gate = gateHandle;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#endif
+ }
+ else {
+ /* Creating the HeapMem ... */
+ obj->owner.creator = TRUE;
+ obj->owner.openCount = 1u;
+ obj->owner.procId = MultiProc_self ();
+ obj->top = handle;
+
+ /* Creating the gate */
+ if (params->gate != NULL) {
+ obj->gate = params->gate;
+ }
+#ifdef ENABLE_GATEMP
+ else {
+ /* If no gate specified, get the default system gate */
+ obj->gate = GateMP_getDefaultRemote ();
+ }
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj->gate == NULL) {
+ status = HeapMem_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "_HeapMem_create",
+ status,
+ "GateMP is NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj->bufSize = params->sharedBufSize;
+
+ if (params->sharedAddr == NULL) {
+ /* Creating using a shared region ID */
+ /* It is allowed to have NULL name for an anonymous, not
+ * to be opened by name, heap.
+ */
+ obj->attrs = NULL; /* Will be alloced in postInit */
+ obj->regionId = params->regionId;
+ }
+ else {
+ /* Creating using sharedAddr */
+ obj->regionId = SharedRegion_getId (params->sharedAddr);
+
+ /* Assert that the buffer is in a valid shared
+ * region
+ */
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj->regionId == SharedRegion_INVALIDREGIONID) {
+ status = HeapMem_E_FAIL;
+ /*! @retval HeapMem_E_FAIL params->sharedAddr is
+ not in a valid SharedRegion. */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "_HeapMem_create",
+ status,
+ "params->sharedAddr is not in"
+ " a valid SharedRegion!");
+ }
+ else if ( ((UInt32) params->sharedAddr
+ % SharedRegion_getCacheLineSize (obj->regionId)
+ != 0)) {
+ status = HeapMem_E_FAIL;
+ /*! @retval HeapMem_E_FAIL params->sharedAddr does
+ not meet cache alignment constraints */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "_ListMP_create",
+ status,
+ "params->sharedAddr does not"
+ " meet cache alignment constraints!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* obj->buf will get alignment-adjusted in
+ * postInit
+ */
+ obj->buf = (Ptr) ( (UInt32) params->sharedAddr
+ + sizeof (HeapMem_Attrs));
+ obj->attrs = (HeapMem_Attrs *) params->sharedAddr;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (status >= 0) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj->cacheEnabled = SharedRegion_isCacheEnabled (
+ obj->regionId);
+
+ /* Set minAlign */
+ obj->minAlign = sizeof (HeapMem_Header);
+ if ( SharedRegion_getCacheLineSize(obj->regionId)
+ > obj->minAlign) {
+ obj->minAlign = SharedRegion_getCacheLineSize (
+ obj->regionId);
+ }
+
+ status = HeapMem_postInit ((HeapMem_Object *)
+ handle);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE (status < 0)) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "_HeapMem_create",
+ status,
+ "HeapMem_postInit failed!");
+ }
+ }
+ }
+
+ if (status >= 0) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* Populate the params member */
+ memcpy ((Ptr) &obj->params,
+ (Ptr) params,
+ sizeof (HeapMem_Params));
+
+ /* Copy the name */
+ if (params->name != NULL) {
+ obj->params.name = (String) Memory_alloc (NULL,
+ (strlen (params->name)+ 1u),
+ 0,
+ NULL);
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj->params.name == NULL) {
+ /*! @retval HeapMem_E_MEMORY Memory allocation
+ * failed for name
+ */
+ status = HeapMem_E_MEMORY;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "_HeapMem_create",
+ status,
+ "Memory allocation "
+ "failed for name!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ strncpy (obj->params.name,
+ params->name,
+ strlen (params->name) + 1u);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+ }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (status < 0) {
+ if (createFlag == TRUE) {
+ HeapMem_delete ((HeapMem_Handle *) handlePtr);
+ }
+ else {
+ HeapMem_close ((HeapMem_Handle *) handlePtr);
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "_HeapMem_create", status);
+
+ /*! @retval HeapMem_S_SUCCESS Operation successful*/
+ return status;
+}
+
+/*
+ * Slice and dice the buffer up into the correct size blocks and
+ * add to the freelist.
+ */
+Int
+HeapMem_postInit (HeapMem_Object * handle)
+{
+ Int status = HeapMem_S_SUCCESS;
+ HeapMem_Obj * obj = NULL;
+ HeapMem_Handle regionHeap = NULL;
+ HeapMem_Params params;
+
+ GT_0trace (curTrace, GT_LEAVE, "HeapMem_postInit");
+
+ GT_assert (curTrace, (handle != NULL));
+
+ /* No need for parameter checks, since this is an internal function. */
+
+ obj = handle->obj;
+
+ if (obj->attrs == NULL) {
+ /* Need to allocate from the heap */
+ HeapMem_Params_init (¶ms);
+ params.regionId = obj->regionId;
+ params.sharedBufSize = obj->bufSize;
+ obj->allocSize = HeapMem_sharedMemReq (¶ms);
+ regionHeap = SharedRegion_getHeap (obj->regionId);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (regionHeap == NULL) {
+ status = HeapMem_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_postInit",
+ status,
+ "Shared Region heap is null!");
+
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj->attrs = Memory_alloc ((IHeap_Handle) regionHeap,
+ obj->allocSize,
+ obj->minAlign,
+ NULL);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj->attrs == NULL) {
+ status = HeapMem_E_MEMORY;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_postInit",
+ status,
+ "Failed to allocate shared memory!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj->buf = (Ptr)((UInt32)obj->attrs + sizeof(HeapMem_Attrs));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (status >= 0) {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* Round obj->buf up by obj->minAlign */
+ obj->buf = (Ptr) ROUNDUP ((obj->buf), (obj->minAlign));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (EXPECT_FALSE ( obj->bufSize
+ < SharedRegion_getCacheLineSize (obj->regionId))) {
+ status = HeapMem_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "HeapMem_postInit",
+ status,
+ "Buffer is not large enough!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* Make sure the size is a multiple of obj->minAlign */
+ obj->bufSize = (obj->bufSize / obj->minAlign) * obj->minAlign;
+#ifdef ENABLE_GATEMP
+ obj->attrs->gateMPAddr = GateMP_getSharedAddr (obj->gate);
+#endif
+ obj->attrs->bufPtr = SharedRegion_getSRPtr (obj->buf,
+ obj->regionId);
+
+ /* Store computed obj->bufSize in shared mem */
+ obj->attrs->head.size = obj->bufSize;
+
+ /* Place the initial header */
+ HeapMem_restore ((HeapMem_Handle) handle);
+
+ /* Last thing, set the status */
+ obj->attrs->status = HeapMem_CREATED;
+
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_wbInv ((Ptr) obj->attrs,
+ sizeof (HeapMem_Attrs),
+ Cache_Type_ALL,
+ TRUE);
+ }
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "HeapMem_postInit", status);
+
+ return status;
+}
+
+/* Restore an instance to it's original created state. */
+Void
+HeapMem_restore (HeapMem_Handle handle)
+{
+ HeapMem_Header * begHeader = NULL;
+ HeapMem_Obj * obj = NULL;
+
+ GT_1trace (curTrace, GT_ENTER, "HeapMem_restore", handle);
+
+ obj = ((HeapMem_Object *) handle)->obj;
+ GT_assert (curTrace, (obj != NULL));
+
+ /*
+ * Fill in the top of the memory block
+ * next: pointer will be NULL (end of the list)
+ * size: size of this block
+ * NOTE: no need to Cache_inv because obj->attrs->bufPtr should be const
+ */
+ begHeader = (HeapMem_Header *) obj->buf;
+ begHeader->next = (SharedRegion_SRPtr) SharedRegion_INVALIDSRPTR;
+ begHeader->size = obj->bufSize;
+
+ obj->attrs->head.next = obj->attrs->bufPtr;
+ if (EXPECT_FALSE (obj->cacheEnabled)) {
+ Cache_wbInv ((Ptr) &(obj->attrs->head),
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ FALSE);
+ Cache_wbInv (begHeader,
+ sizeof (HeapMem_Header),
+ Cache_Type_ALL,
+ TRUE);
+ }
+
+ GT_0trace (curTrace, GT_LEAVE, "HeapMem_restore");
+}
diff --git a/host_linux/simple_buffer_example/host/HeapMem/src/inc/_HeapMem.h b/host_linux/simple_buffer_example/host/HeapMem/src/inc/_HeapMem.h
--- /dev/null
@@ -0,0 +1,131 @@
+/**
+ * @file _HeapMem.h
+ *
+ * @brief Defines HeapMem based memory allocator.
+ *
+ *
+ */
+/*
+ * ============================================================================
+ *
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Contact information for paper mail:
+ * Texas Instruments
+ * Post Office Box 655303
+ * Dallas, Texas 75265
+ * Contact information:
+ * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ * ============================================================================
+ *
+ */
+
+
+
+#ifndef HeapMem_H_0x4C56
+#define HeapMem_H_0x4C56
+
+
+/* Osal & Utils headers */
+#include "IHeap.h"
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/*!
+ * @def HeapMem_MODULEID
+ * @brief Unique module ID.
+ */
+#define HeapMem_MODULEID (0x4AD8)
+
+/*!
+ * @var HeapMem_CREATED
+ *
+ * @brief HeapMemMp tag used in the attrs->status field
+ */
+#define HeapMem_CREATED 0x07041976
+
+/*
+ * @brief Object for the HeapMem Handle
+ */
+#define HeapMem_Object IHeap_Object
+
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+
+/*!
+ * @brief Function to destroy the HeapMem module.
+ *
+ * @param None
+ *
+ * @sa HeapMem_setup
+ * HeapMem_getConfig
+ * NameServer_create
+ * NameServer_delete
+ * GateMutex_delete
+ */
+Int HeapMem_destroy (void);
+
+/*!
+ * @brief Returns the HeapMem kernel object pointer.
+ *
+ * @param handle Handle to previousely created/opened instance.
+ *
+ */
+Ptr HeapMem_getKnlHandle (HeapMem_Handle hpHandle);
+
+/*!
+ * @brief Returns a HeapMem user object pointer.
+ *
+ * @param handle Handle to kernel handle for which user handle is to be
+ * provided.
+ *
+ */
+Ptr HeapMem_getUsrHandle (HeapMem_Handle hpHandle);
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* HeapMem_H_0x4C56 */
+
diff --git a/host_linux/simple_buffer_example/host/IGateProvider.h b/host_linux/simple_buffer_example/host/IGateProvider.h
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======= IGateProvider.h ========
+ *
+ * Interface implemented by all gate providers.
+ *
+ * Gates are used serialize access to data structures that are used by more
+ * than one thread.
+ *
+ * Gates are responsible for ensuring that only one out of multiple threads
+ * can access a data structure at a time. There
+ * are important scheduling latency and performance considerations that
+ * affect the "type" of gate used to protect each data structure. For
+ * example, the best way to protect a shared counter is to simply disable
+ * all interrupts before the update and restore the interrupt state after
+ * the update; disabling all interrupts prevents all thread switching, so
+ * the update is guaranteed to be "atomic". Although highly efficient, this
+ * method of creating atomic sections causes serious system latencies when
+ * the time required to update the data structure can't be bounded.
+ *
+ * For example, a memory manager's list of free blocks can grow indefinitely
+ * long during periods of high fragmentation. Searching such a list with
+ * interrupts disabled would cause system latencies to also become unbounded.
+ * In this case, the best solution is to provide a gate that suspends the
+ * execution of threads that try to enter a gate that has already been
+ * entered; i.e., the gate "blocks" the thread until the thread
+ * already in the gate leaves. The time required to enter and leave the
+ * gate is greater than simply enabling and restoring interrupts, but since
+ * the time spent within the gate is relatively large, the overhead caused by
+ * entering and leaving gates will not become a significant percentage of
+ * overall system time. More importantly, threads that do not need to
+ * access the shared data structure are completely unaffected by threads
+ * that do access it.
+ *
+ */
+
+#ifndef __IGATEPROVIDER_H__
+#define __IGATEPROVIDER_H__
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+
+/* -----------------------------------------------------------------------------
+ * Macros
+ * -----------------------------------------------------------------------------
+ */
+/*! Invalid Igate */
+#define IGateProvider_NULL (IGateProvider_Handle)0xFFFFFFFF
+
+/*!
+ * ======== IGateProvider_Q_BLOCKING ========
+ * Blocking quality
+ *
+ * Gates with this "quality" may cause the calling thread to block;
+ * i.e., suspend execution until another thread leaves the gate.
+ */
+#define IGateProvider_Q_BLOCKING 1
+
+/*!
+ * ======== IGateProvider_Q_PREEMPTING ========
+ * Preempting quality
+ *
+ * Gates with this "quality" allow other threads to preempt the thread
+ * that has already entered the gate.
+ */
+#define IGateProvider_Q_PREEMPTING 2
+
+/*!
+ * ======== IGateProvider_SuperObject ========
+ * Object embedded in other Gate modules. (Inheritance)
+ */
+#define IGateProvider_SuperObject \
+ IGateProvider_ENTER enter; \
+ IGateProvider_LEAVE leave
+
+
+/*!
+ *
+ */
+#define IGateProvider_ObjectInitializer(x,y) \
+ ((IGateProvider_Handle)(x))->enter = (IGateProvider_ENTER)y##_enter; \
+ ((IGateProvider_Handle)(x))->leave = (IGateProvider_LEAVE)y##_leave;
+
+/* -----------------------------------------------------------------------------
+ * Defines
+ * -----------------------------------------------------------------------------
+ */
+/*! Prototype of enter function */
+typedef IArg (*IGateProvider_ENTER) (Void *);
+
+/*! Prototype of leave function */
+typedef Void (*IGateProvider_LEAVE) (Void *, IArg);
+
+
+/* -----------------------------------------------------------------------------
+ * Structs & Enums
+ * -----------------------------------------------------------------------------
+ */
+/*!
+ * Structure for generic gate instance
+ */
+typedef struct IGateProvider_Object {
+ IGateProvider_SuperObject;
+} IGateProvider_Object, *IGateProvider_Handle;
+
+
+/* -----------------------------------------------------------------------------
+ * APIs
+ * -----------------------------------------------------------------------------
+ */
+/*!
+ * Enter this gate
+ *
+ * Each gate provider can implement mutual exclusion using different
+ * algorithms; e.g., disabling all scheduling, disabling the scheduling
+ * of all threads below a specified "priority level", suspending the
+ * caller when the gate has been entered by another thread and
+ * re-enabling it when the the other thread leaves the gate. However,
+ * in all cases, after this method returns that caller has exclusive
+ * access to the data protected by this gate.
+ *
+ * A thread may reenter a gate without blocking or failing.
+ *
+ * @param handle Handle to the Gate.
+ *
+ * @retval IArg Returns the instance specific return values.
+ *
+ * @sa IGateProvider_leave
+ *
+ */
+static inline IArg IGateProvider_enter (IGateProvider_Handle handle)
+{
+ IArg key = 0;
+
+ if (handle != 0x0 && handle != IGateProvider_NULL) {
+ key = (handle->enter) ((void *)handle);
+ }
+ return key;
+}
+
+
+/*!
+ * Leave this gate
+ *
+ * This method is only called by threads that have previously entered
+ * this gate via `{@link #enter}`. After this method returns, the
+ * caller must not access the data structure protected by this gate
+ * (unless the caller has entered the gate more than once and other
+ * calls to `leave` remain to balance the number of previous
+ * calls to `enter`).
+ *
+ * @param handle Handle to the Gate.
+ * @param key Instance specific argument.
+ *
+ * @sa IGateProvider_enter
+ *
+ */
+static inline Void IGateProvider_leave (IGateProvider_Handle handle, IArg key)
+{
+ if (handle != 0x0 && handle != IGateProvider_NULL)
+ (handle->leave) ((void *)handle, key);
+}
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* ifndef __IGATEPROVIDER_H__ */
diff --git a/host_linux/simple_buffer_example/host/SharedRegion/SharedRegion.h b/host_linux/simple_buffer_example/host/SharedRegion/SharedRegion.h
--- /dev/null
@@ -0,0 +1,521 @@
+/*
+ * Copyright (c) 2017 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+/**
+ * @file SharedRegion.h
+ *
+ * @brief Shared memory manager and address translator
+ *
+ * @note SharedRegion is currently only available for SYS/BIOS.
+ *
+ * The SharedRegion module is designed to be used in a multi-processor
+ * environment in which memory regions are shared and accessed
+ * across different processors. The module itself does not use any shared
+ * memory, because all module state is stored locally. SharedRegion
+ * APIs use the system gate for thread protection.
+ *
+ * This module creates and stores a local shared memory region table. The
+ * table contains the processor's view for every shared region in the system.
+ * The table must not contain any overlapping regions. Each processor's
+ * view of a particular shared memory region is determined by the region id.
+ * In cases where a processor cannot access a certain shared memory region,
+ * that shared memory region should be left invalid for that processor.
+ * Note: The number of entries must be the same on all processors.
+ *
+ * Each shared region contains the following:
+ * - @b base - The base address
+ * - @b len - The length
+ * - @b name - The name of the region
+ * - @b isValid - Whether the region is valid
+ * - @b ownerProcId - The id of the processor which owns the region
+ * - @b cacheEnable - Whether the region is cacheable
+ * - @b cacheLineSize - The cache line size
+ * - @b createHeap - Whether a heap is created for the region.
+ *
+ * A region is added using the SharedRegion_setEntry() API.
+ * The length of a region must be the same across all processors.
+ * The owner of the region can be specified. If specified, the owner
+ * manages the shared region. It creates a HeapMemMP instance which spans
+ * the full size of the region. The other processors open the same HeapMemMP
+ * instance.
+ *
+ * Note: Prior to calling Ipc_start(), If a SharedRegion's 'isValid'
+ * is true and 'createHeap' is true then the owner of the SharedRegion
+ * must be the same as the owner of SharedRegion 0.
+ *
+ * After a shared region is valid, SharedRegion APIs can be used to convert
+ * pointers between the local processor's address space and the SharedRegion-
+ * pointer (SRPtr) address space. These APIs include
+ * SharedRegion_getId(), SharedRegion_getSRPtr() and SharedRegion_getPtr().
+ * An example is shown below:
+ *
+ * @code
+ * SharedRegion_SRPtr srptr;
+ * Ptr addr;
+ * UInt16 id;
+ *
+ * // to get the id of the local address if id is not already known.
+ * id = SharedRegion_getId(addr);
+ *
+ * // to get the shared region pointer for the local address
+ * srptr = SharedRegion_getSRPtr(addr, id);
+ *
+ * // to get the local address from the shared region pointer
+ * addr = SharedRegion_getPtr(srptr);
+ * @endcode
+ *
+ * The SharedRegion header should be included in an application as follows:
+ * @code
+ * #include <ti/ipc/SharedRegion.h>
+ * @endcode
+ */
+
+#ifndef SharedRegion__include
+#define SharedRegion__include
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* ============================================================================
+ * All success and failure codes for the module
+ * =============================================================================
+ */
+
+/*!
+ * @brief The resource is still in use
+ */
+#define SharedRegion_S_BUSY 2
+
+/*!
+ * @brief The module has been already setup
+ */
+#define SharedRegion_S_ALREADYSETUP 1
+
+/*!
+ * @brief Operation is successful.
+ */
+#define SharedRegion_S_SUCCESS 0
+
+/*!
+ * @brief Generic failure.
+ */
+#define SharedRegion_E_FAIL -1
+
+/*!
+ * @brief Argument passed to function is invalid.
+ */
+#define SharedRegion_E_INVALIDARG -2
+
+/*!
+ * @brief Operation resulted in memory failure.
+ */
+#define SharedRegion_E_MEMORY -3
+
+/*!
+ * @brief The specified entity already exists.
+ */
+#define SharedRegion_E_ALREADYEXISTS -4
+
+/*!
+ * @brief Unable to find the specified entity.
+ */
+#define SharedRegion_E_NOTFOUND -5
+
+/*!
+ * @brief Operation timed out.
+ */
+#define SharedRegion_E_TIMEOUT -6
+
+/*!
+ * @brief Module is not initialized.
+ */
+#define SharedRegion_E_INVALIDSTATE -7
+
+/*!
+ * @brief A failure occurred in an OS-specific call
+ */
+#define SharedRegion_E_OSFAILURE -8
+
+/*!
+ * @brief Specified resource is not available
+ */
+#define SharedRegion_E_RESOURCE -9
+
+/*!
+ * @brief Operation was interrupted. Please restart the operation
+ */
+#define SharedRegion_E_RESTART -10
+
+/* =============================================================================
+ * Macros
+ * =============================================================================
+ */
+
+/*!
+ * @brief Invalid region id
+ */
+#define SharedRegion_INVALIDREGIONID (0xFFFF)
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+/*!
+ * @brief Module configuration structure.
+ */
+typedef struct SharedRegion_Config {
+ SizeT cacheLineSize;
+ /*!<
+ * Worst-case cache line size
+ *
+ * This is the default system cache line size for all modules.
+ * When a module puts structures in shared memory, this value is
+ * used to make sure items are aligned on a cache line boundary.
+ * If no cacheLineSize is specified for a region, it will use this
+ * value.
+ */
+
+ UInt16 numEntries;
+ /*!<
+ * The number of shared region table entries.
+ *
+ * This value is used for calculating the number of bits for the offset.
+ * Note: This value must be the same across all processors in the system.
+ * Increasing this parameter will increase the footprint and
+ * the time for translating a pointer to a SRPtr.
+ */
+
+ Bool translate;
+ /*!< This configuration parameter should be set to 'true'
+ * if and only if all shared memory regions are the same
+ * for all processors. If 'true', it results in a fast
+ * getPtr and getSRPtr.
+ */
+} SharedRegion_Config;
+
+/*!
+ * @brief SharedRegion pointer type
+ */
+typedef Bits32 SharedRegion_SRPtr;
+
+/*!
+ * @brief Structure defining a region
+ */
+typedef struct SharedRegion_Entry {
+ Ptr base;
+ /*!< @brief The base address of the region */
+
+ SizeT len;
+ /*!< @brief The length of the region
+ *
+ * The length of a region must be the same across all
+ * processors in the system.
+ */
+
+ UInt16 ownerProcId;
+ /*!< @brief The MultiProc id of the owner of the region
+ *
+ * The owner id for a shared region must be the same across
+ * all processors in the system.
+ */
+
+ Bool isValid;
+ /*!< @brief Whether the region is valid */
+
+ Bool cacheEnable;
+ /*!< @brief Whether to perform cache operations for the region
+ *
+ * If 'TRUE', a cache invalidate is performed before any read
+ * and a cache write back invalidate is performed after any
+ * write for the shared region. The cache operations are done
+ * for all caches. If 'FALSE', no cache operations are performed.
+ */
+
+ SizeT cacheLineSize;
+ /*!< @brief The cache line size of the region
+ *
+ * The cache line size for a region must be the same across
+ * all processors in the system. It is used for structure
+ * alignment and padding.
+ */
+
+ Bool createHeap;
+ /*!< @brief Whether a heap is created for the region
+ *
+ * If 'TRUE', a HeapMemMP instance is created with the size
+ * spanning the length of the shared region minus any memory
+ * that is reserved in the region. If 'FALSE', no heap
+ * is created in the shared region.
+ */
+
+ String name;
+ /*!< @brief The name of the region.
+ *
+ * The name must be in persistent memory. It is used for
+ * displaying in ROV.
+ */
+} SharedRegion_Entry;
+
+
+/* =============================================================================
+ * SharedRegion Module-wide Functions
+ * =============================================================================
+ */
+
+/*!
+ * @brief Clears the @c regionid entry
+ *
+ * SharedRegion_clearEntry() is used to render invalid a shared region that is
+ * currently valid. If the region has a heap, it will either be closed or
+ * deleted as necessary. All attributes of region are reset to defaults.
+ *
+ * Calling SharedRegion_clearEntry() upon a region that is already invalid
+ * simply resets the region attributes to their defaults.
+ *
+ * @note Region #0 is special and can neither be cleared nor set.
+ *
+ * @param regionId the region id
+ *
+ * @return Status
+ * - #SharedRegion_S_SUCCESS: Operation was successful
+ * - #SharedRegion_E_FAIL: Delete or close of heap created
+ * in region failed.
+ *
+ * @sa SharedRegion_setEntry()
+ */
+Int SharedRegion_clearEntry(UInt16 regionId);
+
+/*!
+ * @brief Initializes the entry fields
+ *
+ * @param entry pointer to a SharedRegion entry
+ *
+ * @sa SharedRegion_setEntry()
+ */
+Void SharedRegion_entryInit(SharedRegion_Entry *entry);
+
+/*!
+ * @brief Gets the cache line size for the specified region id
+ *
+ * @param regionId the region id
+ *
+ * @return Cache line size
+ *
+ * @sa SharedRegion_isCacheEnabled()
+ */
+SizeT SharedRegion_getCacheLineSize(UInt16 regionId);
+
+/*!
+ * @brief Gets the entry information for the specified region id
+ *
+ * @param regionId the region id
+ * @param entry pointer to return region information
+ *
+ * @return Status
+ * - #SharedRegion_S_SUCCESS: Operation was successful
+ * - #SharedRegion_E_FAIL: Operation failed
+ *
+ * @sa SharedRegion_setEntry()
+ */
+Int SharedRegion_getEntry(UInt16 regionId, SharedRegion_Entry *entry);
+
+/*!
+ * @brief Return the address of the shared region entry structure
+ *
+ * This function is to be used only for module startup configuration.
+ * The returned address gives you direct access to the in-memory entry
+ * structure. Use it to configure the entry just before the module
+ * startup phase begins. It is intended to support single-image loading.
+ *
+ * Do not use this function during normal run-time operations; use
+ * SharedRegion_getEntry() instead.
+ */
+SharedRegion_Entry *SharedRegion_getEntryPtr(UInt16 regionId);
+
+/*!
+ * @brief Gets the heap associated with the specified region id
+ *
+ * The heap handle returned is of type xdc.runtime.IHeap.
+ * This handle type can be used with xdc.runtime.Memory.
+ *
+ * The following code shows an example.
+ *
+ * @code
+ * #include <xdc/runtime/IHeap.h>
+ * #include <xdc/runtime/Memory.h>
+ * #include <ti/ipc/SharedRegion.h>
+ *
+ * IHeap_Handle heap;
+ * UInt16 regionId;
+ * SizeT size;
+ * SizeT align;
+ *
+ * heap = (IHeap_Handle)SharedRegion_getHeap(regionId); // get the heap
+ * Memory_alloc(heap, size, align, NULL); // alloc memory from heap
+ * @endcode
+ *
+ * @param regionId the region id
+ *
+ * @return Handle of the heap, NULL if the region has no heap
+ */
+Ptr SharedRegion_getHeap(UInt16 regionId);
+
+/*!
+ * @brief Gets the region id for the specified address
+ *
+ * @param addr address
+ *
+ * @return region id
+ */
+UInt16 SharedRegion_getId(Ptr addr);
+
+/*!
+ * @brief Gets the id of a region, given its name
+ *
+ * @param name name of the region
+ *
+ * @return region id
+ */
+UInt16 SharedRegion_getIdByName(String name);
+
+/*!
+ * @brief Gets the number of regions
+ *
+ * @return number of regions
+ */
+UInt16 SharedRegion_getNumRegions(Void);
+
+/*!
+ * @brief Calculate the local pointer from the shared region pointer
+ *
+ * @param srptr SharedRegion pointer
+ *
+ * @return local pointer or NULL if shared region pointer is invalid
+ *
+ * @sa SharedRegion_getSRPtr()
+ */
+Ptr SharedRegion_getPtr(SharedRegion_SRPtr srptr);
+
+/*!
+ * @brief Calculate the shared region pointer given local address and id
+ *
+ * @param addr the local address
+ * @param regionId region id
+ *
+ * @return SharedRegion pointer
+ *
+ * @sa SharedRegion_getPtr()
+ */
+SharedRegion_SRPtr SharedRegion_getSRPtr(Ptr addr, UInt16 regionId);
+
+/*!
+ * @brief whether cache enable was specified
+ *
+ * @param regionId region id
+ *
+ * @return 'TRUE' if cache enable specified, otherwise 'FALSE'
+ */
+Bool SharedRegion_isCacheEnabled(UInt16 regionId);
+
+/*!
+ * @brief Sets the entry at the specified region id
+ *
+ * SharedRegion_setEntry() is used to set up a shared region that is
+ * currently invalid. Configuration is performed using the values supplied
+ * in the 'entry' parameter. If the 'createHeap' flag is TRUE, then a
+ * region heap will be created (if the processor is the region owner)
+ * or opened.
+ *
+ * If 'createHeap' is TRUE, SharedRegion_setEntry() must always be called by
+ * a 'client' of the shared region only after the region owner has called
+ * SharedRegion_setEntry(). It is unsafe to poll using SharedRegion_setEntry()
+ * to wait for the corresponding heap to be created by the owner. An external
+ * synchronization mechanism (i.e. Notify, shared memory, etc) must be used
+ * to ensure the proper sequence of operations.
+ *
+ * NOTE: This function should never be called upon a region
+ * that is currently valid.
+ *
+ * @param regionId region id
+ * @param entry pointer to set region information.
+ *
+ * @return Status
+ * - #SharedRegion_S_SUCCESS: Operation was successful
+ * - #SharedRegion_E_FAIL: Region already exists or overlaps with
+ * with another region
+ * - #SharedRegion_E_MEMORY: Unable to create Heap
+ */
+Int SharedRegion_setEntry(UInt16 regionId, SharedRegion_Entry *entry);
+
+/*!
+ * @brief Whether address translation is enabled
+ *
+ * @return 'TRUE' if translate is enabled otherwise 'FALSE'
+ */
+Bool SharedRegion_translateEnabled(Void);
+
+/*!
+ * @brief Returns the SharedRegion_SRPtr value that maps to NULL
+ *
+ * @return Value in SRPtr-space that maps to NULL in Ptr-space
+ */
+SharedRegion_SRPtr SharedRegion_invalidSRPtr(Void);
+
+/*!
+ * @brief Function to setup the SharedRegion module.
+ *
+ * @param cfgParams Configuration values.
+ */
+Void SharedRegion_getConfig (SharedRegion_Config * config);
+
+/*!
+ * @brief Function to setup the SharedRegion module.
+ *
+ * Here if user passes both numEntries and indexBits, than
+ * numEntries takes precedence over indexBits.
+ *
+ * @param cfg Configuration values.
+ *
+ * @sa SharedRegion_destroy
+ */
+Int SharedRegion_setup (SharedRegion_Config * config);
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* SharedRegion__include */
diff --git a/host_linux/simple_buffer_example/host/SharedRegion/src/SharedRegion.c b/host_linux/simple_buffer_example/host/SharedRegion/src/SharedRegion.c
--- /dev/null
@@ -0,0 +1,1481 @@
+/*
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file SharedRegion.c
+ *
+ * @brief Shared Region Manager
+ */
+
+/* Standard headers */
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* IPC headers */
+#include <ti/ipc/Std.h>
+#include "Std.h"
+#include <ti/ipc/MultiProc.h>
+#include <IGateProvider.h>
+#include <GateMutex.h>
+
+#include "Trace.h"
+#include "Cache.h"
+#include "Memory.h"
+
+#include "_SharedRegion.h"
+
+//#define ENABLE_LOCAL_LOCK
+
+#define ROUNDUP(size, align) \
+ (UInt32)(((UInt32)(size) + ((UInt32)(align) - 1)) & ~((UInt32)(align) - 1))
+
+/* =============================================================================
+ * Macros
+ * =============================================================================
+ */
+/* Macro to make a correct module magic number with refCount */
+#define SharedRegion_MAKE_MAGICSTAMP(x) ((SharedRegion_MODULEID << 16u) | (x))
+
+/* =============================================================================
+ * Structure & Enums
+ * =============================================================================
+ */
+
+/*!
+ * @brief Module state object.
+ */
+typedef struct SharedRegion_ModuleObject_tag {
+ UInt32 refCount;
+ /*!< Reference count */
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_Handle localLock;
+ /*!< Handle to a gate instance */
+#endif
+ SharedRegion_Region * regions;
+ /*!< Pointer to the regions */
+ SharedRegion_Config cfg;
+ /*!< Current config values */
+ SharedRegion_Config defCfg;
+ /*!< Default config values */
+ UInt32 numOffsetBits;
+ /*!< number of bits for the offset for a SRPtr. This value is calculated */
+ UInt32 offsetMask;
+ /*!< offset bitmask using for generating a SRPtr */
+ bool isStarted;
+ /*!< indicates whether shared region start API is called */
+ UInt32 *regionRefCount;
+ /* To keep track of how many start/stop region API is called for a region*/
+} SharedRegion_ModuleObject;
+
+/* =============================================================================
+ * Global
+ * =============================================================================
+ */
+/*!
+ * @brief Shared region state object variable with default settings
+ */
+static
+SharedRegion_ModuleObject SharedRegion_state = {
+ .numOffsetBits = 0,
+ .regions = NULL,
+#ifdef ENABLE_LOCAL_LOCK
+ .localLock = NULL,
+#endif
+ .regionRefCount = NULL,
+ .offsetMask = 0,
+ .defCfg.numEntries = 4u,
+ .defCfg.translate = TRUE,
+ .defCfg.cacheLineSize = 128u
+};
+
+/*!
+ * @var SharedRegion_module
+ *
+ * @brief Pointer to the SharedRegion module state.
+ */
+static
+SharedRegion_ModuleObject * SharedRegion_module = &SharedRegion_state;
+
+/*!
+ * @brief SharedRegion_CREATED flag in shared memory
+ */
+const UInt32 SharedRegion_CREATED = 0x08111963;
+
+/*!
+ * @brief SharedRegion_VERSION attribute in shared memory
+ */
+const UInt32 SharedRegion_VERSION = 1;
+
+/* =============================================================================
+ * Forward declarations of internal functions
+ * =============================================================================
+ */
+/*!
+ * @brief Checks to make sure overlap does not exists.
+ * Return error if overlap found.
+ *
+ * @param base Base of Shared Region
+ * @param len Length of Shared Region
+ *
+ * @sa None
+ */
+static Int SharedRegion_checkOverlap (Ptr base, UInt32 len);
+
+/*
+ * @brief Return the number of offsetBits bits
+ *
+ * @param None
+ *
+ * @sa None
+ */
+static UInt32 SharedRegion_getNumOffsetBits (Void);
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+/* Function to get the configuration */
+Void
+SharedRegion_getConfig (SharedRegion_Config * config)
+{
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_getConfig", config);
+
+ GT_assert (curTrace, (config != NULL));
+
+ if ((SharedRegion_module->refCount & SharedRegion_MAKE_MAGICSTAMP(0)) <
+ SharedRegion_MAKE_MAGICSTAMP(1)) {
+ memcpy ((Ptr) config,
+ (Ptr) &SharedRegion_module->defCfg,
+ sizeof (SharedRegion_Config));
+ }
+ else {
+ memcpy ((Ptr) config,
+ (Ptr) &SharedRegion_module->cfg,
+ sizeof (SharedRegion_Config));
+ }
+
+ GT_0trace (curTrace, GT_LEAVE, "SharedRegion_getConfig");
+}
+
+/* Function to setup the SharedRegion module. */
+Int
+SharedRegion_setup (SharedRegion_Config * cfg)
+{
+ Int status = SharedRegion_S_SUCCESS;
+ UInt32 eb;
+ SharedRegion_Config tmpCfg;
+ UInt32 i;
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_setup", cfg);
+ eb=0;
+
+ if (cfg == NULL) {
+ SharedRegion_getConfig (&tmpCfg);
+ cfg = &tmpCfg;
+ }
+
+ if (cfg == NULL) {
+ SharedRegion_getConfig (&tmpCfg);
+ cfg = &tmpCfg;
+ }
+
+ /* This sets the refCount variable is not initialized, upper 16 bits is
+ * written with module Id to ensure correctness of refCount variable.
+ */
+ if((SharedRegion_module->refCount & SharedRegion_MAKE_MAGICSTAMP(0))
+ != SharedRegion_MAKE_MAGICSTAMP(0)) {
+ SharedRegion_module->refCount = SharedRegion_MAKE_MAGICSTAMP(0);
+ }
+ if (++SharedRegion_module->refCount
+ != SharedRegion_MAKE_MAGICSTAMP(1u)) {
+ status = SharedRegion_S_ALREADYSETUP;
+ GT_0trace (curTrace,
+ GT_2CLASS,
+ "SharedRegion Module already initialized!");
+ }
+ else {
+ /* copy the user provided values into the state object */
+ memcpy ((Ptr) &SharedRegion_module->cfg,
+ (Ptr) cfg,
+ sizeof (SharedRegion_Config));
+
+ /* In a single processor system, we should never translate.
+ * but on HlOS side where there are user space virtual space
+ * we should set translate = TRUE.
+ */
+
+ SharedRegion_module->cfg.translate = TRUE;
+
+ /* Allocate memory for the regions */
+ SharedRegion_module->regions = (SharedRegion_Region *)
+ malloc(sizeof(SharedRegion_Region)
+ *SharedRegion_module->cfg.numEntries);
+
+ SharedRegion_module->regionRefCount = malloc (sizeof (UInt32)
+ * SharedRegion_module->cfg.numEntries);
+ GT_assert(curTrace,(SharedRegion_module->regionRefCount != NULL));
+
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ SharedRegion_module->regions[i].entry.base = NULL;
+ SharedRegion_module->regions[i].entry.len = 0;
+ SharedRegion_module->regions[i].entry.ownerProcId = 0;
+ SharedRegion_module->regions[i].entry.isValid = FALSE;
+ SharedRegion_module->regions[i].entry.cacheEnable = FALSE;
+ SharedRegion_module->regions[i].entry.cacheLineSize =
+ SharedRegion_module->cfg.cacheLineSize;
+ SharedRegion_module->regions[i].entry.createHeap = FALSE;
+ SharedRegion_module->regions[i].reservedSize = 0;
+#ifdef ENABLE_HEAPMP
+ SharedRegion_module->regions[i].heap = NULL;
+#endif
+ SharedRegion_module->regions[i].entry.name = NULL;
+ }
+
+ /* set the defaults for region 0 */
+#ifdef ENABLE_HEAPMP
+ SharedRegion_module->regions[0].entry.createHeap = TRUE;
+#endif
+ SharedRegion_module->regions[0].entry.ownerProcId = MultiProc_self();
+
+ SharedRegion_module->numOffsetBits = SharedRegion_getNumOffsetBits ();
+ SharedRegion_module->offsetMask =
+ (1 << SharedRegion_module->numOffsetBits) - 1;
+ SharedRegion_module->isStarted = FALSE;
+#ifdef ENABLE_LOCAL_LOCK
+ /* Create a lock for protecting list object */
+ SharedRegion_module->localLock = (IGateProvider_Handle)
+ GateMutex_create ((GateMutex_Params*)NULL, &eb);
+#endif
+ }
+
+ if (status < 0) {
+ SharedRegion_destroy ();
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_setup", status);
+
+ /*! @retval SharedRegion_SUCCESS operation was successful */
+ return status;
+}
+
+/* Function to destroy the SharedRegion module. */
+Int
+SharedRegion_destroy (Void)
+{
+ Int status = SharedRegion_S_SUCCESS;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+ GT_0trace (curTrace, GT_ENTER, "SharedRegion_destroy");
+
+ if ( --SharedRegion_module->refCount
+ == SharedRegion_MAKE_MAGICSTAMP(0)) {
+#ifdef ENABLE_LOCAL_LOCK
+ /* Enter the gate */
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+ if (SharedRegion_module->regionRefCount != NULL) {
+ free (SharedRegion_module->regionRefCount);
+ SharedRegion_module->regionRefCount = NULL;
+ }
+
+ if (SharedRegion_module->regions != NULL) {
+ free (SharedRegion_module->regions);
+ SharedRegion_module->regions = NULL;
+ }
+
+ memset (&SharedRegion_module->cfg,
+ 0,
+ sizeof (SharedRegion_Config));
+
+ SharedRegion_module->numOffsetBits = 0;
+ SharedRegion_module->offsetMask = 0;
+#ifdef ENABLE_LOCAL_LOCK
+ /* Leave the gate */
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+ /* Delete the local lock */
+ if (SharedRegion_module->localLock != NULL) {
+ status = GateMutex_delete ((GateMutex_Handle *)
+ &SharedRegion_module->localLock);
+ GT_assert (curTrace, (status >= 0));
+ if (status < 0) {
+ status = SharedRegion_E_FAIL;
+ }
+ }
+#endif
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_destroy", status);
+
+ return status;
+}
+
+/* API to know whether shared region is started or not.Returns true if shared
+ * region is already started othere wise returns false.
+ */
+Int
+_SharedRegion_isStarted(Void)
+{
+ return(SharedRegion_module->isStarted) ;
+}
+
+/* Creates a heap by owner of region for each SharedRegion.
+ * Function is called by Ipc_start(). Requires that SharedRegion 0
+ * be valid before calling start().
+ */
+Int
+SharedRegion_start (Void)
+{
+ Int status = SharedRegion_S_SUCCESS;
+ SharedRegion_Region * region = NULL;
+#ifdef ENABLE_HEAPMP
+ Ptr sharedAddr = NULL;
+ HeapMemMP_Handle heapHandle = NULL;
+ HeapMemMP_Params params;
+#endif
+ Int i;
+
+ GT_0trace (curTrace, GT_ENTER, "SharedRegion_start");
+
+ /*
+ * Loop through shared regions. If an owner of a region is specified
+ * and createHeap has been specified for the SharedRegion, then
+ * the owner creates a HeapMemMP and the other processors open it.
+ */
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &(SharedRegion_module->regions[i]);
+ if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+ if ((region->entry.ownerProcId == MultiProc_self())
+ && (region->entry.createHeap)
+ && (region->heap == NULL)) {
+ /* get the next free address in each region */
+ sharedAddr = (Ptr)((UInt32)region->entry.base
+ + region->reservedSize);
+
+ /* Create the HeapMemMP in the region. */
+ HeapMemMP_Params_init(¶ms);
+ params.sharedAddr = sharedAddr;
+ params.sharedBufSize = region->entry.len - region->reservedSize;
+
+ /* Adjust to account for the size of HeapMemMP_Attrs */
+ params.sharedBufSize -= (HeapMemMP_sharedMemReq(¶ms)
+ - params.sharedBufSize);
+ heapHandle = HeapMemMP_create(¶ms);
+
+ /* put heap handle into SharedRegion Module state */
+ region->heap = heapHandle;
+ }
+#endif
+ SharedRegion_module->regionRefCount[i] += 1;
+ }
+ }
+
+ /* Set flag indiacting shared region has been started */
+ SharedRegion_module->isStarted = TRUE;
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_start", status);
+
+ return status;
+}
+
+/* Function to stop the SharedRegion module. */
+Int
+SharedRegion_stop (Void)
+{
+ Int status = SharedRegion_S_SUCCESS;
+#ifdef ENABLE_HEAPMP
+ Int tmpStatus = SharedRegion_S_SUCCESS;
+#endif
+ SharedRegion_Region * region = NULL;
+ Int i;
+
+ GT_0trace (curTrace, GT_ENTER, "SharedRegion_stop");
+
+ /*
+ * Loop through shared regions. If an owner of a region is specified
+ * and createHeap has been specified for the SharedRegion, then
+ * the other processors close it and the owner deletes the HeapMemMP.
+ */
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &(SharedRegion_module->regions[i]);
+ if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+ if ((region->entry.ownerProcId == MultiProc_self ())
+ && (region->entry.createHeap)
+ && (region->heap != NULL)) {
+ /* Delete heap */
+ tmpStatus = HeapMemMP_delete ((HeapMemMP_Handle *)
+ &(region->heap));
+ if ((tmpStatus < 0) && (status >= 0)) {
+ status = SharedRegion_E_FAIL;
+ }
+ }
+#endif
+ memset (region, 0, sizeof (SharedRegion_Region));
+ SharedRegion_entryInit (&(region->entry));
+
+ SharedRegion_module->regionRefCount[i] -= 1;
+ }
+ }
+
+ /* set the defaults for region 0 */
+ memset (&(SharedRegion_module->regions[0]),
+ 0,
+ sizeof (SharedRegion_Region));
+ SharedRegion_entryInit (&(SharedRegion_module->regions[0].entry));
+ SharedRegion_module->regions[0].entry.createHeap = TRUE;
+ SharedRegion_module->regions[0].entry.ownerProcId = MultiProc_self();
+ /* Set flag indicating shared region has been started */
+ SharedRegion_module->isStarted = FALSE;
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_stop", status);
+
+ return status;
+}
+
+/* Opens a heap, for non-owner processors, for each SharedRegion. */
+Int
+SharedRegion_attach (UInt16 remoteProcId)
+{
+ Int status = SharedRegion_S_SUCCESS;
+ SharedRegion_Region * region = NULL;
+#ifdef ENABLE_HEAPMP
+ Ptr sharedAddr = NULL;
+#endif
+ Int i;
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_attach", remoteProcId);
+
+ GT_assert (curTrace, (remoteProcId < MultiProc_MAXPROCESSORS));
+
+ /*
+ * Loop through the regions and open the heap if not owner
+ */
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &(SharedRegion_module->regions [i]);
+ if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+ if ((region->entry.ownerProcId != MultiProc_self ()) &&
+ (region->entry.ownerProcId != MultiProc_INVALIDID) &&
+ (region->entry.createHeap) &&
+ (region->heap == NULL)) {
+ /* SharedAddr should match creator's for each region */
+ sharedAddr = (Ptr) ((UInt32) region->entry.base +
+ region->reservedSize);
+
+ /* Heap should already be created so open by address */
+ status = HeapMemMP_openByAddr (sharedAddr,
+ (HeapMemMP_Handle *) &(region->heap));
+ if (status < 0) {
+ status = SharedRegion_E_FAIL;
+
+ /* Break the loop on failure. */
+ break;
+ }
+ }
+#endif
+ SharedRegion_module->regionRefCount[i] ++;
+ }
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_attach", status);
+
+ return status;
+}
+
+/* Closes a heap, for non-owner processors, for each SharedRegion. */
+Int
+SharedRegion_detach (UInt16 remoteProcId)
+{
+ Int status = SharedRegion_S_SUCCESS;
+#ifdef ENABLE_HEAPMP
+ Int tmpStatus = SharedRegion_S_SUCCESS;
+#endif
+ SharedRegion_Region * region = NULL;
+ UInt16 i;
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_detach", remoteProcId);
+
+ GT_assert (curTrace, (remoteProcId < MultiProc_MAXPROCESSORS));
+
+ /*
+ * Loop through the regions and open the heap if not owner
+ */
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &(SharedRegion_module->regions [i]);
+ if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+ if ((region->entry.ownerProcId != MultiProc_self ()) &&
+ (region->entry.ownerProcId != MultiProc_INVALIDID) &&
+ (region->entry.createHeap) && (region->heap != NULL)) {
+ /* Close the heap */
+ tmpStatus = HeapMemMP_close ((HeapMemMP_Handle *)
+ &(region->heap));
+ if ((tmpStatus < 0) && (status >= 0)) {
+ status = SharedRegion_E_FAIL;
+
+ }
+ }
+#endif
+ SharedRegion_module->regionRefCount[i]--;
+ }
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_detach", status);
+
+ return status;
+}
+
+/* Returns the address pointer associated with the shared region pointer. */
+Ptr
+SharedRegion_getPtr (SharedRegion_SRPtr srPtr)
+{
+ SharedRegion_Region * region = NULL;
+ Ptr returnPtr = NULL;
+ UInt16 regionId;
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_getPtr", srPtr);
+
+ /* srPtr can be invalid. */
+
+ if (srPtr != SharedRegion_INVALIDSRPTR) {
+ if (SharedRegion_module->cfg.translate == FALSE) {
+ returnPtr = (Ptr) srPtr;
+ }
+ else {
+ regionId = (UInt32) (srPtr >> SharedRegion_module->numOffsetBits);
+
+ region = &(SharedRegion_module->regions [regionId]);
+
+ returnPtr = (Ptr)( (srPtr & SharedRegion_module->offsetMask)
+ + (UInt32) region->entry.base);
+
+ }
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getPtr", returnPtr);
+
+ return returnPtr;
+}
+
+/* Returns the address pointer associated with the shared region pointer. */
+SharedRegion_SRPtr
+SharedRegion_getSRPtr (Ptr addr, UInt16 id)
+{
+ SharedRegion_Region * region = NULL;
+ SharedRegion_SRPtr retPtr = SharedRegion_INVALIDSRPTR;
+
+ GT_2trace (curTrace, GT_ENTER, "SharedRegion_getSRPtr", addr, id);
+
+ /* addr can be NULL. */
+
+ /* Return invalid for NULL addr */
+ if (addr != NULL) {
+ GT_assert (curTrace, (id != SharedRegion_INVALIDREGIONID));
+ GT_assert (curTrace,
+ ( (id != SharedRegion_INVALIDREGIONID)
+ && (id < SharedRegion_module->cfg.numEntries)));
+
+ /* if no shared region configured, set SRPtr to addr */
+ if (SharedRegion_module->cfg.translate == FALSE) {
+ retPtr = (SharedRegion_SRPtr) addr;
+ }
+ else {
+ region = &(SharedRegion_module->regions[id]);
+
+ /*
+ * Note: The very last byte on the very last id cannot be
+ * mapped because SharedRegion_INVALIDSRPTR which is ~0
+ * denotes an error. Since pointers should be word
+ * aligned, we don't expect this to be a problem.
+ *
+ * ie: numEntries = 4,
+ * id = 3, base = 0x00000000, len = 0x40000000
+ * ==> address 0x3fffffff would be invalid because
+ * the SRPtr for this address is 0xffffffff
+ */
+ if ( ((UInt32) addr >= (UInt32) region->entry.base)
+ && ( (UInt32) addr
+ < ((UInt32) region->entry.base + region->entry.len))) {
+ retPtr = (SharedRegion_SRPtr)
+ ( (id << SharedRegion_module->numOffsetBits)
+ | ((UInt32) addr - (UInt32) region->entry.base));
+ }
+ else {
+ retPtr = SharedRegion_INVALIDSRPTR;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "SharedRegion_getSRPtr",
+ SharedRegion_E_INVALIDARG,
+ "Provided addr is not in correct range"
+ " for the specified id!");
+ }
+ }
+
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getSRPtr", retPtr);
+
+ return retPtr;
+}
+
+/* Whether address translation is enabled */
+Bool
+SharedRegion_translateEnabled (Void)
+{
+ GT_0trace (curTrace, GT_ENTER, "SharedRegion_translateEnabled");
+ GT_1trace (curTrace,
+ GT_LEAVE,
+ "SharedRegion_translateEnabled",
+ SharedRegion_module->cfg.translate);
+
+ return (SharedRegion_module->cfg.translate);
+}
+
+/* Gets the number of regions */
+UInt16
+SharedRegion_getNumRegions (Void)
+{
+ GT_0trace (curTrace, GT_ENTER, "SharedRegion_getNumRegions");
+ GT_1trace (curTrace,
+ GT_LEAVE,
+ "SharedRegion_getNumRegions",
+ SharedRegion_module->cfg.numEntries);
+ return (SharedRegion_module->cfg.numEntries);
+}
+
+/* Sets the table information entry in the table. */
+Int
+SharedRegion_setEntry (UInt16 id,
+ SharedRegion_Entry * entry)
+{
+ Int status = SharedRegion_S_SUCCESS;
+ SharedRegion_Region * region = NULL;
+#ifdef ENABLE_HEAPMP
+ Ptr sharedAddr = NULL;
+#endif
+#ifdef ENABLE_HEAPMP
+ HeapMemMP_Handle heapHandle = NULL;
+ HeapMemMP_Handle * heapHandlePtr = NULL;
+ HeapMemMP_Params params;
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+
+ GT_2trace (curTrace, GT_ENTER, "SharedRegion_setEntry", id, entry);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+ GT_assert (curTrace, (entry != NULL));
+
+ region = &(SharedRegion_module->regions [id]);
+
+ /* Make sure region does not overlap existing ones */
+ status = SharedRegion_checkOverlap (region->entry.base,
+ region->entry.len);
+
+ if (region->entry.isValid) {
+ /* region already exist */
+ SharedRegion_module->regionRefCount[id] += 1;
+ }
+ else {
+#ifdef ENABLE_LOCAL_LOCK
+ /* needs to be thread safe */
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+ /* set specified region id to entry values */
+ memcpy ((Ptr) &(region->entry),
+ (Ptr) entry,
+ sizeof (SharedRegion_Entry));
+#ifdef ENABLE_LOCAL_LOCK
+ /* leave gate */
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+#ifdef ENABLE_HEAPMP
+ if (entry->ownerProcId == MultiProc_self ()) {
+ if ((entry->createHeap) && (region->heap == NULL)) {
+ /* get current Ptr (reserve memory with size of 0) */
+ sharedAddr = SharedRegion_reserveMemory (id, 0);
+ HeapMemMP_Params_init (¶ms);
+ params.sharedAddr = sharedAddr;
+ params.sharedBufSize = region->entry.len
+ - region->reservedSize;
+
+ /*
+ * Calculate size of HeapMemMP_Attrs and adjust
+ * sharedBufSize. Size of HeapMemMP_Attrs =
+ * HeapMemMP_sharedMemReq(¶ms) - params.sharedBufSize
+ */
+ params.sharedBufSize -= ( HeapMemMP_sharedMemReq (¶ms)
+ - params.sharedBufSize);
+
+ heapHandle = HeapMemMP_create (¶ms);
+ if (heapHandle == NULL) {
+ region->entry.isValid = FALSE;
+ status = SharedRegion_E_MEMORY;
+
+ }
+ else {
+ region->heap = heapHandle;
+ }
+ }
+ }
+ else {
+ if ((entry->createHeap) && (region->heap == NULL)) {
+ /* sharedAddr should match creator's for each region */
+ sharedAddr = (Ptr)( (UInt32) region->entry.base
+ + region->reservedSize);
+
+ /* set the pointer to a heap handle */
+ heapHandlePtr = (HeapMemMP_Handle *) &(region->heap);
+
+ /* open the heap by address */
+ status = HeapMemMP_openByAddr (sharedAddr, heapHandlePtr);
+ if (status < 0) {
+ region->entry.isValid = FALSE;
+ status = SharedRegion_E_FAIL;
+
+ }
+ }
+ }
+#endif
+ if (region->entry.isValid) {
+ SharedRegion_module->regionRefCount[id] ++;
+ }
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_setEntry", status);
+
+ return (status);
+}
+
+/* Clears the region in the table. */
+Int
+SharedRegion_clearEntry (UInt16 id)
+{
+ Int status = SharedRegion_S_SUCCESS;
+ SharedRegion_Region * region = NULL;
+#ifdef ENABLE_HEAPMP
+ HeapMemMP_Handle heapmemPtr = NULL;
+ UInt16 myId;
+ UInt16 ownerProcId;
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_clearEntry", id);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+ /* Need to make sure not trying to clear Region 0 */
+
+#ifdef ENABLE_HEAPMP
+ myId = MultiProc_self ();
+#endif
+
+#ifdef ENABLE_LOCAL_LOCK
+ /* Needs to be thread safe */
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+
+ region = &(SharedRegion_module->regions [id]);
+
+#ifdef ENABLE_HEAPMP
+ /* Store these fields to local variables */
+ ownerProcId = region->entry.ownerProcId;
+ heapmemPtr = region->heap;
+#endif
+ if (region->entry.isValid) {
+ SharedRegion_module->regionRefCount[id] -= 1;
+ }
+
+ if (SharedRegion_module->regionRefCount[id] == 0) {
+ /* Assert if region is 0.
+ * Region 0 should always be cleared through SharedRegion_stop API
+ */
+ GT_assert (curTrace, (id != 0));
+ /* Clear region to their defaults */
+ region->entry.isValid = FALSE;
+ region->entry.base = NULL;
+ region->entry.len = 0u;
+ region->entry.ownerProcId = 0u;
+ region->entry.cacheEnable = FALSE;
+ region->entry.cacheLineSize = SharedRegion_module->cfg.cacheLineSize;
+ region->entry.createHeap = TRUE;
+ region->entry.name = NULL;
+ region->reservedSize = 0u;
+#ifdef ENABLE_HEAPMP
+ region->heap = NULL;
+#endif
+
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+#ifdef ENABLE_HEAPMP
+ /* Delete or close previous created heap outside the gate */
+ if (heapmemPtr != NULL) {
+ if (ownerProcId == myId) {
+ status = HeapMemMP_delete ((HeapMemMP_Handle *) &heapmemPtr);
+ if (status < 0) {
+ status = SharedRegion_E_FAIL;
+
+ }
+ }
+ else if (ownerProcId != MultiProc_INVALIDID) {
+ status = HeapMemMP_close ((HeapMemMP_Handle *) &heapmemPtr);
+ if (status < 0) {
+ status = SharedRegion_E_FAIL;
+
+ }
+ }
+ }
+#endif
+#ifdef ENABLE_LOCAL_LOCK
+ /* Needs to be thread safe */
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+ }
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_clearEntry", status);
+
+ return status;
+}
+
+/* Clears the reserve memory for each region in the table. */
+Void
+SharedRegion_clearReservedMemory (Void)
+{
+ SharedRegion_Region * region = NULL;
+ Int i;
+
+ GT_0trace (curTrace, GT_ENTER, "SharedRegion_clearReservedMemory");
+
+ /*
+ * Loop through shared regions. If an owner of a region is specified,
+ * the owner zeros out the reserved memory in each region.
+ */
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &(SharedRegion_module->regions [i]);
+ if ( (region->entry.isValid)
+ && (region->entry.ownerProcId == MultiProc_self ())) {
+ /* Clear reserved memory, if any */
+ if (region->reservedSize != 0) {
+ memset (region->entry.base, 0, region->reservedSize);
+
+ /* Writeback invalidate the cache if enabled in region */
+ if (region->entry.cacheEnable) {
+ Cache_wbInv (region->entry.base,
+ region->reservedSize,
+ Cache_Type_ALL,
+ TRUE);
+ }
+ }
+ }
+ }
+
+ GT_0trace (curTrace, GT_LEAVE, "SharedRegion_clearReservedMemory");
+}
+
+/* Initializes the entry fields */
+Void
+SharedRegion_entryInit (SharedRegion_Entry * entry)
+{
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_entryInit", entry);
+
+ GT_assert (curTrace, (entry != NULL));
+
+ /* init the entry to default values */
+ entry->base = NULL;
+ entry->len = 0u;
+ entry->ownerProcId = 0u;
+ entry->cacheEnable = TRUE;
+ entry->cacheLineSize = SharedRegion_module->cfg.cacheLineSize;
+ entry->createHeap = TRUE;
+ entry->name = NULL;
+ entry->isValid = FALSE;
+
+ GT_0trace (curTrace, GT_LEAVE, "SharedRegion_entryInit");
+}
+
+/* Returns Heap Handle of associated id */
+Ptr
+SharedRegion_getHeap (UInt16 id)
+{
+#ifdef ENABLE_HEAPMP
+ HeapMemMP_Handle heap = NULL;
+#endif
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_getHeap", id);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+ /*
+ * If translate == TRUE or translate == FALSE
+ * and 'id' is not INVALIDREGIONID, then assert id is valid.
+ * Return the heap associated with the region id.
+ *
+ * If those conditions are not met, the id is from
+ * an addres in local memory so return NULL.
+ */
+ if ( (SharedRegion_module->cfg.translate)
+ || ( (SharedRegion_module->cfg.translate == FALSE)
+ && (id != SharedRegion_INVALIDREGIONID))) {
+ if (id >= SharedRegion_module->cfg.numEntries) {
+ /* Need to make sure id is smaller than numEntries */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "SharedRegion_getHeap",
+ SharedRegion_E_INVALIDARG,
+ "id cannot be larger than numEntries!");
+ }
+ else {
+#ifdef ENABLE_HEAPMP
+ heap = SharedRegion_module->regions [id].heap;
+#endif
+ }
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getHeap", heap);
+
+#ifdef ENABLE_HEAPMP
+ return (Ptr) heap;
+#else
+ return NULL;
+#endif
+}
+
+/* Returns the id of shared region in which the pointer resides.
+ * Returns 0 if SharedRegion_module->cfg.translate set to TRUE.
+ * It returns SharedRegion_INVALIDREGIONID if no entry is found.
+ */
+UInt16
+SharedRegion_getId (Ptr addr)
+{
+ SharedRegion_Region * region = NULL;
+ UInt16 regionId = SharedRegion_INVALIDREGIONID;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+ UInt16 i;
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_getId", addr);
+
+ /* addr can be NULL. */
+
+ /* Return invalid for NULL addr */
+ if (addr != NULL) {
+#ifdef ENABLE_LOCAL_LOCK
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &(SharedRegion_module->regions [i]);
+ if ( (region->entry.isValid)
+ && (addr >= region->entry.base)
+ && ( addr
+ < (Ptr)((UInt32) region->entry.base + region->entry.len))) {
+ regionId = i;
+ break;
+ }
+ }
+
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getId", regionId);
+
+ return (regionId);
+}
+
+/* Returns the id of shared region that matches name.
+ * Returns SharedRegion_INVALIDREGIONID if no region is found.
+ */
+UInt16
+SharedRegion_getIdByName (String name)
+{
+ SharedRegion_Region * region = NULL;
+ UInt16 regionId = SharedRegion_INVALIDREGIONID;
+ UInt16 i;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_getIdByName", name);
+
+ GT_assert (curTrace, (name != NULL));
+
+#ifdef ENABLE_LOCAL_LOCK
+ /* Needs to be thread safe */
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+
+ /* loop through entries to find matching name */
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &(SharedRegion_module->regions [i]);
+
+ if (region->entry.isValid) {
+ if (strcmp (region->entry.name, name) == 0) {
+ regionId = i;
+ break;
+ }
+ }
+ }
+
+#ifdef ENABLE_LOCAL_LOCK
+ /* leave the gate */
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getIdByName", regionId);
+
+ return (regionId);
+}
+
+/* Gets the entry information for the specified region id */
+Int
+SharedRegion_getEntry (UInt16 id,
+ SharedRegion_Entry * entry)
+{
+ Int status = SharedRegion_S_SUCCESS;
+ SharedRegion_Region * region = NULL;
+
+ GT_2trace (curTrace, GT_ENTER, "SharedRegion_getEntry", id, entry);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+ GT_assert (curTrace, (entry != NULL));
+
+ region = &(SharedRegion_module->regions [id]);
+
+ memcpy ((Ptr) entry,
+ (Ptr) &(region->entry),
+ sizeof (SharedRegion_Entry));
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getEntry", status);
+
+ return status;
+}
+
+/* Get cache line size */
+SizeT
+SharedRegion_getCacheLineSize (UInt16 id)
+{
+ SizeT cacheLineSize = 0u;
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_getCacheLineSize", id);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+ /*
+ * If translate == TRUE or translate == FALSE
+ * and 'id' is not INVALIDREGIONID, then assert id is valid.
+ * Return the heap associated with the region id.
+ *
+ * If those conditions are not met, the id is from
+ * an addres in local memory so return NULL.
+ */
+ if ( (SharedRegion_module->cfg.translate)
+ || ( (SharedRegion_module->cfg.translate == FALSE)
+ && (id != SharedRegion_INVALIDREGIONID))) {
+ if (id >= SharedRegion_module->cfg.numEntries) {
+ /* Need to make sure id is smaller than numEntries */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "SharedRegion_getCacheLineSize",
+ SharedRegion_E_INVALIDARG,
+ "id cannot be larger than numEntries!");
+ }
+ else {
+ cacheLineSize =
+ SharedRegion_module->regions [id].entry.cacheLineSize;
+ }
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getCacheLineSize",
+ cacheLineSize);
+
+ return cacheLineSize;
+}
+
+/* Is cache enabled */
+Bool
+SharedRegion_isCacheEnabled (UInt16 id)
+{
+ Bool cacheEnable = FALSE;
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_isCacheEnabled", id);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+ /*
+ * If translate == TRUE or translate == FALSE
+ * and 'id' is not INVALIDREGIONID, then assert id is valid.
+ * Return the heap associated with the region id.
+ *
+ * If those conditions are not met, the id is from
+ * an addres in local memory so return NULL.
+ */
+ if ( (SharedRegion_module->cfg.translate)
+ || ( (SharedRegion_module->cfg.translate == FALSE)
+ && (id != SharedRegion_INVALIDREGIONID))) {
+ if (id >= SharedRegion_module->cfg.numEntries) {
+ /* Need to make sure id is smaller than numEntries */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "SharedRegion_isCacheEnabled",
+ SharedRegion_E_INVALIDARG,
+ "id cannot be larger than numEntries!");
+ }
+ else {
+ cacheEnable =
+ SharedRegion_module->regions[id].entry.cacheEnable;
+ }
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_isCacheEnabled", cacheEnable);
+
+ return (cacheEnable);
+}
+
+/* Returns invalid SRPtr value. */
+SharedRegion_SRPtr SharedRegion_invalidSRPtr (Void)
+{
+ return (SharedRegion_INVALIDSRPTR);
+}
+
+/* =============================================================================
+ * Internal Functions
+ * =============================================================================
+ */
+/* Reserves the specified amount of memory from the specified region id. */
+Ptr
+SharedRegion_reserveMemory (UInt16 id, SizeT size)
+{
+ Ptr retPtr = NULL;
+ SharedRegion_Region * region = NULL;
+ UInt32 minAlign;
+ SizeT newSize;
+ SizeT curSize;
+
+ GT_2trace (curTrace, GT_ENTER, "SharedRegion_reserveMemory", id, size);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+ minAlign = Memory_getMaxDefaultTypeAlign ();
+
+ if (SharedRegion_getCacheLineSize (id) > minAlign) {
+ minAlign = SharedRegion_getCacheLineSize (id);
+ }
+
+ region = &(SharedRegion_module->regions [id]);
+
+ /* Set the current size to the reservedSize */
+ curSize = region->reservedSize;
+
+ /* No need to round here since curSize is already aligned */
+ retPtr = (Ptr)((UInt32) region->entry.base + curSize);
+
+ /* Round the new size to the min alignment since */
+ newSize = ROUNDUP (size, minAlign);
+
+ /* Add the new size to current size */
+ region->reservedSize = curSize + newSize;
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_reserveMemory", retPtr);
+
+ return (retPtr);
+}
+
+/* Reserves the specified amount of memory from the specified region id. */
+Void
+SharedRegion_unreserveMemory (UInt16 id, SizeT size)
+{
+ SharedRegion_Region * region = NULL;
+ UInt32 minAlign;
+ SizeT newSize;
+ SizeT curSize;
+
+ GT_2trace (curTrace, GT_ENTER, "SharedRegion_unreserveMemory", id, size);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+
+ minAlign = Memory_getMaxDefaultTypeAlign ();
+
+ if (SharedRegion_getCacheLineSize (id) > minAlign) {
+ minAlign = SharedRegion_getCacheLineSize (id);
+ }
+
+ region = &(SharedRegion_module->regions [id]);
+
+ /* Set the current size to the unreservedSize */
+ curSize = region->reservedSize;
+
+ /* Round the new size to the min alignment since */
+ newSize = ROUNDUP (size, minAlign);
+
+ /* Add the new size to current size */
+ region->reservedSize = curSize - newSize;
+
+ GT_0trace (curTrace, GT_LEAVE, "SharedRegion_unreserveMemory");
+
+ return ;
+}
+
+/* Return the number of offsetBits bits */
+static UInt32 SharedRegion_getNumOffsetBits (Void)
+{
+ UInt32 numEntries = SharedRegion_module->cfg.numEntries;
+ UInt32 indexBits = 0;
+ UInt32 numOffsetBits = 0;
+
+ GT_0trace (curTrace, GT_ENTER, "SharedRegion_getNumOffsetBits");
+
+ if (numEntries == 0) {
+ indexBits = 0;
+ }
+ else if (numEntries == 1) {
+ indexBits = 1;
+ }
+ else {
+ numEntries = numEntries - 1;
+
+ /* determine the number of bits for the index */
+ while (numEntries) {
+ indexBits++;
+ numEntries = numEntries >> 1;
+ }
+ }
+
+ numOffsetBits = 32 - indexBits;
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getNumOffsetBits",
+ numOffsetBits);
+
+ return (numOffsetBits);
+}
+
+/* Checks to make sure overlap does not exists. */
+static Int SharedRegion_checkOverlap(Ptr base, SizeT len)
+{
+ Int status = SharedRegion_S_SUCCESS;
+ SharedRegion_Region * region = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key = 0;
+#endif
+ UInt32 i;
+
+ GT_2trace (curTrace, GT_ENTER, "SharedRegion_checkOverlap", base, len);
+
+#ifdef ENABLE_LOCAL_LOCK
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+ /* check whether new region overlaps existing ones */
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &(SharedRegion_module->regions [i]);
+ if (region->entry.isValid) {
+ if ((base == region->entry.base)&&(len == region->entry.len)) {
+ /* OK.Return sucess as user is going to create the same
+ * shared region from different process
+ */
+ break;
+ }
+ else if (base >= region->entry.base) {
+ if ( base
+ < (Ptr)( (UInt32) region->entry.base
+ + region->entry.len)) {
+ status = SharedRegion_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "SharedRegion_checkOverlap",
+ status,
+ "Specified region falls within another"
+ " region!");
+ /* Break on failure. */
+ break;
+ }
+ }
+ else {
+ if ((Ptr) ((UInt32) base + len) > region->entry.base) {
+ status = SharedRegion_E_FAIL;
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "SharedRegion_checkOverlap",
+ status,
+ "Specified region spans across"
+ " multiple regions!");
+ /* Break on failure. */
+ break;
+ }
+ }
+ }
+ }
+
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_checkOverlap", status);
+
+ return (status);
+}
+
+/* Return the region info */
+Void
+SharedRegion_getRegionInfo (UInt16 i,
+ SharedRegion_Region * region)
+{
+ SharedRegion_Region * regions = NULL;
+
+ GT_2trace (curTrace, GT_ENTER, "SharedRegion_getRegionInfo", i, region);
+
+ GT_assert (curTrace, (i < SharedRegion_module->cfg.numEntries));
+ GT_assert (curTrace, (region != NULL));
+
+ regions = &(SharedRegion_module->regions[i]);
+
+ memcpy ((Ptr) region,
+ (Ptr) regions,
+ sizeof (SharedRegion_Region));
+
+ GT_0trace (curTrace, GT_LEAVE, "SharedRegion_getRegionInfo");
+}
+
+/* Sets the table information entry in the table (doesn't create heap). */
+Int
+_SharedRegion_setEntry (UInt16 id,
+ SharedRegion_Entry * entry)
+{
+ Int status = SharedRegion_S_SUCCESS;
+ SharedRegion_Region * region = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+
+ GT_2trace (curTrace, GT_ENTER, "_SharedRegion_setEntry", id, entry);
+
+ GT_assert (curTrace, (id < SharedRegion_module->cfg.numEntries));
+ GT_assert (curTrace, (entry != NULL));
+
+ region = &(SharedRegion_module->regions [id]);
+
+ /* Make sure region does not overlap existing ones */
+ status = SharedRegion_checkOverlap (region->entry.base,
+ region->entry.len);
+#ifdef ENABLE_LOCAL_LOCK
+ /* needs to be thread safe */
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+
+ /* set specified region id to entry values */
+ memcpy ((Ptr) &(region->entry),
+ (Ptr) entry,
+ sizeof (SharedRegion_Entry));
+
+#ifdef ENABLE_LOCAL_LOCK
+ /* leave gate */
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+
+ GT_1trace (curTrace, GT_LEAVE, "_SharedRegion_setEntry", status);
+
+ return (status);
+}
+
+/* Gets region ID when given a physical address */
+UInt16 _SharedRegion_getIdPhys(Ptr physAddr)
+{
+ SharedRegion_Region * region = NULL;
+ UInt16 regionId = SharedRegion_INVALIDREGIONID;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+ UInt16 i;
+ Ptr base;
+
+ GT_1trace (curTrace, GT_ENTER, "SharedRegion_getIdPhys", physAddr);
+
+ /* physAddr can be NULL. */
+
+ /* Return invalid for NULL physAddr */
+ if (physAddr != NULL) {
+#ifdef ENABLE_LOCAL_LOCK
+ key = IGateProvider_enter (SharedRegion_module->localLock);
+#endif
+ for (i = 0; i < SharedRegion_module->cfg.numEntries; i++) {
+ region = &SharedRegion_module->regions[i];
+ if (region->entry.isValid) {
+#ifdef ENABLE_HEAPMP
+ if (region->entry.createHeap) {
+ base = MemoryOS_translate(region->entry.base,
+ Memory_XltFlags_Virt2Phys);
+ }
+ else
+#endif
+ {
+ base = region->entry.base;
+ }
+ if ((physAddr >= base) &&
+ (physAddr < (Ptr)((UInt32)base + region->entry.len))) {
+
+ regionId = i;
+ break;
+ }
+ }
+ }
+
+#ifdef ENABLE_LOCAL_LOCK
+ IGateProvider_leave (SharedRegion_module->localLock, key);
+#endif
+ }
+
+ GT_1trace (curTrace, GT_LEAVE, "SharedRegion_getIdPhys", regionId);
+
+ return (regionId);
+}
+
+/*
+ * ======== SharedRegion_getEntryPtr ========
+ */
+SharedRegion_Entry *SharedRegion_getEntryPtr(UInt16 id)
+{
+ SharedRegion_Region *region;
+
+ region = &(SharedRegion_module->regions[id]);
+ return ((SharedRegion_Entry *)(®ion->entry));
+}
diff --git a/host_linux/simple_buffer_example/host/SharedRegion/src/inc/_SharedRegion.h b/host_linux/simple_buffer_example/host/SharedRegion/src/inc/_SharedRegion.h
--- /dev/null
@@ -0,0 +1,217 @@
+/**
+ * @file _SharedRegion.h
+ *
+ * @brief Shared Region Manager internal functions
+ *
+ *
+ */
+/*
+ * ============================================================================
+ *
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Contact information for paper mail:
+ * Texas Instruments
+ * Post Office Box 655303
+ * Dallas, Texas 75265
+ * Contact information:
+ * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ * ============================================================================
+ *
+ */
+
+
+
+#ifndef _SharedRegion_H_0X5D8A
+#define _SharedRegion_H_0X5D8A
+
+
+/* Standard headers */
+#include "SharedRegion.h"
+#ifdef ENABLE_GATEMP
+#include <ti/ipc/HeapMemMP.h>
+#endif
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/*!
+ * @def SharedRegion_MODULEID
+ * @brief Module ID for Shared region manager.
+ */
+#define SharedRegion_MODULEID (0x5D8A)
+
+/*!
+ * @brief Name of the reserved name server used for application.
+ */
+#define SharedRegion_NAMESERVER "SHAREDREGION"
+
+/*!
+ * @def SharedRegion_INVALIDSRPTR
+ * @brief Invalid SharedRegion pointer. Default value for when translate
+ * is true.
+ */
+#define SharedRegion_INVALIDSRPTR (~0)
+
+
+/*!
+ * @brief Information stored on a per region basis
+ */
+typedef struct SharedRegion_Region_tag {
+ SharedRegion_Entry entry;
+ SizeT reservedSize;
+// HeapMemMP_Handle heap;
+} SharedRegion_Region;
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+
+/*!
+ * @brief Function to destroy the SharedRegion module.
+ *
+ * @sa SharedRegion_setup
+ */
+Int SharedRegion_destroy (Void);
+
+/*!
+ * @brief Creates a heap by owner of region for each SharedRegion.
+ * Function is called by Ipc_start(). Requires that SharedRegion 0
+ * be valid before calling start().
+ *
+ * @param None
+ *
+ * @sa Ipc_start
+ */
+Int SharedRegion_start (Void);
+
+/*!
+ * @brief Function to stop Shared Region 0
+ *
+ * @param None
+ *
+ * @sa Ipc_stop
+ */
+Int SharedRegion_stop (Void);
+
+/*!
+ * @brief Opens a heap, for non-owner processors, for each SharedRegion.
+ *
+ * @param None
+ *
+ * @sa SharedRegion_detach
+ */
+Int SharedRegion_attach (UInt16 remoteProcId);
+
+/*!
+ * @brief Closes a heap, for non-owner processors, for each SharedRegion.
+ *
+ * @param None
+ *
+ * @sa SharedRegion_attach
+ */
+Int SharedRegion_detach (UInt16 remoteProcId);
+
+/*!
+ * @brief Reserve shared region memory
+ *
+ * @param id Shared region id
+ * @param size Shared region size
+ *
+ * @sa None
+ */
+Ptr SharedRegion_reserveMemory (UInt16 id, UInt32 size);
+
+
+/*!
+ * @brief Reserve shared region memory
+ *
+ * @param id Shared region id
+ * @param size Shared region size
+ *
+ * @sa None
+ */
+Void SharedRegion_unreserveMemory (UInt16 id, UInt32 size);
+
+
+/*!
+ * @brief Sets the entry at the specified region id (doesn't create heap)
+ *
+ * @param regionId region id
+ * @param entry pointer to set region information.
+ *
+ * @return Status
+ * - #SharedRegion_S_SUCCESS: Operation was successful
+ * - #SharedRegion_E_FAIL: Region already exists or overlaps with
+ * with another region
+ * - #SharedRegion_E_MEMORY: Unable to create Heap
+ */
+Int _SharedRegion_setEntry(UInt16 regionId, SharedRegion_Entry *entry);
+
+
+/*! @brief Function to clear the reserved memory */
+Void SharedRegion_clearReservedMemory (Void);
+
+/*! @brief Return the region info
+ *
+ * @param i Shared region id
+ * @param region Pointer to region structure
+ */
+Void SharedRegion_getRegionInfo (UInt16 i,
+ SharedRegion_Region * region);
+
+/* User space internal API */
+/*! Sets the regions in user space that are created in knl space and
+ * not on user space
+ */
+Int
+_SharedRegion_setRegions (Void);
+
+/*! Clears the regions in user space that are created in knl space and
+ * not on user space.
+ */
+Int
+_SharedRegion_clearRegions (Void);
+
+/*! To know if shared region start has been called */
+Int
+_SharedRegion_isStarted(Void);
+
+/*! Get shared region Id from physical address */
+UInt16
+_SharedRegion_getIdPhys(Ptr physAddr);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif /* _SharedRegion_H_0X5D8A */
diff --git a/host_linux/simple_buffer_example/host/Std.h b/host_linux/simple_buffer_example/host/Std.h
--- /dev/null
@@ -0,0 +1,65 @@
+/**
+ * @file Std.h
+ *
+ * @brief This will have definitions of standard data types for
+ * platform abstraction.
+ *
+ *
+ */
+/*
+ * ============================================================================
+ *
+ * Copyright (c) 2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * ============================================================================
+ *
+ */
+
+
+#if !defined(T_STD_H)
+#define T_STD_H
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+#include <std_linux.h>
+
+typedef unsigned long long UInt64;
+
+/*! Data type for errors */
+typedef UInt32 Error_Block;
+
+/*! Initialize error block */
+#define Error_init(eb) *eb = 0
+
+#if defined (__cplusplus)
+}
+#endif
+
+#endif /* T_STD_H */
diff --git a/host_linux/simple_buffer_example/host/main_host.c b/host_linux/simple_buffer_example/host/main_host.c
--- /dev/null
@@ -0,0 +1,247 @@
+/*
+ * Copyright (c) 2013-2017 Texas Instruments Incorporated - http://www.ti.com
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * ======== main_host.c ========
+ *
+ */
+
+/* cstdlib header files */
+#include <stdio.h>
+#include <stdlib.h>
+
+/* package header files */
+#include <ti/ipc/Std.h>
+#include <ti/ipc/Ipc.h>
+#include <ti/ipc/transports/TransportRpmsg.h>
+
+#include <ti/ipc/MultiProc.h>
+
+/* local header files */
+#include "App.h"
+
+/* private functions */
+static Int Main_main(Void);
+static Int Main_parseArgs(Int argc, Char *argv[]);
+
+
+#define Main_USAGE "\
+Usage:\n\
+ app_host [options] procName\n\
+\n\
+Arguments:\n\
+ procName : the name of the remote processor\n\
+\n\
+Options:\n\
+ h : print this help message\n\
+ l : list the available remote names\n\
+\n\
+Examples:\n\
+ app_host DSP\n\
+ app_host -l\n\
+ app_host -h\n\
+\n"
+
+/* private data */
+static String Main_remoteProcName = NULL;
+
+
+/*
+ * ======== main ========
+ */
+Int main(Int argc, Char* argv[])
+{
+ Int status;
+
+ printf("--> main:\n");
+
+ /* configure the transport factory */
+ Ipc_transportConfig(&TransportRpmsg_Factory);
+
+ /* parse command line */
+ status = Main_parseArgs(argc, argv);
+
+ if (status < 0) {
+ goto leave;
+ }
+
+ /* Ipc initialization */
+ status = Ipc_start();
+
+ if (status >= 0) {
+ /* application create, exec, delete */
+ status = Main_main();
+
+ /* Ipc finalization */
+ Ipc_stop();
+ }
+ else {
+ printf("Ipc_start failed: status = %d\n", status);
+ goto leave;
+ }
+
+leave:
+ printf("<-- main:\n");
+ status = (status >= 0 ? 0 : status);
+
+ return (status);
+}
+
+
+/*
+ * ======== Main_main ========
+ */
+Int Main_main(Void)
+{
+ UInt16 remoteProcId;
+ Int status = 0;
+
+ printf("--> Main_main:\n");
+
+ remoteProcId = MultiProc_getId(Main_remoteProcName);
+
+ /* application create phase */
+ status = App_create(remoteProcId);
+
+ if (status < 0) {
+ goto leave;
+ }
+
+ /* application execute phase */
+ status = App_exec();
+
+ if (status < 0) {
+ goto leave;
+ }
+
+ /* application delete phase */
+ status = App_delete();
+
+ if (status < 0) {
+ goto leave;
+ }
+
+leave:
+ printf("<-- Main_main:\n");
+
+ if (status < 0)
+ printf("\n Host: Test Failed, error %d\n", status);
+ else
+ printf("\n Host: Test Passed \n");
+
+ status = (status >= 0 ? 0 : status);
+ return (status);
+}
+
+
+/*
+ * ======== Main_parseArgs ========
+ */
+Int Main_parseArgs(Int argc, Char *argv[])
+{
+ Int x, cp, opt, argNum;
+ UInt16 i, numProcs;
+ String name;
+ Int status = 0;
+
+
+ /* parse the command line options */
+ for (opt = 1; (opt < argc) && (argv[opt][0] == '-'); opt++) {
+ for (x = 0, cp = 1; argv[opt][cp] != '\0'; cp++) {
+ x = (x << 8) | (int)argv[opt][cp];
+ }
+
+ switch (x) {
+ case 'h': /* -h */
+ printf("%s", Main_USAGE);
+ exit(0);
+ break;
+
+ case 'l': /* -l */
+ printf("Processor List\n");
+ status = Ipc_start();
+ if (status >= 0) {
+ numProcs = MultiProc_getNumProcessors();
+ for (i = 0; i < numProcs; i++) {
+ name = MultiProc_getName(i);
+ printf(" procId=%d, procName=%s\n", i, name);
+ }
+ Ipc_stop();
+ }
+ else {
+ printf(
+ "Error: %s, line %d: Ipc_start failed\n",
+ __FILE__, __LINE__);
+ goto leave;
+ }
+ exit(0);
+ break;
+
+ default:
+ printf(
+ "Error: %s, line %d: invalid option, %c\n",
+ __FILE__, __LINE__, (Char)x);
+ printf("%s", Main_USAGE);
+ status = -1;
+ goto leave;
+ }
+ }
+
+ /* parse the command line arguments */
+ for (argNum = 1; opt < argc; argNum++, opt++) {
+
+ switch (argNum) {
+ case 1: /* name of proc #1 */
+ Main_remoteProcName = argv[opt];
+ break;
+
+ default:
+ printf(
+ "Error: %s, line %d: too many arguments\n",
+ __FILE__, __LINE__);
+ printf("%s", Main_USAGE);
+ status = -1;
+ goto leave;
+ }
+ }
+
+ /* validate command line arguments */
+ if (Main_remoteProcName == NULL) {
+ printf("Error: missing procName argument\n");
+ printf("%s", Main_USAGE);
+ status = -1;
+ goto leave;
+ }
+
+leave:
+ return(status);
+}
diff --git a/host_linux/simple_buffer_example/host/makefile b/host_linux/simple_buffer_example/host/makefile
--- /dev/null
@@ -0,0 +1,190 @@
+#
+# Copyright (c) 2017 Texas Instruments Incorporated - http://www.ti.com
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# * Neither the name of Texas Instruments Incorporated nor the names of
+# its contributors may be used to endorse or promote products derived
+# from this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+
+#
+# ======== Makefile ========
+#
+
+srcs = main_host.c App.c
+locallibsrcs = shared/bigdataxlat/bigdataxlat.c \
+ host/SharedRegion/src/SharedRegion.c \
+ host/HeapMem/src/HeapMem.c \
+ host/utils/List.c \
+ host/utils/Memory.c \
+ host/utils/Cache.c
+
+EXBASE = ..
+include $(EXBASE)/products.mak
+-include $(addprefix bin/$(PROFILE)/obj/,$(patsubst %.c,%.ov7A.dep,$(srcs)))
+-include $(addprefix bin/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.ov7A.dep,$(locallibsrcs)))
+
+objs = $(addprefix bin/$(PROFILE)/obj/,$(patsubst %.c,%.ov7A,$(srcs)))
+locallibobjs = $(addprefix bin/$(PLATFORM)/$(PROFILE)/obj/,$(patsubst %.c,%.ov7A,$(locallibsrcs)))
+
+ifdef LIBS_STATIC
+libs = libtitransportrpmsg.a \
+ libtiipc.a \
+ libtiipcutils.a
+else
+# Use dynamic or shared libs
+#libs = $(IPC_INSTALL_DIR)/linux/src/api/.libs/libtiipc.so \
+# $(IPC_INSTALL_DIR)/linux/src/utils/.libs/libtiipcutils.so \
+# $(IPC_INSTALL_DIR)/linux/src/transport/.libs/libtitransportrpmsg.so
+libs =
+endif
+
+all:
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+# $(MAKE) PROFILE=debug app_host
+ $(MAKE) PROFILE=release app_host
+
+help:
+ @$(ECHO) "make # build executables"
+ @$(ECHO) "make clean # clean everything"
+
+install:
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+# @$(MKDIR) $(EXEC_DIR)/debug
+# $(CP) bin/debug/app_host $(EXEC_DIR)/debug
+ @$(MKDIR) $(EXEC_DIR)/release
+ $(CP) bin/$(PLATFORM)/release/app_host $(EXEC_DIR)/release
+
+clean::
+ $(RMDIR) bin
+
+#
+# ======== rules ========
+#
+app_host: bin/$(PLATFORM)/$(PROFILE)/app_host
+bin/$(PLATFORM)/$(PROFILE)/app_host: $(objs) $(locallibobjs) $(libs)
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+ $(LD) $(LDFLAGS) -o $@ $^ $(LDLIBS)
+
+bin/$(PROFILE)/obj/%.ov7A: %.c
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+ $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+bin/$(PLATFORM)/$(PROFILE)/obj/%.ov7A: ../%.c
+ @$(ECHO) "#"
+ @$(ECHO) "# Making $@ ..."
+ $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
+
+# ======== install validation ========
+ifeq (install,$(MAKECMDGOALS))
+ifeq (,$(EXEC_DIR))
+$(error must specify EXEC_DIR)
+endif
+endif
+
+# ======== toolchain macros ========
+ifndef LINUX_SYSROOT_DIR
+CC = $(TOOLCHAIN_PREFIX)gcc
+AR = $(TOOLCHAIN_PREFIX)ar
+LD = $(TOOLCHAIN_PREFIX)gcc
+CFLAGS =
+CPPFLAGS =
+LDFLAGS = -L$(IPC_INSTALL_DIR)/linux/src/api/.libs/ \
+ -L$(IPC_INSTALL_DIR)/linux/src/utils/.libs \
+ -L$(IPC_INSTALL_DIR)/linux/src/transport/.libs \
+ -L$(CMEM_INSTALL_DIR)/src/cmem/api/.libs
+else
+LD = $(CC)
+endif
+
+CFLAGS += -c -MD -MF $@.dep
+ARFLAGS = cr
+
+CPPFLAGS += -D_REENTRANT
+
+CFLAGS += -Wall -ffloat-store -fPIC -Wunused -pthread -Dfar= $(CCPROFILE_$(PROFILE)) \
+ -I. -I.. -I../shared/bigdataxlat -I../shared/bigdataxlat/linux -I../host/SharedRegion -I../host/SharedRegion/src/inc \
+ -I../host/HeapMem -I../host/HeapMem/src/inc -I../host/utils
+
+ifdef LINUX_SYSROOT_DIR
+CFLAGS += -I$(LINUX_SYSROOT_DIR)
+else
+CFLAGS += -I$(IPC_INSTALL_DIR)/linux/include -I$(IPC_INSTALL_DIR)/packages -I$(CMEM_INSTALL_DIR)/include
+endif
+
+LDFLAGS += $(LDPROFILE_$(PROFILE)) -Wall -Wl,-Map=$@.map
+
+LDLIBS = -lpthread -lc -lrt -lticmem
+ifndef LIBS_STATIC
+LDLIBS +=-ltiipc -ltiipcutils -ltitransportrpmsg
+endif
+CCPROFILE_debug = -ggdb -D DEBUG
+CCPROFILE_release = -O3 -D NDEBUG
+
+LDPROFILE_debug = -ggdb
+LDPROFILE_release = -O3
+
+# ======== standard macros ========
+ifneq (,$(wildcard $(XDC_INSTALL_DIR)/bin/echo.exe))
+ # use these on Windows
+ CP = $(XDC_INSTALL_DIR)/bin/cp
+ ECHO = $(XDC_INSTALL_DIR)/bin/echo
+ MKDIR = $(XDC_INSTALL_DIR)/bin/mkdir -p
+ RM = $(XDC_INSTALL_DIR)/bin/rm -f
+ RMDIR = $(XDC_INSTALL_DIR)/bin/rm -rf
+else
+ # use these on Linux
+ CP = cp
+ ECHO = echo
+ MKDIR = mkdir -p
+ RM = rm -f
+ RMDIR = rm -rf
+endif
+
+# ======== create output directories ========
+ifneq (clean,$(MAKECMDGOALS))
+ifneq (,$(PROFILE))
+ifeq (,$(wildcard bin/$(PROFILE)/obj))
+ $(shell $(MKDIR) -p bin/$(PROFILE)/obj)
+endif
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj/shared/bigdataxlat/linux))
+ $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj/shared/bigdataxlat/linux)
+endif
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj/host/SharedRegion/src))
+ $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj/host/SharedRegion/src)
+endif
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj/host/HeapMem/src))
+ $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj/host/HeapMem/src)
+endif
+ifeq (,$(wildcard bin/$(PLATFORM)/$(PROFILE)/obj/host/utils))
+ $(shell $(MKDIR) -p bin/$(PLATFORM)/$(PROFILE)/obj/host/utils)
+endif
+endif
+endif
diff --git a/host_linux/simple_buffer_example/host/std_linux.h b/host_linux/simple_buffer_example/host/std_linux.h
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/**
+ * @file ti/syslink/inc/knl/Linux/std_linux.h
+ */
+
+#if !defined(STD_LINUX_H)
+#define STD_LINUX_H
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* Branch Prediction for likely true case */
+#define EXPECT_TRUE(x) __builtin_expect(!!(x), 1)
+/* Branch Prediction for likely false case */
+#define EXPECT_FALSE(x) __builtin_expect(!!(x), 0)
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+#endif
diff --git a/host_linux/simple_buffer_example/host/utils/Cache.c b/host_linux/simple_buffer_example/host/utils/Cache.c
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * @file Cache.c
+ *
+ * @brief Cache API implementation
+ *
+ *
+ * ============================================================================
+ *
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Contact information for paper mail:
+ * Texas Instruments
+ * Post Office Box 655303
+ * Dallas, Texas 75265
+ * Contact information:
+ * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ * ============================================================================
+ *
+ */
+
+/* Standard headers */
+#include <ti/ipc/Std.h>
+#include <ti/cmem.h>
+
+#if defined (__cplusplus)
+extern "C" {
+#endif /* defined (__cplusplus) */
+
+/*
+ * ======== Cache_inv ========
+ */
+Void Cache_inv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait)
+{
+ /* Do cache inv using CMEM device */
+ CMEM_cacheInv(blockPtr, byteCnt);
+
+}
+
+/*
+ * ======== Cache_wb ========
+ */
+Void Cache_wb(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait)
+{
+ /* Do cache writeback using CMEM device */
+ CMEM_cacheWb(blockPtr, byteCnt);
+}
+
+/*
+ * ======== Cache_wbInv ========
+ */
+Void Cache_wbInv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait)
+{
+ /* Do cache write back and inv using CMEM device */
+ CMEM_cacheWbInv(blockPtr, byteCnt);
+}
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
diff --git a/host_linux/simple_buffer_example/host/utils/Cache.h b/host_linux/simple_buffer_example/host/utils/Cache.h
--- /dev/null
@@ -0,0 +1,157 @@
+/**
+ * @file Cache.h
+ *
+ * @brief Defines Cache API interface.
+ *
+ *
+ */
+/*
+ * ============================================================================
+ *
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Contact information for paper mail:
+ * Texas Instruments
+ * Post Office Box 655303
+ * Dallas, Texas 75265
+ * Contact information:
+ * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ * ============================================================================
+ *
+ */
+
+
+
+#ifndef CACHE_H
+#define CACHE_H
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif /* defined (__cplusplus) */
+
+/* =============================================================================
+ * All success and failure codes for the module
+ * =============================================================================
+ */
+
+/*!
+ * @def Cache_S_ALREADYSETUP
+ * @brief Cache module is already setup.
+ */
+#define Cache_S_ALREADYSETUP (1)
+
+/*!
+ * @def Cache_S_SUCCESS
+ * @brief Operation is successful.
+ */
+#define Cache_S_SUCCESS (0)
+
+/*!
+ * @def Cache_E_FAIL
+ * @brief Generic failure.
+ */
+#define Cache_E_FAIL (-1)
+
+/*!
+ * @def Cache_E_INVALIDARG
+ * @brief Argument passed to a function is invalid.
+ */
+#define Cache_E_INVALIDARG (-2)
+
+/*!
+ * @def Cache_E_OSFAILURE
+ * @brief Failure in OS call.
+ */
+#define Cache_E_OSFAILURE (-3)
+
+/* ================================
+ * Enums for the module
+ * ================================
+ */
+/*! Lists of bitmask cache types */
+enum Cache_Type {
+ Cache_Type_L1P = 0x1, /*! Level 1 Program cache */
+ Cache_Type_L1D = 0x2, /*! Level 1 Data cache */
+ Cache_Type_L1 = 0x3, /*! Level 1 caches */
+ Cache_Type_L2P = 0x4, /*! Level 2 Program cache */
+ Cache_Type_L2D = 0x8, /*! Level 2 Data cache */
+ Cache_Type_L2 = 0xC, /*! Level 2 caches */
+ Cache_Type_ALL = 0xffff /*! All caches */
+};
+
+/*! Lists of cache modes */
+enum Cache_Mode {
+ Cache_Mode_FREEZE,
+ Cache_Mode_BYPASS,
+ Cache_Mode_NORMAL
+};
+
+/*!
+ * @brief Invalidate the Cache module.
+ *
+ * @sa Cache_inv
+ */
+Void Cache_inv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait);
+
+/*!
+ * @brief Writeback the Cache module.
+ *
+ * @sa Cache_wb
+ */
+Void Cache_wb(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait);
+
+/*!
+ * @brief Write Back and Invalidate the Cache module.
+ *
+ * @sa Cache_wbInv
+ */
+Void Cache_wbInv(Ptr blockPtr, UInt32 byteCnt, Bits16 type, Bool wait);
+
+/*!
+ * @brief Wait for cache operation to complete.
+ *
+ * @sa Cache_wait
+ */
+Void Cache_wait(Void);
+
+/*!
+ * @brief Set the mode of Cache module.
+ *
+ * @sa Cache_setMode
+ */
+enum Cache_Mode Cache_setMode(Bits16 type, enum Cache_Mode mode);
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* CACHE_H */
diff --git a/host_linux/simple_buffer_example/host/utils/IHeap.h b/host_linux/simple_buffer_example/host/utils/IHeap.h
--- /dev/null
@@ -0,0 +1,291 @@
+/**
+ * @file IHeap.h
+ *
+ * @brief Defines Heap based memory allocator.
+ *
+ * Heap implementation that manages fixed size buffers that can be
+ * used in a multiprocessor system with shared memory.
+ *
+ * The Heap manager provides functions to allocate and free storage
+ * from a heap of type Heap which inherits from IHeap. Heap manages
+ * a single fixed-size buffer, split into equally sized allocable
+ * blocks.
+ *
+ * The Heap manager is intended as a very fast memory
+ * manager which can only allocate blocks of a single size. It is
+ * ideal for managing a heap that is only used for allocating a
+ * single type of object, or for objects that have very similar
+ * sizes.
+ *
+ * This module is instance based. Each instance requires shared
+ * memory (for the buffers and other internal state). This is
+ * specified via the sharedAddr parameter to the create. The proper
+ * sharedAddrSize parameter can be determined via the
+ * sharedMemReq call. Note: the parameters to this
+ * function must be the same that will used to create the instance.
+ *
+ * The Heap module uses a NameServer instance to
+ * store instance information when an instance is created and the
+ * name parameter is non-NULL. If a name is supplied, it must be
+ * unique for all Heap instances.
+ *
+ * The create initializes the shared memory as needed. The shared
+ * memory must be initialized to 0 before the Heap instance is
+ * created or opened.
+ *
+ * Once an instance is created, an open can be performed. The
+ * open is used to gain access to the same Heap instance.
+ * Generally an instance is created on one processor and opened
+ * on the other processor(s).
+ *
+ * The open returns a Heap instance handle like the create,
+ * however the open does not modify the shared memory.
+ *
+ * There are two options when opening the instance:
+ * -Supply the same name as specified in the create. The Heap
+ * module queries the NameServer to get the needed information.
+ * -Supply the same sharedAddr value as specified in the create.
+ *
+ * If the open is called before the instance is created, open
+ * returns NULL.
+ *
+ * Constraints:
+ * -Align parameter must be a power of 2.
+ * -The buffer passed to dynamically create a Heap must be aligned
+ * according to the alignment parameter, and must be large enough
+ * to account for the actual block size after it has been rounded
+ * up to a multiple of the alignment.
+ *
+ *
+ */
+/*
+ * ============================================================================
+ *
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Contact information for paper mail:
+ * Texas Instruments
+ * Post Office Box 655303
+ * Dallas, Texas 75265
+ * Contact information:
+ * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ * ============================================================================
+ *
+ */
+
+
+
+#ifndef HEAP_H_0x7033
+#define HEAP_H_0x7033
+
+
+#include <assert.h>
+/* OSAL and utils */
+#include "MemoryDefs.h"
+#include <Trace.h>
+
+
+#if defined (__cplusplus)
+extern "C" {
+#endif
+
+/* =============================================================================
+ * Forward declarations
+ * =============================================================================
+ */
+/*! @brief Forward declaration of structure defining object for the
+ * Heap module
+ */
+typedef struct IHeap_Object_tag IHeap_Object;
+
+/*!
+ * @brief Handle for the Heap Buf.
+ */
+typedef IHeap_Object * IHeap_Handle;
+
+
+/* =============================================================================
+ * Function pointer types for heap operations
+ * =============================================================================
+ */
+/*! @brief Type for function pointer to allocate a memory block */
+typedef Ptr (*IHeap_allocFxn) (IHeap_Handle handle,
+ SizeT size,
+ SizeT align);
+
+/*! @brief Type for function pointer to free a memory block */
+typedef Void (*IHeap_freeFxn) (IHeap_Handle handle,
+ Ptr block,
+ SizeT size);
+
+/*! @brief Type for function pointer to get memory related statistics */
+typedef Void (*IHeap_getStatsFxn) (IHeap_Handle handle,
+ Memory_Stats * stats);
+
+/*
+ * ! @brief Type for function pointer to indicate whether the heap may block
+ * during an alloc or free call
+ */
+typedef Bool (*IHeap_isBlockingFxn) (IHeap_Handle handle);
+
+/*! @brief Type for function pointer to get handle to kernel object */
+typedef Ptr (*IHeap_getKnlHandleFxn) (IHeap_Handle handle);
+
+
+/* =============================================================================
+ * Structures & Enums
+ * =============================================================================
+ */
+/*!
+ * @brief Structure for the Handle for the Heap.
+ */
+struct IHeap_Object_tag {
+ IHeap_allocFxn alloc;
+ /*!< Allocate a block */
+ IHeap_freeFxn free;
+ /*!< Free a block */
+ IHeap_getStatsFxn getStats;
+ /*!< Get statistics */
+ IHeap_isBlockingFxn isBlocking;
+ /*!< Does the Heap block during alloc/free? */
+ IHeap_getKnlHandleFxn getKnlHandle;
+ /*!< Get kernel object handle */
+ Ptr obj;
+ /*!< Actual Heap Handle */
+};
+
+
+/* =============================================================================
+ * APIs
+ * =============================================================================
+ */
+/*!
+ * @brief Allocate a block of memory of specified size.
+ *
+ * @param handle Handle to previously created/opened instance.
+ * @param size Size to be allocated (in bytes)
+ * @param align Alignment for allocation (power of 2)
+ *
+ * @retval buffer Allocated buffer
+ *
+ * @sa IHeap_free
+ */
+static inline Ptr IHeap_alloc (IHeap_Handle handle,
+ SizeT size,
+ SizeT align)
+{
+ Ptr buffer;
+
+ GT_assert (curTrace, (((IHeap_Object *) handle)->alloc != NULL));
+ buffer = ((IHeap_Object *) handle)->alloc (handle, size, align);
+ return (buffer);
+}
+
+
+/*!
+ * @brief Frees a block of memory.
+ *
+ * @param handle Handle to previously created/opened instance.
+ * @param block Block of memory to be freed.
+ * @param size Size to be freed (in bytes)
+ *
+ * @sa Heap_alloc
+ */
+static inline Void IHeap_free (IHeap_Handle handle,
+ Ptr block,
+ SizeT size)
+{
+ GT_assert (curTrace, (((IHeap_Object *) handle)->free != NULL));
+ ((IHeap_Object *) handle)->free (handle, block, size);
+}
+
+
+/*!
+ * @brief Get memory statistics
+ *
+ * @param handle Handle to previously created/opened instance.
+ * @params stats Memory statistics structure
+ *
+ * @sa
+ */
+static inline Void IHeap_getStats (IHeap_Handle handle,
+ Memory_Stats * stats)
+{
+ GT_assert (curTrace, (((IHeap_Object *) handle)->getStats != NULL));
+ ((IHeap_Object *) handle)->getStats (handle, stats);
+}
+
+
+/*!
+ * @brief Indicate whether the heap may block during an alloc or free call
+ *
+ * @param handle Handle to previously created/opened instance.
+ *
+ * @retval TRUE Heap is blocking
+ * @retval FALSE Heap is non-blocking
+ *
+ * @sa
+ */
+static inline Bool IHeap_isBlocking (IHeap_Handle handle)
+{
+ Bool isBlocking;
+ GT_assert (curTrace, (((IHeap_Object *) handle)->isBlocking != NULL));
+ isBlocking = ((IHeap_Object *) handle)->isBlocking (handle);
+ return (isBlocking);
+}
+
+
+/*!
+ * @brief Function to get the kernel object pointer embedded in userspace heap.
+ * Some Heap implementations return the kernel object handle.
+ * Heaps which do not have kernel object pointer embedded return NULL.
+ *
+ * @params handle handle to a heap instance
+ *
+ * @retval handle Handle to kernel object.
+ *
+ * @sa
+ */
+static inline Ptr IHeap_getKnlHandle (IHeap_Handle handle)
+{
+ Ptr knlHandle;
+ GT_assert (curTrace, (((IHeap_Object *) handle)->getKnlHandle != NULL));
+ knlHandle = ((IHeap_Object *) handle)->getKnlHandle (handle);
+ return (knlHandle);
+}
+
+
+#if defined (__cplusplus)
+}
+#endif /* defined (__cplusplus) */
+
+
+#endif /* HEAP_H_0x7033 */
+
diff --git a/host_linux/simple_buffer_example/host/utils/List.c b/host_linux/simple_buffer_example/host/utils/List.c
--- /dev/null
@@ -0,0 +1,798 @@
+/*
+ * @file List.c
+ *
+ * @brief Creates a doubly linked list.
+ *
+ *
+ * ============================================================================
+ *
+ * Copyright (c) 2008-2017, Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of Texas Instruments Incorporated nor the names of
+ * its contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * Contact information for paper mail:
+ * Texas Instruments
+ * Post Office Box 655303
+ * Dallas, Texas 75265
+ * Contact information:
+ * http://www-k.ext.ti.com/sc/technical-support/product-information-centers.htm?
+ * DCMP=TIHomeTracking&HQS=Other+OT+home_d_contact
+ * ============================================================================
+ *
+ */
+
+/* Standard headers */
+#include <ti/ipc/Std.h>
+#include "Std.h"
+#include "List.h"
+#include "Memory.h"
+
+#include "Trace.h"
+
+/* =============================================================================
+ * All success and failure codes for the module. Defined here because they are
+ * only used internally.
+ * =============================================================================
+ */
+
+/*!
+ * @def List_S_BUSY
+ * @brief The resource is still in use
+ */
+#define List_S_BUSY 2
+
+/*!
+ * @def List_S_ALREADYSETUP
+ * @brief The module has been already setup
+ */
+#define List_S_ALREADYSETUP 1
+
+/*!
+ * @def List_S_SUCCESS
+ * @brief Operation is successful.
+ */
+#define List_S_SUCCESS 0
+
+/*!
+ * @def List_E_FAIL
+ * @brief Generic failure.
+ */
+#define List_E_FAIL -1
+
+/*!
+ * @def List_E_INVALIDARG
+ * @brief Argument passed to function is invalid.
+ */
+#define List_E_INVALIDARG -2
+
+/*!
+ * @def List_E_MEMORY
+ * @brief Operation resulted in memory failure.
+ */
+#define List_E_MEMORY -3
+
+/*!
+ * @def List_E_ALREADYEXISTS
+ * @brief The specified entity already exists.
+ */
+#define List_E_ALREADYEXISTS -4
+
+/*!
+ * @def List_E_NOTFOUND
+ * @brief Unable to find the specified entity.
+ */
+#define List_E_NOTFOUND -5
+
+/*!
+ * @def List_E_TIMEOUT
+ * @brief Operation timed out.
+ */
+#define List_E_TIMEOUT -6
+
+/*!
+ * @def List_E_INVALIDSTATE
+ * @brief Module is not initialized.
+ */
+#define List_E_INVALIDSTATE -7
+
+/*!
+ * @def List_E_OSFAILURE
+ * @brief A failure occurred in an OS-specific call
+ */
+#define List_E_OSFAILURE -8
+
+/*!
+ * @def List_E_RESOURCE
+ * @brief Specified resource is not available
+ */
+#define List_E_RESOURCE -9
+
+/*!
+ * @def List_E_RESTART
+ * @brief Operation was interrupted. Please restart the operation
+ */
+#define List_E_RESTART -10
+
+/* Function to initialize the parameters structure */
+Void
+List_Params_init (List_Params * params)
+{
+ GT_1trace (curTrace, GT_ENTER, "List_Params_init", params);
+
+ GT_assert (curTrace, (params != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (params == NULL) {
+ /* No retVal since this is a Void function. */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_Params_init",
+ List_E_INVALIDARG,
+ "Argument of type (List_Params *) is NULL!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "List_Params_init");
+}
+
+/* Function to create a list. */
+List_Handle
+List_create (List_Params * params, Error_Block *eb)
+{
+ List_Object * obj = NULL;
+
+ GT_1trace (curTrace, GT_ENTER, "List_create", params);
+
+ (void) params;
+ (void) eb;
+
+ /* heapHandle can be NULL if created from default OS memory. */
+ obj = (List_Object *) Memory_alloc (NULL,
+ sizeof (List_Object),
+ 0,
+ NULL);
+
+ GT_assert (curTrace, (obj != NULL));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj == NULL) {
+ /*! @retval NULL Allocate memory for handle failed */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_create",
+ List_E_MEMORY,
+ "Allocating memory for handle failed");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj->elem.next = obj->elem.prev = &(obj->elem);
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "List_create", obj);
+
+ /*! @retval valid-handle Operation successful */
+ return (List_Handle) obj;
+}
+
+/* Function to delete the list */
+Void
+List_delete (List_Handle * handlePtr)
+{
+ List_Object * obj;
+
+ GT_1trace (curTrace, GT_ENTER, "List_delete", handlePtr);
+
+ GT_assert (curTrace, (handlePtr != NULL));
+ GT_assert (curTrace, ((handlePtr != NULL) && (*handlePtr != NULL)));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (handlePtr == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_delete",
+ List_E_INVALIDARG,
+ "handlePtr passed is invalid!");
+ }
+ else if (*handlePtr == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_delete",
+ List_E_INVALIDARG,
+ "*handlePtr passed is invalid!");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ obj = (List_Object *) (*handlePtr);
+ Memory_free (NULL, obj, sizeof (List_Object));
+ *handlePtr = NULL;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "List_delete");
+}
+
+/* Function to initialize the List head */
+Void List_construct(List_Object *obj, List_Params *params)
+{
+ GT_1trace (curTrace, GT_ENTER, "List_construct", obj);
+
+ GT_assert (curTrace, (obj != NULL));
+ /* params is unused, so don't assert anything about it */
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj == NULL) {
+ GT_setFailureReason(curTrace, GT_4CLASS, "List_construct",
+ List_E_INVALIDARG, "Invalid NULL passed for obj parameter");
+ }
+ else {
+#endif
+
+ obj->elem.next = obj->elem.prev = &(obj->elem);
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif
+
+ GT_0trace(curTrace, GT_LEAVE, "List_construct");
+}
+
+/* Function to destruct List object */
+Void List_destruct(List_Object *obj)
+{
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key;
+#endif
+
+ GT_1trace(curTrace, GT_ENTER, "List_destruct", obj);
+
+ GT_assert(curTrace, (obj != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (obj == NULL) {
+ GT_setFailureReason(curTrace, GT_4CLASS, "List_destruct",
+ List_E_INVALIDARG, "Invalid NULL passed for obj parameter");
+ }
+ else {
+#endif
+
+#ifdef ENABLE_LOCAL_LOCK
+ key = Gate_enterSystem ();;
+#endif
+ obj->elem.next = NULL;
+ obj->elem.prev = NULL;
+#ifdef ENABLE_LOCAL_LOCK
+ Gate_leaveSystem(key);
+#endif
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif
+
+ GT_0trace (curTrace, GT_LEAVE, "List_destruct");
+}
+
+/* Function to remove specific elem from list */
+Void
+List_elemClear (List_Elem * elem)
+{
+ GT_1trace (curTrace, GT_ENTER, "List_elemClear", elem);
+
+ GT_assert (curTrace, (elem != NULL));
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (elem == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_elemClear",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for elem parameter");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ elem->next = elem->prev = elem;
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "List_elemClear");
+}
+
+/* Function to check if list is empty */
+Bool
+List_empty (List_Handle handle)
+{
+ Bool isEmpty = FALSE;
+ List_Object * obj = (List_Object *) handle;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key = 0;
+#endif
+
+ GT_1trace (curTrace, GT_ENTER, "List_empty", handle);
+
+ GT_assert (curTrace, (handle != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (handle == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_empty",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for handle parameter");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_LOCAL_LOCK
+ key = Gate_enterSystem();
+#endif
+
+ if (obj->elem.next == &(obj->elem)) {
+ /*! @retval TRUE List is empty */
+ isEmpty = TRUE;
+ }
+#ifdef ENABLE_LOCAL_LOCK
+ Gate_leaveSystem(key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "List_empty", isEmpty);
+
+ /*! @retval FALSE List is not empty */
+ return isEmpty;
+}
+
+/* Function to get front element */
+Ptr
+List_get (List_Handle handle)
+{
+ List_Elem * elem = NULL;
+ List_Object * obj = (List_Object *) handle;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key = 0;
+#endif
+
+ GT_1trace (curTrace, GT_ENTER, "List_get", handle);
+
+ GT_assert (curTrace, (handle != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (handle == NULL) {
+ /*! @retval NULL Invalid NULL passed for handle parameter */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_get",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for handle parameter");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_LOCAL_LOCK
+ key = Gate_enterSystem();
+#endif
+
+ elem = List_dequeue(obj);
+
+#ifdef ENABLE_LOCAL_LOCK
+ Gate_leaveSystem(key);
+#endif
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "List_get", elem);
+
+ /*! @retval Valid-pointer Pointer to first element */
+ return elem ;
+}
+
+/* Function to put elem at the end */
+Void
+List_put (List_Handle handle, List_Elem * elem)
+{
+ List_Object * obj = (List_Object *) handle;
+#ifdef ENABLE_LOCAL_LOCK
+ IArg key = 0;
+#endif
+
+ GT_2trace (curTrace, GT_ENTER, "List_put", handle, elem);
+
+ GT_assert (curTrace, (handle != NULL));
+ GT_assert (curTrace, (elem != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (handle == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_put",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for handle parameter");
+ }
+ else if (elem == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_put",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for elem parameter");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+#ifdef ENABLE_LOCAL_LOCK
+ key = Gate_enterSystem();
+#endif
+ List_enqueue (obj, elem);
+#ifdef ENABLE_LOCAL_LOCK
+ Gate_leaveSystem(key);
+#endif
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "List_put");
+}
+
+/* Function to get next elem of current one (non-atomic) */
+Ptr
+List_next (List_Handle handle, List_Elem * elem)
+{
+ List_Elem * retElem = NULL;
+ List_Object * obj = (List_Object *) handle;
+
+ GT_2trace (curTrace, GT_ENTER, "List_Next", handle, elem);
+
+ GT_assert (curTrace, (handle != NULL)) ;
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (handle == NULL) {
+ /*! @retval NULL Invalid NULL passed for handle parameter */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_next",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for handle parameter");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* elem == NULL -> start at the head */
+ if (elem == NULL) {
+ retElem = obj->elem.next;
+ }
+ else {
+ retElem = elem->next;
+ }
+
+ if (retElem == (List_Elem *) obj) {
+ /*! @retval NULL List reached end or list is empty */
+ retElem = NULL;
+ }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "List_Next", retElem);
+
+ /*! @retval Valid-pointer Pointer to the next element */
+ return retElem;
+}
+
+/* Function to get previous elem of current one (non-atomic) */
+Ptr
+List_prev (List_Handle handle, List_Elem * elem)
+{
+ List_Elem * retElem = NULL;
+ List_Object * obj = (List_Object *) handle;
+
+ GT_2trace (curTrace, GT_ENTER, "List_prev", handle, elem);
+
+ GT_assert (curTrace, (handle != NULL)) ;
+ GT_assert (curTrace, (elem != NULL)) ;
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (handle == NULL) {
+ /*! @retval NULL Invalid NULL passed for handle parameter */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_prev",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for handle parameter");
+ }
+ else if (elem == NULL) {
+ /*! @retval NULL Invalid NULL passed for elem parameter */
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_prev",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for elem parameter");
+ }
+ else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+ /* elem == NULL -> start at the head */
+ if (elem == NULL) {
+ retElem = obj->elem.prev;
+ }
+ else {
+ retElem = elem->prev;
+ }
+
+ if (retElem == (List_Elem *)obj) {
+ /*! @retval NULL List reached end or list is empty */
+ retElem = NULL;
+ }
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_1trace (curTrace, GT_LEAVE, "List_prev", retElem);
+
+ /*! @retval Valid-pointer Pointer to the prev element */
+ return retElem;
+}
+
+/* Function to insert elem before existing elem */
+Void
+List_insert (List_Handle handle, List_Elem * newElem, List_Elem * curElem)
+{
+ GT_3trace (curTrace, GT_ENTER, "List_insert", handle, newElem, curElem);
+
+ GT_assert (curTrace, (handle != NULL));
+ GT_assert (curTrace, (newElem != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ if (handle == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_insert",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for handle parameter");
+ }
+ else if (newElem == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_insert",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for newElem parameter");
+ }
+ else if (curElem == NULL) {
+ GT_setFailureReason (curTrace,
+ GT_4CLASS,
+ "List_insert",
+ List_E_INVALIDARG,
+ "Invalid NULL passed for curElem parameter use List_putHead");
+ }else {
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ /* Cannot directly call enqueue since the object has other fields */
+ newElem->next = curElem;
+ newElem->prev = curElem->prev;
+ newElem->prev->next = newElem;
+ curElem->prev = newElem;
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+ }
+#endif /* if !defined(SYSLINK_BUILD_OPTIMIZE) */
+
+ GT_0trace (curTrace, GT_LEAVE, "List_insert");
+}
+
+/* Function to remove specific elem from list */
+Void
+List_remove (List_Handle handle, List_Elem * elem)
+{
+ GT_2trace (curTrace, GT_ENTER, "List_remove", handle, elem);
+
+ GT_assert (curTrace, (handle != NULL));
+ GT_assert (curTrace, (elem != NULL));
+
+#if !defined(SYSLINK_BUILD_OPTIMIZE)
+