/****************************************************************************** * * 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