summaryrefslogtreecommitdiffstatshomepage
path: root/cc3200/simplelink/source/spawn.c
diff options
context:
space:
mode:
Diffstat (limited to 'cc3200/simplelink/source/spawn.c')
-rw-r--r--cc3200/simplelink/source/spawn.c197
1 files changed, 197 insertions, 0 deletions
diff --git a/cc3200/simplelink/source/spawn.c b/cc3200/simplelink/source/spawn.c
new file mode 100644
index 0000000000..fdf1930ca4
--- /dev/null
+++ b/cc3200/simplelink/source/spawn.c
@@ -0,0 +1,197 @@
+/*
+ * spawn.c - CC31xx/CC32xx Host Driver Implementation
+ *
+ * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ *
+ * 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.
+ *
+*/
+
+
+
+/*****************************************************************************/
+/* Include files */
+/*****************************************************************************/
+#include "simplelink.h"
+
+
+#if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
+
+#define _SL_MAX_INTERNAL_SPAWN_ENTRIES 10
+
+typedef struct _SlInternalSpawnEntry_t
+{
+ _SlSpawnEntryFunc_t pEntry;
+ void* pValue;
+ struct _SlInternalSpawnEntry_t* pNext;
+}_SlInternalSpawnEntry_t;
+
+typedef struct
+{
+ _SlInternalSpawnEntry_t SpawnEntries[_SL_MAX_INTERNAL_SPAWN_ENTRIES];
+ _SlInternalSpawnEntry_t* pFree;
+ _SlInternalSpawnEntry_t* pWaitForExe;
+ _SlInternalSpawnEntry_t* pLastInWaitList;
+ _SlSyncObj_t SyncObj;
+ _SlLockObj_t LockObj;
+}_SlInternalSpawnCB_t;
+
+_SlInternalSpawnCB_t g_SlInternalSpawnCB;
+
+
+void _SlInternalSpawnTaskEntry()
+{
+ _i16 i;
+ _SlInternalSpawnEntry_t* pEntry;
+ _u8 LastEntry;
+
+ /* create and lock the locking object. lock in order to avoid race condition
+ on the first creation */
+ sl_LockObjCreate(&g_SlInternalSpawnCB.LockObj,"SlSpawnProtect");
+ sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_NO_WAIT);
+
+ /* create and clear the sync object */
+ sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync");
+ sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT);
+
+ g_SlInternalSpawnCB.pFree = &g_SlInternalSpawnCB.SpawnEntries[0];
+ g_SlInternalSpawnCB.pWaitForExe = NULL;
+ g_SlInternalSpawnCB.pLastInWaitList = NULL;
+
+ /* create the link list between the entries */
+ for (i=0 ; i<_SL_MAX_INTERNAL_SPAWN_ENTRIES - 1 ; i++)
+ {
+ g_SlInternalSpawnCB.SpawnEntries[i].pNext = &g_SlInternalSpawnCB.SpawnEntries[i+1];
+ g_SlInternalSpawnCB.SpawnEntries[i].pEntry = NULL;
+ }
+ g_SlInternalSpawnCB.SpawnEntries[i].pNext = NULL;
+
+ sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
+
+
+ /* here we ready to execute entries */
+
+ while (TRUE)
+ {
+ sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_WAIT_FOREVER);
+ /* go over all entries that already waiting for execution */
+ LastEntry = FALSE;
+ do
+ {
+ /* get entry to execute */
+ sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER);
+
+ pEntry = g_SlInternalSpawnCB.pWaitForExe;
+ if ( NULL == pEntry )
+ {
+ sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
+ break;
+ }
+ g_SlInternalSpawnCB.pWaitForExe = pEntry->pNext;
+ if (pEntry == g_SlInternalSpawnCB.pLastInWaitList)
+ {
+ g_SlInternalSpawnCB.pLastInWaitList = NULL;
+ LastEntry = TRUE;
+ }
+
+ sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
+
+
+ /* pEntry could be null in case that the sync was already set by some
+ of the entries during execution of earlier entry */
+ if (NULL != pEntry)
+ {
+ pEntry->pEntry(pEntry->pValue);
+ /* free the entry */
+ sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER);
+
+ pEntry->pNext = g_SlInternalSpawnCB.pFree;
+ g_SlInternalSpawnCB.pFree = pEntry;
+
+
+ if (NULL != g_SlInternalSpawnCB.pWaitForExe)
+ {
+ /* new entry received meanwhile */
+ LastEntry = FALSE;
+ }
+
+ sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
+
+ }
+
+ }while (!LastEntry);
+ }
+}
+
+
+_i16 _SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags)
+{
+ _i16 Res = 0;
+ _SlInternalSpawnEntry_t* pSpawnEntry;
+
+ if (NULL == pEntry)
+ {
+ Res = -1;
+ }
+ else
+ {
+ sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER);
+
+ pSpawnEntry = g_SlInternalSpawnCB.pFree;
+ g_SlInternalSpawnCB.pFree = pSpawnEntry->pNext;
+
+ pSpawnEntry->pEntry = pEntry;
+ pSpawnEntry->pValue = pValue;
+ pSpawnEntry->pNext = NULL;
+
+ if (NULL == g_SlInternalSpawnCB.pWaitForExe)
+ {
+ g_SlInternalSpawnCB.pWaitForExe = pSpawnEntry;
+ g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
+ }
+ else
+ {
+ g_SlInternalSpawnCB.pLastInWaitList->pNext = pSpawnEntry;
+ g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
+ }
+
+ sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
+ /* this sync is called after releasing the lock object to avoid unnecessary context switches */
+ sl_SyncObjSignal(&g_SlInternalSpawnCB.SyncObj);
+ }
+
+ return Res;
+}
+
+
+
+
+
+#endif