X-Git-Url: https://gerrit.o-ran-sc.org/r/gitweb?p=o-du%2Fphy.git;a=blobdiff_plain;f=fhi_lib%2Fapp%2Fsrc%2Fapp_bbu_pool.c;fp=fhi_lib%2Fapp%2Fsrc%2Fapp_bbu_pool.c;h=fd897c04fac283ef4f53997f86e1c6bb135d9d4a;hp=0000000000000000000000000000000000000000;hb=892daba4c616407f16506415d5a69549519ef11d;hpb=76b4495d593ccf45d712db1a3ec96fa9d2d8f5f5 diff --git a/fhi_lib/app/src/app_bbu_pool.c b/fhi_lib/app/src/app_bbu_pool.c new file mode 100644 index 0000000..fd897c0 --- /dev/null +++ b/fhi_lib/app/src/app_bbu_pool.c @@ -0,0 +1,625 @@ +/****************************************************************************** +* +* Copyright (c) 2020 Intel. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +* +*******************************************************************************/ + +/** + * @brief This module provides implementation of BBU tasks for sample app + * @file app_bbu.c + * @ingroup xran + * @author Intel Corporation + * + **/ + +#include +#include +#include +#include +#include +#include +#include + +#include "app_bbu_pool.h" + +/** + * @file gnb_main_ebbu_pool.c + * @brief example pipeline code to use Enhanced BBUPool Framework +*/ + +extern int32_t gQueueCtxNum; +extern int32_t nSplitNumCell[EBBU_POOL_MAX_TEST_CELL]; + +int32_t test_func_A(void *pCookies); +int32_t test_func_B(void *pCookies); +int32_t test_func_C(void *pCookies); + +void test_pre_func_A(uint32_t nSubframe, uint16_t nCellIdx, TaskPreGen *pPara); +void test_pre_func_B(uint32_t nSubframe, uint16_t nCellIdx, TaskPreGen *pPara); + +int32_t test_func_gen(eBbuPoolHandler pHandler, int32_t nCell, int32_t nSlot, int32_t eventId); + +int32_t simulate_traffic(void *pCookies, int32_t testCount); + +typedef enum +{ + CAT_A = 0, //directly execute + CAT_B, //highest priority + CAT_C, //first priority + CAT_D, //second priority + CAT_E, //third priority + CAT_F, //forth priority + CAT_G, //fifth priority + CAT_H, //sixth priority + CAT_I, //seventh priority + CAT_NUM +} EventCatEnum; + +static int32_t eventSendDic[CAT_NUM] = +{ + EBBUPOOL_PRIO_EXECUTE, + EBBUPOOL_PRIO_HIGHEST, + EBBUPOOL_PRIO_ONE, + EBBUPOOL_PRIO_TWO, + EBBUPOOL_PRIO_THREE, + EBBUPOOL_PRIO_FOUR, + EBBUPOOL_PRIO_FIVE, + EBBUPOOL_PRIO_SIX, + EBBUPOOL_PRIO_SEVEN +}; + +EventConfigStruct testEventTable[MAX_TASK_NUM_G_NB] = +{ + /* Event ID*/ /* Event Name*/ /* pri */ /* event function */ /* pre event function */ /* nExtEvent */ /*prefetch flag */ /*core mask type */ /* core affinity 0~63 */ /* core affinity 64~127 */ + { TTI_START, EVENT_NAME(TTI_START), CAT_B, test_func_A, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { SYM2_WAKE_UP, EVENT_NAME(SYM2_WAKE_UP), CAT_B, app_bbu_pool_task_sym2_wakeup, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { SYM6_WAKE_UP, EVENT_NAME(SYM6_WAKE_UP), CAT_B, app_bbu_pool_task_sym6_wakeup, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { SYM11_WAKE_UP, EVENT_NAME(SYM11_WAKE_UP), CAT_B, app_bbu_pool_task_sym11_wakeup, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { SYM13_WAKE_UP, EVENT_NAME(SYM13_WAKE_UP), CAT_B, app_bbu_pool_task_sym13_wakeup, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { PRACH_WAKE_UP, EVENT_NAME(PRACH_WAKE_UP), CAT_B, app_bbu_pool_task_prach_wakeup, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { SRS_WAKE_UP, EVENT_NAME(SRS_WAKE_UP), CAT_B, app_bbu_pool_task_srs_wakeup, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { DL_CONFIG, EVENT_NAME(DL_CONFIG), CAT_B, app_bbu_pool_task_dl_config,app_bbu_pool_pre_task_dl_cfg, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { DL_PDSCH_TB, EVENT_NAME(DL_PDSCH_TB), CAT_B, test_func_A, test_pre_func_B, 0, 0, 0, 0x000000ffffffffff, 0xfffffffffffffff}, + { DL_PDSCH_SCRM, EVENT_NAME(DL_PDSCH_SCRM), CAT_C, test_func_A, NULL, 0, 0, 0, 0x000000ffffffffff, 0xfffffffffffffff}, + { DL_PDSCH_SYM, EVENT_NAME(DL_PDSCH_SYM), CAT_C, test_func_B, test_pre_func_A, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { DL_PDSCH_RS, EVENT_NAME(DL_PDSCH_RS), CAT_C, test_func_A, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { DL_CTRL, EVENT_NAME(DL_CTRL), CAT_C, test_func_A, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_CONFIG, EVENT_NAME(UL_CONFIG), CAT_C, app_bbu_pool_task_ul_config,app_bbu_pool_pre_task_ul_cfg, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_IQ_DECOMP2, EVENT_NAME(UL_IQ_DECOMP2), CAT_D, test_func_A, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_IQ_DECOMP6, EVENT_NAME(UL_IQ_DECOMP6), CAT_D, test_func_A, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_IQ_DECOMP11, EVENT_NAME(UL_IQ_DECOMP11), CAT_D, test_func_A, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_IQ_DECOMP13, EVENT_NAME(UL_IQ_DECOMP13), CAT_D, test_func_A, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_PUSCH_CE0, EVENT_NAME(UL_PUSCH_CE0), CAT_D, test_func_B, test_pre_func_A, 0, 0, 0, 0x000000ffffffffff, 0xfffffffffffffff}, + { UL_PUSCH_CE7, EVENT_NAME(UL_PUSCH_CE7), CAT_D, test_func_B, test_pre_func_A, 0, 0, 0, 0x000000ffffffffff, 0xfffffffffffffff}, + { UL_PUSCH_EQL0, EVENT_NAME(UL_PUSCH_EQL0), CAT_D, test_func_B, test_pre_func_A, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_PUSCH_EQL7, EVENT_NAME(UL_PUSCH_EQL7), CAT_D, test_func_B, test_pre_func_A, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_PUSCH_LLR, EVENT_NAME(UL_PUSCH_LLR), CAT_C, test_func_A, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_PUSCH_DEC, EVENT_NAME(UL_PUSCH_DEC), CAT_C, test_func_A, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_PUSCH_TB, EVENT_NAME(UL_PUSCH_TB), CAT_C, test_func_A, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_PUCCH, EVENT_NAME(UL_PUCCH), CAT_E, test_func_A, test_pre_func_A, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_PRACH, EVENT_NAME(UL_PRACH), CAT_E, test_func_A, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_SRS_DECOMP, EVENT_NAME(UL_SRS_DECOMP), CAT_E, test_func_A, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_SRS_CE, EVENT_NAME(UL_SRS_CE), CAT_E, test_func_B, test_pre_func_B, 0, 0, 0, 0x000000ffffffffff, 0xfffffffffffffff}, + { UL_SRS_POST, EVENT_NAME(UL_SRS_POST), CAT_E, test_func_A, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { DL_POST, EVENT_NAME(DL_POST), CAT_B, app_bbu_pool_task_dl_post, app_bbu_pool_pre_task_dl_post, 0, 1, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_POST, EVENT_NAME(UL_POST), CAT_A, test_func_C, NULL, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { DL_BEAM_GEN, EVENT_NAME(DL_BEAM_GEN), CAT_D, test_func_B, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { DL_BEAM_TX, EVENT_NAME(DL_BEAM_TX), CAT_D, test_func_A, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_BEAM_GEN, EVENT_NAME(UL_BEAM_GEN), CAT_D, test_func_B, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, + { UL_BEAM_TX, EVENT_NAME(UL_BEAM_TX), CAT_D, test_func_A, test_pre_func_B, 0, 0, 0, 0x00ffffffffffffff, 0xfffffffffffffff}, +}; + +int32_t gNBNextTaskMap[MAX_TASK_NUM_G_NB][MAX_NEXT_TASK_NUM] = +{ + // TTI_START + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // SYM2_WAKE_UP + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // SYM6_WAKE_UP + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // SYM11_WAKE_UP + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // SYM13_WAKE_UP + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // PRACH_WAKE_UP + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // SRS_WAKE_UP + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // DL_CONFIG + {DL_PDSCH_TB, DL_CTRL, DL_PDSCH_RS, DL_BEAM_GEN, -1, -1, -1, -1}, + + // DL_PDSCH_TB + {DL_PDSCH_SCRM, -1, -1, -1, -1, -1, -1, -1}, + + // DL_PDSCH_SCRM + {DL_PDSCH_SYM, -1, -1, -1, -1, -1, -1, -1}, + + // DL_PDSCH_SYM + {DL_POST, -1, -1, -1, -1, -1, -1, -1}, + + // DL_PDSCH_RS + {DL_PDSCH_SYM, -1, -1, -1, -1, -1, -1, -1}, + + // DL_CTRL + {DL_POST, -1, -1, -1, -1, -1, -1, -1}, + + // UL_CONFIG + {UL_IQ_DECOMP2, UL_IQ_DECOMP6, UL_IQ_DECOMP11, UL_IQ_DECOMP13, UL_PUCCH, UL_PRACH, UL_SRS_DECOMP, UL_BEAM_GEN}, + + // UL_IQ_DECOMP2 + {UL_PUSCH_CE0, UL_PUSCH_CE7, -1, -1, -1, -1, -1, -1}, + + // UL_IQ_DECOMP6 + {UL_PUSCH_EQL0, UL_PUSCH_EQL7, -1, -1, -1, -1, -1, -1}, + + // UL_IQ_DECOMP11 + {UL_PUSCH_CE7, -1, -1, -1, -1, -1, -1, -1}, + + // UL_IQ_DECOMP13 + {UL_PUSCH_EQL7, UL_PUCCH, UL_SRS_DECOMP, -1, -1, -1, -1, -1}, + + // UL_PUSCH_CE0 + {UL_PUSCH_EQL0, UL_PUSCH_EQL7, -1, -1, -1, -1, -1, -1}, + + // UL_PUSCH_CE7 + {UL_PUSCH_EQL7, -1, -1, -1, -1, -1, -1, -1}, + + // UL_PUSCH_EQL0 + {UL_PUSCH_LLR, -1, -1, -1, -1, -1, -1, -1}, + + // UL_PUSCH_EQL7 + {UL_PUSCH_LLR, -1, -1, -1, -1, -1, -1, -1}, + + // UL_PUSCH_LLR + {UL_PUSCH_DEC, -1, -1, -1, -1, -1, -1, -1}, + + // UL_PUSCH_DEC + {UL_PUSCH_TB, -1, -1, -1, -1, -1, -1, -1}, + + // UL_PUSCH_TB + {UL_POST, -1, -1, -1, -1, -1, -1, -1}, + + // UL_PUCCH + {UL_POST, -1, -1, -1, -1, -1, -1, -1}, + + // UL_PRACH + {UL_POST, -1, -1, -1, -1, -1, -1, -1}, + + // UL_SRS_DECOMP + {UL_SRS_CE, -1, -1, -1, -1, -1, -1, -1}, + + // UL_SRS_CE + {UL_SRS_POST, -1, -1, -1, -1, -1, -1, -1}, + + // UL_SRS_POST + {UL_POST, -1, -1, -1, -1, -1, -1, -1}, + + // DL_POST + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // UL_POST + {-1, -1, -1, -1, -1, -1, -1, -1}, + + // DL_BEAM_GEN + {DL_BEAM_TX, -1, -1, -1, -1, -1, -1, -1}, + + // DL_BEAM_TX + {DL_POST, -1, -1, -1, -1, -1, -1, -1}, + + // UL_BEAM_GEN + {UL_BEAM_TX, -1, -1, -1, -1, -1, -1, -1}, + + // UL_BEAM_TX + {UL_POST, -1, -1, -1, -1, -1, -1, -1}, +}; + +__attribute__((aligned(IA_ALIGN))) EventCtrlStruct gEventCtrl[EBBU_POOL_MAX_TEST_CELL][MAX_TEST_CTX][MAX_TASK_NUM_G_NB][MAX_TEST_SPLIT_NUM]; +static __attribute__((aligned(IA_ALIGN))) EventStruct gEvent[EBBU_POOL_MAX_TEST_CELL][MAX_TEST_CTX][MAX_TASK_NUM_G_NB][MAX_TEST_SPLIT_NUM]; +__attribute__((aligned(IA_ALIGN))) EventChainDescStruct gEventChain[EBBU_POOL_MAX_TEST_CELL][MAX_TEST_CTX]; +static SampleSplitStruct gsSampleSplit[EBBU_POOL_MAX_TEST_CELL][MAX_TEST_CTX][MAX_TEST_SPLIT_NUM]; + +static uint64_t dl_start_mlog[EBBU_POOL_MAX_TEST_CELL][MAX_TEST_CTX]; +static uint64_t ul_start_mlog[EBBU_POOL_MAX_TEST_CELL][MAX_TEST_CTX]; +extern volatile uint64_t ttistart; +extern int32_t dl_ul_count, dl_count, ul_count; +int32_t test_buffer_create() +{ + int32_t iCell, iCtx, iTask, iSplit; + for(iCell = 0; iCell < EBBU_POOL_MAX_TEST_CELL; iCell ++) + for(iCtx = 0; iCtx < MAX_TEST_CTX; iCtx ++) + for(iTask = 0; iTask < MAX_TASK_NUM_G_NB; iTask ++) + for(iSplit = 0; iSplit < MAX_TEST_SPLIT_NUM; iSplit ++) + gEventCtrl[iCell][iCtx][iTask][iSplit].dummy0 = (float *)_mm_malloc(sizeof(float), IA_ALIGN); + return 0; +} + +int32_t event_chain_gen(EventChainDescStruct *psEventChain) +{ + /*Construct the next event chain by copying existing array */ + psEventChain->eventChainDepth = MAX_TASK_NUM_G_NB; + memcpy((void *)psEventChain->nextEventChain, (void *)gNBNextTaskMap, sizeof(gNBNextTaskMap)); + //printf("\nCopy gNBNextTaskMap with size %d", sizeof(gNBNextTaskMap)); + memset((void *)&psEventChain->nextEventCount, 0 , sizeof(psEventChain->nextEventCount)); + memset((void *)&psEventChain->preEventCount, 0 , sizeof(psEventChain->preEventCount)); + memset((void *)&psEventChain->preEventStat, 0 , sizeof(psEventChain->preEventStat)); + + /*For each event, find all preceding dependent event */ + int32_t iEvent = 0; + int32_t iNext = 0; + + /* Set the external event Wakeup Dependencies (apart from Task Dependency) */ + for(iEvent = 0; iEvent < MAX_TASK_NUM_G_NB; iEvent++) + { + psEventChain->preEventCountSave[iEvent] = testEventTable[iEvent].nWakeOnExtrernalEvent; + } + + for(iEvent = 0; iEvent < MAX_TASK_NUM_G_NB; iEvent ++) + { + for(iNext = 0; iNext < MAX_NEXT_TASK_NUM; iNext ++) + { + if(psEventChain->nextEventChain[iEvent][iNext] != -1) + { + psEventChain->preEventCountSave[psEventChain->nextEventChain[iEvent][iNext]] ++; + psEventChain->nextEventCount[iEvent] ++; + } + } + } + + /* + for(iEvent = 0; iEvent < MAX_TASK_NUM_G_NB; iEvent ++) + { + printf("\nEvent %d preEvent %d",iEvent,psEventChain->preEventCount[iEvent]); + } + */ + return 0; +} + +int32_t event_chain_reset(EventChainDescStruct *psEventChain) +{ + memset((void *)&psEventChain->preEventStat, 0 , sizeof(psEventChain->preEventStat)); + + /*For each event, find all preceding dependent event */ + int32_t iEvent = 0; + + /* Set the external event Wakeup Dependencies (apart from Task Dependency) */ + for(iEvent = 0; iEvent < MAX_TASK_NUM_G_NB; iEvent++) + { + psEventChain->preEventCount[iEvent] = psEventChain->preEventCountSave[iEvent]; + } + return 0; +} + +static void set_event_info(EventCtrlStruct *pEvenCtrl, int32_t eventId, + int32_t iSplit, EventSendStruct *psEventSend) +{ + int32_t nCell = pEvenCtrl->nCellIdx; + int32_t nSlot = pEvenCtrl->nSlotIdx; + int32_t nCtx = nSlot % MAX_TEST_CTX; + int32_t nQueueCtxNum = nSlot % gQueueCtxNum; + EventStruct * pEvent = &gEvent[nCell][nCtx][eventId][iSplit]; + pEvent->pEventFunc = testEventTable[eventId].pEventFunc; + pEvent->pEventArgs = pEvenCtrl; + pEvent->nEventId = eventId; + pEvent->nEventSentTime = ebbu_pool_tick(); + pEvent->nEventSentTimeMlog = MLogTick(); + pEvent->nEventAliveTime = 10000000; + pEvent->nCoreAffinityMask = _mm256_set_epi64x(0,0,testEventTable[eventId].nCoreMask1,testEventTable[eventId].nCoreMask0); + pEvent->nEventStatus = EBBUPOOL_EVENT_VALID; + + psEventSend->eDisposFlag = EBBUPOOL_NON_DISPOSABLE; + + psEventSend->ePrioCat = eventSendDic[testEventTable[eventId].nEventPrio]; + psEventSend->nQueueCtx = 0; + if(gQueueCtxNum > 1) + psEventSend->nQueueCtx = nQueueCtxNum; + + psEventSend->psEventStruct[0] = pEvent; + psEventSend->nEventNum = 1; + + psEventSend->nPreFlag = testEventTable[eventId].nPrefetchFlag; + + return; +} + +static void set_split_event_info(EventCtrlStruct *pEvenCtrl, int32_t eventId, + int32_t nSplit, EventSendStruct *psEventSend) +{ + int32_t nCell = pEvenCtrl[0].nCellIdx; + int32_t nSlot = pEvenCtrl[0].nSlotIdx; + int32_t nCtx = nSlot % MAX_TEST_CTX; + int32_t nQueueCtxNum = nSlot % gQueueCtxNum; + int32_t iSplit = 0; + for(; iSplit < nSplit; iSplit ++) + { + EventStruct *pEvent = &gEvent[nCell][nCtx][eventId][iSplit]; + pEvent->pEventFunc = testEventTable[eventId].pEventFunc; + pEvent->pEventArgs = &pEvenCtrl[iSplit]; + pEvent->nEventId = eventId; + pEvent->nEventSentTime = ebbu_pool_tick(); + pEvent->nEventSentTimeMlog = MLogTick(); + pEvent->nEventAliveTime = 10000000; + pEvent->nCoreAffinityMask = _mm256_set_epi64x(0,0,testEventTable[eventId].nCoreMask1,testEventTable[eventId].nCoreMask0); + pEvent->nEventStatus = EBBUPOOL_EVENT_VALID; + psEventSend->psEventStruct[iSplit] = pEvent; + } + pEvenCtrl[0].tSendTime = MLogTick(); + psEventSend->eDisposFlag = EBBUPOOL_DISPOSABLE; + psEventSend->ePrioCat = eventSendDic[testEventTable[eventId].nEventPrio]; + psEventSend->nQueueCtx = 0; + if(gQueueCtxNum > 1) + psEventSend->nQueueCtx = nQueueCtxNum; + psEventSend->nEventNum = nSplit; + psEventSend->nPreFlag = testEventTable[eventId].nPrefetchFlag; + + return; +} + +int32_t next_event_unlock(void *pCookies) +{ + EventCtrlStruct *pEvenCtrl = (EventCtrlStruct *)pCookies; + eBbuPoolHandler pHandler = (eBbuPoolHandler)pEvenCtrl->pHandler; + int32_t nCell = pEvenCtrl->nCellIdx; + int32_t nSlot = pEvenCtrl->nSlotIdx; + int32_t nCtx = nSlot % MAX_TEST_CTX; + int32_t eventId = pEvenCtrl->nEventId; + EventChainDescStruct * pEventChain = &gEventChain[nCell][nCtx]; + + if(eventId == DL_POST||eventId == UL_POST) + ebbu_pool_queue_ctx_add(pHandler, nCtx); + + /*Set and check the status of all next event */ + /*Then decide whether to send next event or not */ + int32_t iNext = 0; + int32_t nextEventId = 0; + + for(iNext = 0; iNext < pEventChain->nextEventCount[eventId]; iNext++) + { + nextEventId = pEventChain->nextEventChain[eventId][iNext]; + /*printf("\nnSlot %d event %d nextEventCount %d inext %d next %d next_pre_count %d next_pre_stat %d", + nSlotIdx, nTaskId, pEventChain->nextEventCount[nTaskId], iNext, nextEventId, + pEventChain->preEventCount[nextEventId], pEventChain->preEventStat[nextEventId]); + */ + + if(__atomic_add_fetch(&pEventChain->preEventStat[nextEventId], 1, __ATOMIC_ACQ_REL) == + __atomic_load_n(&pEventChain->preEventCount[nextEventId], __ATOMIC_ACQUIRE)) + { + test_func_gen(pHandler, nCell, nSlot, nextEventId); + } + } + + return 0; +} + +int32_t test_func_gen(eBbuPoolHandler pHandler, int32_t nCell, int32_t nSlot, int32_t eventId) +{ + int j; + if(eventId >= MAX_TASK_NUM_G_NB || nCell >= EBBU_POOL_MAX_TEST_CELL) + { + printf("\nError! Wrong eventId %d max %d nCell %d",eventId, MAX_TASK_NUM_G_NB, nCell); + exit(-1); + } + + int32_t nCtx = nSlot % MAX_TEST_CTX; + int32_t iNext, iNextEventId, nSplitIdx; + EventChainDescStruct * pEventChain = &gEventChain[nCell][nCtx]; + EventSendStruct sEventSend; + EventCtrlStruct *pEventCtrl; + TaskPreGen sPara; + int32_t nSplit = 1, ret = 0; + + uint64_t t1 = MLogTick(); + + if(DL_CONFIG == eventId) + dl_start_mlog[nCell][nCtx] = t1; + else if(UL_CONFIG == eventId) + ul_start_mlog[nCell][nCtx] = t1; + + // Klocwork check + for (j = 0; j < MAX_TEST_SPLIT_NUM; j++) + sPara.pTaskExePara[j] = (void *)&gsSampleSplit[nCell%EBBU_POOL_MAX_TEST_CELL][nSlot%MAX_TEST_CTX][j]; + + if (testEventTable[eventId].pPreEventFunc) + { + /* Run Pre Event and Find out how many split */ + sPara.nTaskNum = 1; + testEventTable[eventId].pPreEventFunc(nSlot, nCell, &sPara); + nSplit = sPara.nTaskNum; + if(nSplit > 1) + { + /* Add the split to all the Nex Next Dependencies */ + for(iNext = 0; iNext < pEventChain->nextEventCount[eventId]; iNext++) + { + iNextEventId = pEventChain->nextEventChain[eventId][iNext]; + __atomic_add_fetch(&pEventChain->preEventCount[iNextEventId], nSplit - 1, __ATOMIC_ACQ_REL); + } + } + } + + //send the splitted events together, save ebbupool internal overhead + for(nSplitIdx = 0; nSplitIdx < nSplit; nSplitIdx++) + { + pEventCtrl = &gEventCtrl[nCell][nCtx][eventId][nSplitIdx]; + pEventCtrl->nEventId = eventId; + pEventCtrl->nSplitIdx = nSplitIdx; + pEventCtrl->nCellIdx = nCell; + pEventCtrl->nSlotIdx = nSlot; + pEventCtrl->pTaskPara = sPara.pTaskExePara[nSplitIdx]; + pEventCtrl->pHandler = pHandler; + } + + set_split_event_info(&gEventCtrl[nCell][nCtx][eventId][0], eventId, nSplit, &sEventSend); + ret = ebbu_pool_send_event(pHandler, sEventSend); + + if(0 != ret) + printf("\nEvent %d gen failed!",eventId); + + MLogTask(MAX_TASK_NUM_G_NB * nCell + eventId + 2000, t1, MLogTick()); + + return 0; +} +void test_pre_func_A(uint32_t nSubframe, uint16_t nCellIdx, TaskPreGen *pPara) +{ + // uint64_t t1 = MLogTick(); + //printf("\nfunc pre A event %d",pEvenCtrl->nEventId); + // int32_t ret = 0; + //do some traffic + //ret = simulate_traffic(pCookies, 1000); + + pPara->nTaskNum = nSplitNumCell[nCellIdx]; + int32_t iSplit = 0; + for(iSplit = 0; iSplit < pPara->nTaskNum; iSplit ++) + { + pPara->pTaskExePara[iSplit] = (void *)&gsSampleSplit[nCellIdx%EBBU_POOL_MAX_TEST_CELL][nSubframe%MAX_TEST_CTX][iSplit]; + } + return; + //MLogTask(MAX_TASK_NUM_G_NB * pInputPara->nCellIdx + pEvenCtrl->nEventId, t1, MLogTick()); +} + + +void test_pre_func_B(uint32_t nSubframe, uint16_t nCellIdx, TaskPreGen *pPara) +{ + // uint64_t t1 = MLogTick(); + //printf("\nfunc pre A event %d",pEvenCtrl->nEventId); + // int32_t ret = 0; + + //do some traffic + //ret = simulate_traffic(pCookies, 1000); + int32_t iSplit = 0; + for(iSplit = 0; iSplit < pPara->nTaskNum; iSplit ++) + { + pPara->pTaskExePara[iSplit] = (void *)&gsSampleSplit[nCellIdx%EBBU_POOL_MAX_TEST_CELL][nSubframe%MAX_TEST_CTX][iSplit]; + } + return; + + pPara->nTaskNum = nSplitNumCell[nCellIdx]; + + //MLogTask(MAX_TASK_NUM_G_NB * pInputPara->nCellIdx + pEvenCtrl->nEventId, t1, MLogTick()); +} + +int32_t test_func_A(void *pCookies) +{ + EventCtrlStruct *pEvenCtrl = (EventCtrlStruct *)pCookies; + + uint64_t t1 = MLogTick(); +#if 0 + //printf("\nfunc A event %d",pEvenCtrl->nEventId); + if(DL_CONFIG == pEvenCtrl->nEventId) + { + app_bbu_pool_task_dl_config(pCookies); + MLogTask(pEvenCtrl->nCellIdx + 4000, pEvenCtrl->tSendTime, t1); + } + + if(UL_CONFIG == pEvenCtrl->nEventId) + { + app_bbu_pool_task_ul_config(pCookies); + MLogTask(pEvenCtrl->nCellIdx + 5000, pEvenCtrl->tSendTime, t1); + } +#endif + // int32_t ret = 0; + + //do some traffic + //ret = simulate_traffic(pCookies, 3000); + //usleep(10); + + //unlock the next task + next_event_unlock(pCookies); + + MLogTask(MAX_TASK_NUM_G_NB * pEvenCtrl->nCellIdx + pEvenCtrl->nEventId, t1, MLogTick()); + //printf("\nfunc a latency %llu",MLogTick()-t1); + + return 0; + +} + +int32_t test_func_B(void *pCookies) +{ + EventCtrlStruct *pEvenCtrl = (EventCtrlStruct *)pCookies; + + uint64_t t1 = MLogTick(); + //printf("\nfunc B event %d",pEvenCtrl->nEventId); + // int32_t ret = 0; + + //do some traffic + //ret = simulate_traffic(pCookies, 5000); + //usleep(10); + + //unlock the next task + next_event_unlock(pCookies); + + MLogTask(MAX_TASK_NUM_G_NB * pEvenCtrl->nCellIdx + pEvenCtrl->nEventId, t1, MLogTick()); + + return 0; +} + +int32_t test_func_C(void *pCookies) +{ + EventCtrlStruct *pEvenCtrl = (EventCtrlStruct *)pCookies; + + uint64_t t1 = MLogTick(); + //printf("\nfunc B event %d",pEvenCtrl->nEventId); + int32_t ret = 0; + + //do some traffic + + MLogTask(MAX_TASK_NUM_G_NB * pEvenCtrl->nCellIdx + pEvenCtrl->nEventId, t1, MLogTick()); + + if(pEvenCtrl->nEventId == DL_POST || pEvenCtrl->nEventId == UL_POST) + { + if(__atomic_sub_fetch(&dl_ul_count, 1, __ATOMIC_ACQ_REL) == 0) + { + MLogTask(MAX_TASK_NUM_G_NB * pEvenCtrl->nCellIdx + 6000, ttistart, MLogTick()); + } + } + + MLogTask(77777, t1, MLogTick()); + return ret; +} + +#if 0 +int32_t simulate_traffic(void *pCookies, int32_t testCount) +{ + //printf("\ndo traffic!"); + EventCtrlStruct *pEvenCtrl = (EventCtrlStruct *)pCookies; + __m256 sigma2 = _mm256_set1_ps(testCount/1234.5); + __m256 ftemp1, ftemp2; + + int32_t m = testCount; + m = m/2; + + while(m > 0) + { + ftemp1 = _mm256_rcp_ps(sigma2); + ftemp2 = _mm256_sub_ps(_mm256_set1_ps(0), sigma2); + ftemp2 = _mm256_fmadd_ps(ftemp1, sigma2, ftemp2); + sigma2 = _mm256_rcp_ps(ftemp2); + m --; + } + + int32_t nfloat = 8; //256bits has eight 32bits + float *dummy = (float *)&sigma2; + *pEvenCtrl->dummy0 = 0; + for(m = 0; m < nfloat; m++) + *pEvenCtrl->dummy0 += dummy[m]; + + return 0; +} +#endif