1*b6aadd18SAndrew Turner /* 2*b6aadd18SAndrew Turner * \file ocsd_gen_elem_stack.cpp 3*b6aadd18SAndrew Turner * \brief OpenCSD : List of Generic trace elements for output. 4*b6aadd18SAndrew Turner * 5*b6aadd18SAndrew Turner * \copyright Copyright (c) 2020, ARM Limited. All Rights Reserved. 6*b6aadd18SAndrew Turner */ 7*b6aadd18SAndrew Turner 8*b6aadd18SAndrew Turner 9*b6aadd18SAndrew Turner /* 10*b6aadd18SAndrew Turner * Redistribution and use in source and binary forms, with or without modification, 11*b6aadd18SAndrew Turner * are permitted provided that the following conditions are met: 12*b6aadd18SAndrew Turner * 13*b6aadd18SAndrew Turner * 1. Redistributions of source code must retain the above copyright notice, 14*b6aadd18SAndrew Turner * this list of conditions and the following disclaimer. 15*b6aadd18SAndrew Turner * 16*b6aadd18SAndrew Turner * 2. Redistributions in binary form must reproduce the above copyright notice, 17*b6aadd18SAndrew Turner * this list of conditions and the following disclaimer in the documentation 18*b6aadd18SAndrew Turner * and/or other materials provided with the distribution. 19*b6aadd18SAndrew Turner * 20*b6aadd18SAndrew Turner * 3. Neither the name of the copyright holder nor the names of its contributors 21*b6aadd18SAndrew Turner * may be used to endorse or promote products derived from this software without 22*b6aadd18SAndrew Turner * specific prior written permission. 23*b6aadd18SAndrew Turner * 24*b6aadd18SAndrew Turner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND 25*b6aadd18SAndrew Turner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 26*b6aadd18SAndrew Turner * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 27*b6aadd18SAndrew Turner * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 28*b6aadd18SAndrew Turner * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 29*b6aadd18SAndrew Turner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30*b6aadd18SAndrew Turner * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 31*b6aadd18SAndrew Turner * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 32*b6aadd18SAndrew Turner * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 33*b6aadd18SAndrew Turner * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34*b6aadd18SAndrew Turner */ 35*b6aadd18SAndrew Turner 36*b6aadd18SAndrew Turner #include "common/ocsd_gen_elem_stack.h" 37*b6aadd18SAndrew Turner 38*b6aadd18SAndrew Turner OcsdGenElemStack::OcsdGenElemStack() : 39*b6aadd18SAndrew Turner m_pElemArray(0), 40*b6aadd18SAndrew Turner m_elemArraySize(0), 41*b6aadd18SAndrew Turner m_elem_to_send(0), 42*b6aadd18SAndrew Turner m_curr_elem_idx(0), 43*b6aadd18SAndrew Turner m_send_elem_idx(0), 44*b6aadd18SAndrew Turner m_CSID(0), 45*b6aadd18SAndrew Turner m_is_init(false) 46*b6aadd18SAndrew Turner { 47*b6aadd18SAndrew Turner 48*b6aadd18SAndrew Turner } 49*b6aadd18SAndrew Turner 50*b6aadd18SAndrew Turner OcsdGenElemStack::~OcsdGenElemStack() 51*b6aadd18SAndrew Turner { 52*b6aadd18SAndrew Turner for (int i = 0; i<m_elemArraySize; i++) 53*b6aadd18SAndrew Turner { 54*b6aadd18SAndrew Turner delete m_pElemArray[i].pElem; 55*b6aadd18SAndrew Turner } 56*b6aadd18SAndrew Turner delete [] m_pElemArray; 57*b6aadd18SAndrew Turner m_pElemArray = 0; 58*b6aadd18SAndrew Turner } 59*b6aadd18SAndrew Turner 60*b6aadd18SAndrew Turner ocsd_err_t OcsdGenElemStack::addElem(const ocsd_trc_index_t trc_pkt_idx) 61*b6aadd18SAndrew Turner { 62*b6aadd18SAndrew Turner ocsd_err_t err = OCSD_OK; 63*b6aadd18SAndrew Turner 64*b6aadd18SAndrew Turner if (((m_curr_elem_idx + 1) == m_elemArraySize) || !m_pElemArray) 65*b6aadd18SAndrew Turner { 66*b6aadd18SAndrew Turner err = growArray(); 67*b6aadd18SAndrew Turner if (err) 68*b6aadd18SAndrew Turner return err; 69*b6aadd18SAndrew Turner } 70*b6aadd18SAndrew Turner 71*b6aadd18SAndrew Turner // if there is a least one element then copy and increment 72*b6aadd18SAndrew Turner // otherwise we are at base of stack. 73*b6aadd18SAndrew Turner if (m_elem_to_send) 74*b6aadd18SAndrew Turner { 75*b6aadd18SAndrew Turner copyPersistentData(m_curr_elem_idx, m_curr_elem_idx + 1); 76*b6aadd18SAndrew Turner m_curr_elem_idx++; 77*b6aadd18SAndrew Turner } 78*b6aadd18SAndrew Turner m_pElemArray[m_curr_elem_idx].trc_pkt_idx = trc_pkt_idx; 79*b6aadd18SAndrew Turner m_elem_to_send++; 80*b6aadd18SAndrew Turner return err; 81*b6aadd18SAndrew Turner } 82*b6aadd18SAndrew Turner 83*b6aadd18SAndrew Turner ocsd_err_t OcsdGenElemStack::addElemType(const ocsd_trc_index_t trc_pkt_idx, ocsd_gen_trc_elem_t elem_type) 84*b6aadd18SAndrew Turner { 85*b6aadd18SAndrew Turner ocsd_err_t err = addElem(trc_pkt_idx); 86*b6aadd18SAndrew Turner if (!err) 87*b6aadd18SAndrew Turner getCurrElem().setType(elem_type); 88*b6aadd18SAndrew Turner return err; 89*b6aadd18SAndrew Turner } 90*b6aadd18SAndrew Turner 91*b6aadd18SAndrew Turner ocsd_err_t OcsdGenElemStack::resetElemStack() 92*b6aadd18SAndrew Turner { 93*b6aadd18SAndrew Turner ocsd_err_t err = OCSD_OK; 94*b6aadd18SAndrew Turner if (!m_pElemArray) 95*b6aadd18SAndrew Turner { 96*b6aadd18SAndrew Turner err = growArray(); 97*b6aadd18SAndrew Turner if (err) 98*b6aadd18SAndrew Turner return err; 99*b6aadd18SAndrew Turner } 100*b6aadd18SAndrew Turner 101*b6aadd18SAndrew Turner if (!isInit()) 102*b6aadd18SAndrew Turner return OCSD_ERR_NOT_INIT; 103*b6aadd18SAndrew Turner 104*b6aadd18SAndrew Turner resetIndexes(); 105*b6aadd18SAndrew Turner return err; 106*b6aadd18SAndrew Turner } 107*b6aadd18SAndrew Turner 108*b6aadd18SAndrew Turner void OcsdGenElemStack::resetIndexes() 109*b6aadd18SAndrew Turner { 110*b6aadd18SAndrew Turner // last time there was more than one element on stack 111*b6aadd18SAndrew Turner if (m_curr_elem_idx > 0) 112*b6aadd18SAndrew Turner copyPersistentData(m_curr_elem_idx, 0); 113*b6aadd18SAndrew Turner 114*b6aadd18SAndrew Turner // indexes to bottom of stack, nothing in use at present 115*b6aadd18SAndrew Turner m_curr_elem_idx = 0; 116*b6aadd18SAndrew Turner m_send_elem_idx = 0; 117*b6aadd18SAndrew Turner m_elem_to_send = 0; 118*b6aadd18SAndrew Turner } 119*b6aadd18SAndrew Turner 120*b6aadd18SAndrew Turner ocsd_datapath_resp_t OcsdGenElemStack::sendElements() 121*b6aadd18SAndrew Turner { 122*b6aadd18SAndrew Turner ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 123*b6aadd18SAndrew Turner if (!isInit()) 124*b6aadd18SAndrew Turner return OCSD_RESP_FATAL_NOT_INIT; 125*b6aadd18SAndrew Turner 126*b6aadd18SAndrew Turner while (m_elem_to_send && OCSD_DATA_RESP_IS_CONT(resp)) 127*b6aadd18SAndrew Turner { 128*b6aadd18SAndrew Turner resp = m_sendIf->first()->TraceElemIn(m_pElemArray[m_send_elem_idx].trc_pkt_idx, m_CSID, *(m_pElemArray[m_send_elem_idx].pElem)); 129*b6aadd18SAndrew Turner m_send_elem_idx++; 130*b6aadd18SAndrew Turner m_elem_to_send--; 131*b6aadd18SAndrew Turner } 132*b6aadd18SAndrew Turner 133*b6aadd18SAndrew Turner // clear the indexes if we are done. 134*b6aadd18SAndrew Turner if (!m_elem_to_send) 135*b6aadd18SAndrew Turner resetIndexes(); 136*b6aadd18SAndrew Turner return resp; 137*b6aadd18SAndrew Turner } 138*b6aadd18SAndrew Turner 139*b6aadd18SAndrew Turner ocsd_err_t OcsdGenElemStack::growArray() 140*b6aadd18SAndrew Turner { 141*b6aadd18SAndrew Turner elemPtr_t *p_new_array = 0; 142*b6aadd18SAndrew Turner const int increment = 4; 143*b6aadd18SAndrew Turner 144*b6aadd18SAndrew Turner p_new_array = new (std::nothrow) elemPtr_t[m_elemArraySize + increment]; 145*b6aadd18SAndrew Turner 146*b6aadd18SAndrew Turner if (p_new_array != 0) 147*b6aadd18SAndrew Turner { 148*b6aadd18SAndrew Turner OcsdTraceElement *pElem = 0; 149*b6aadd18SAndrew Turner 150*b6aadd18SAndrew Turner // fill the last increment elements with new objects 151*b6aadd18SAndrew Turner for (int i = 0; i < increment; i++) 152*b6aadd18SAndrew Turner { 153*b6aadd18SAndrew Turner pElem = new (std::nothrow) OcsdTraceElement(); 154*b6aadd18SAndrew Turner if (!pElem) 155*b6aadd18SAndrew Turner return OCSD_ERR_MEM; 156*b6aadd18SAndrew Turner pElem->init(); 157*b6aadd18SAndrew Turner p_new_array[m_elemArraySize + i].pElem = pElem; 158*b6aadd18SAndrew Turner } 159*b6aadd18SAndrew Turner 160*b6aadd18SAndrew Turner // copy the existing objects from the old array to the start of the new one 161*b6aadd18SAndrew Turner if (m_elemArraySize > 0) 162*b6aadd18SAndrew Turner { 163*b6aadd18SAndrew Turner for (int i = 0; i < m_elemArraySize; i++) 164*b6aadd18SAndrew Turner { 165*b6aadd18SAndrew Turner p_new_array[i].pElem = m_pElemArray[i].pElem; 166*b6aadd18SAndrew Turner p_new_array[i].trc_pkt_idx = m_pElemArray[i].trc_pkt_idx; 167*b6aadd18SAndrew Turner } 168*b6aadd18SAndrew Turner } 169*b6aadd18SAndrew Turner 170*b6aadd18SAndrew Turner // delete the old pointer array. 171*b6aadd18SAndrew Turner delete[] m_pElemArray; 172*b6aadd18SAndrew Turner m_elemArraySize += increment; 173*b6aadd18SAndrew Turner m_pElemArray = p_new_array; 174*b6aadd18SAndrew Turner } 175*b6aadd18SAndrew Turner else 176*b6aadd18SAndrew Turner return OCSD_ERR_MEM; 177*b6aadd18SAndrew Turner 178*b6aadd18SAndrew Turner return OCSD_OK; 179*b6aadd18SAndrew Turner } 180*b6aadd18SAndrew Turner 181*b6aadd18SAndrew Turner void OcsdGenElemStack::copyPersistentData(int src, int dst) 182*b6aadd18SAndrew Turner { 183*b6aadd18SAndrew Turner m_pElemArray[dst].pElem->copyPersistentData(*(m_pElemArray[src].pElem)); 184*b6aadd18SAndrew Turner } 185*b6aadd18SAndrew Turner 186*b6aadd18SAndrew Turner const bool OcsdGenElemStack::isInit() 187*b6aadd18SAndrew Turner { 188*b6aadd18SAndrew Turner if (!m_is_init) { 189*b6aadd18SAndrew Turner if (m_elemArraySize && m_pElemArray && m_sendIf) 190*b6aadd18SAndrew Turner m_is_init = true; 191*b6aadd18SAndrew Turner } 192*b6aadd18SAndrew Turner return m_is_init; 193*b6aadd18SAndrew Turner } 194*b6aadd18SAndrew Turner 195*b6aadd18SAndrew Turner 196*b6aadd18SAndrew Turner /* End of File ocsd_gen_elem_stack.cpp */ 197