TI's CC3100 host driver and demo. Experimental and a work in progress.

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3100_spawn.cpp Source File

cc3100_spawn.cpp

00001 /*
00002  * spawn.c - CC31xx/CC32xx Host Driver Implementation
00003  *
00004  * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/ 
00005  * 
00006  * 
00007  *  Redistribution and use in source and binary forms, with or without 
00008  *  modification, are permitted provided that the following conditions 
00009  *  are met:
00010  *
00011  *    Redistributions of source code must retain the above copyright 
00012  *    notice, this list of conditions and the following disclaimer.
00013  *
00014  *    Redistributions in binary form must reproduce the above copyright
00015  *    notice, this list of conditions and the following disclaimer in the 
00016  *    documentation and/or other materials provided with the   
00017  *    distribution.
00018  *
00019  *    Neither the name of Texas Instruments Incorporated nor the names of
00020  *    its contributors may be used to endorse or promote products derived
00021  *    from this software without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00026  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
00027  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
00028  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00029  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00030  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00031  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00032  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00033  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00034  *
00035 */
00036 
00037 
00038 
00039 /*****************************************************************************/
00040 /* Include files                                                             */
00041 /*****************************************************************************/
00042 #include "cc3100_simplelink.h"
00043 
00044 
00045 #if (defined (SL_PLATFORM_MULTI_THREADED)) && (!defined (SL_PLATFORM_EXTERNAL_SPAWN))
00046 
00047 #define _SL_MAX_INTERNAL_SPAWN_ENTRIES      10
00048 
00049 typedef struct _SlInternalSpawnEntry_t
00050 {
00051     _SlSpawnEntryFunc_t                 pEntry;
00052     void*                               pValue;
00053     struct _SlInternalSpawnEntry_t*     pNext;
00054 }_SlInternalSpawnEntry_t;
00055 
00056 typedef struct
00057 {
00058     _SlInternalSpawnEntry_t     SpawnEntries[_SL_MAX_INTERNAL_SPAWN_ENTRIES];
00059     _SlInternalSpawnEntry_t*    pFree;
00060     _SlInternalSpawnEntry_t*    pWaitForExe;
00061     _SlInternalSpawnEntry_t*    pLastInWaitList;
00062     _SlSyncObj_t                SyncObj;
00063     _SlLockObj_t                LockObj;
00064 }_SlInternalSpawnCB_t;
00065 
00066 _SlInternalSpawnCB_t g_SlInternalSpawnCB;
00067 
00068 
00069 void _SlInternalSpawnTaskEntry() 
00070 {
00071     _i16                         i;
00072     _SlInternalSpawnEntry_t*    pEntry;
00073     _u8                         LastEntry;
00074 
00075     /* create and lock the locking object. lock in order to avoid race condition 
00076         on the first creation */
00077     sl_LockObjCreate(&g_SlInternalSpawnCB.LockObj,"SlSpawnProtect");
00078     sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_NO_WAIT);
00079 
00080     /* create and clear the sync object */
00081     sl_SyncObjCreate(&g_SlInternalSpawnCB.SyncObj,"SlSpawnSync");
00082     sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_NO_WAIT);
00083 
00084     g_SlInternalSpawnCB.pFree = &g_SlInternalSpawnCB.SpawnEntries[0];
00085     g_SlInternalSpawnCB.pWaitForExe = NULL;
00086     g_SlInternalSpawnCB.pLastInWaitList = NULL;
00087 
00088     /* create the link list between the entries */
00089     for (i=0 ; i<_SL_MAX_INTERNAL_SPAWN_ENTRIES - 1 ; i++)
00090     {
00091         g_SlInternalSpawnCB.SpawnEntries[i].pNext = &g_SlInternalSpawnCB.SpawnEntries[i+1];
00092         g_SlInternalSpawnCB.SpawnEntries[i].pEntry = NULL;
00093     }
00094     g_SlInternalSpawnCB.SpawnEntries[i].pNext = NULL;
00095 
00096     sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
00097 
00098 
00099     /* here we ready to execute entries */
00100 
00101     while (TRUE)
00102     {
00103         sl_SyncObjWait(&g_SlInternalSpawnCB.SyncObj,SL_OS_WAIT_FOREVER);
00104         /* go over all entries that already waiting for execution */
00105         LastEntry = FALSE;
00106         do
00107         {
00108             /* get entry to execute */
00109             sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER);
00110 
00111             pEntry = g_SlInternalSpawnCB.pWaitForExe;
00112             if ( NULL == pEntry )
00113             {
00114                sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
00115                break;
00116             }
00117             g_SlInternalSpawnCB.pWaitForExe = pEntry->pNext;
00118             if (pEntry == g_SlInternalSpawnCB.pLastInWaitList)
00119             {
00120                 g_SlInternalSpawnCB.pLastInWaitList = NULL;
00121                 LastEntry = TRUE;
00122             }
00123 
00124             sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
00125 
00126 
00127             /* pEntry could be null in case that the sync was already set by some
00128                of the entries during execution of earlier entry */
00129             if (NULL != pEntry)
00130             {
00131                 pEntry->pEntry(pEntry->pValue);
00132                 /* free the entry */
00133                 sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER);
00134 
00135                 pEntry->pNext = g_SlInternalSpawnCB.pFree;
00136                 g_SlInternalSpawnCB.pFree = pEntry;
00137 
00138 
00139                 if (NULL != g_SlInternalSpawnCB.pWaitForExe)
00140                 {
00141                     /* new entry received meanwhile */
00142                     LastEntry = FALSE;
00143                 }
00144 
00145                 sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
00146 
00147             }
00148 
00149         }while (!LastEntry);
00150     }
00151 }
00152 
00153 
00154 _i16 _SlInternalSpawn(_SlSpawnEntryFunc_t pEntry , void* pValue , _u32 flags)
00155 {
00156     _i16                         Res = 0;
00157     _SlInternalSpawnEntry_t*    pSpawnEntry;
00158 
00159     if (NULL == pEntry)
00160     {
00161         Res = -1;
00162     }
00163     else
00164     {
00165         sl_LockObjLock(&g_SlInternalSpawnCB.LockObj,SL_OS_WAIT_FOREVER);
00166 
00167         pSpawnEntry = g_SlInternalSpawnCB.pFree;
00168         g_SlInternalSpawnCB.pFree = pSpawnEntry->pNext;
00169 
00170         pSpawnEntry->pEntry = pEntry;
00171         pSpawnEntry->pValue = pValue;
00172         pSpawnEntry->pNext = NULL;
00173 
00174         if (NULL == g_SlInternalSpawnCB.pWaitForExe)
00175         {
00176             g_SlInternalSpawnCB.pWaitForExe = pSpawnEntry;
00177             g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
00178         }
00179         else
00180         {
00181             g_SlInternalSpawnCB.pLastInWaitList->pNext = pSpawnEntry;
00182             g_SlInternalSpawnCB.pLastInWaitList = pSpawnEntry;
00183         }
00184 
00185         sl_LockObjUnlock(&g_SlInternalSpawnCB.LockObj);
00186         /* this sync is called after releasing the lock object to avoid unnecessary context switches */
00187         sl_SyncObjSignal(&g_SlInternalSpawnCB.SyncObj);
00188     }
00189 
00190     return Res;
00191 }
00192 
00193 
00194 
00195 
00196 
00197 #endif
00198