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