David Fletcher
/
cc3100_test
TI's CC3100 host driver and demo. Experimental and a work in progress.
Embed:
(wiki syntax)
Show/hide line numbers
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
Generated on Tue Jul 12 2022 22:55:20 by 1.7.2