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 38 OcsdGenElemStack::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_sendIf(NULL), 46 m_is_init(false) 47 { 48 49 } 50 51 OcsdGenElemStack::~OcsdGenElemStack() 52 { 53 for (int i = 0; i<m_elemArraySize; i++) 54 { 55 delete m_pElemArray[i].pElem; 56 } 57 delete [] m_pElemArray; 58 m_pElemArray = 0; 59 } 60 61 ocsd_err_t OcsdGenElemStack::addElem(const ocsd_trc_index_t trc_pkt_idx) 62 { 63 ocsd_err_t err = OCSD_OK; 64 65 if (((m_curr_elem_idx + 1) == m_elemArraySize) || !m_pElemArray) 66 { 67 err = growArray(); 68 if (err) 69 return err; 70 } 71 72 // if there is a least one element then copy and increment 73 // otherwise we are at base of stack. 74 if (m_elem_to_send) 75 { 76 copyPersistentData(m_curr_elem_idx, m_curr_elem_idx + 1); 77 m_curr_elem_idx++; 78 } 79 m_pElemArray[m_curr_elem_idx].trc_pkt_idx = trc_pkt_idx; 80 m_elem_to_send++; 81 return err; 82 } 83 84 ocsd_err_t OcsdGenElemStack::addElemType(const ocsd_trc_index_t trc_pkt_idx, ocsd_gen_trc_elem_t elem_type) 85 { 86 ocsd_err_t err = addElem(trc_pkt_idx); 87 if (!err) 88 getCurrElem().setType(elem_type); 89 return err; 90 } 91 92 ocsd_err_t OcsdGenElemStack::resetElemStack() 93 { 94 ocsd_err_t err = OCSD_OK; 95 if (!m_pElemArray) 96 { 97 err = growArray(); 98 if (err) 99 return err; 100 } 101 102 if (!isInit()) 103 return OCSD_ERR_NOT_INIT; 104 105 resetIndexes(); 106 return err; 107 } 108 109 void OcsdGenElemStack::resetIndexes() 110 { 111 // last time there was more than one element on stack 112 if (m_curr_elem_idx > 0) 113 copyPersistentData(m_curr_elem_idx, 0); 114 115 // indexes to bottom of stack, nothing in use at present 116 m_curr_elem_idx = 0; 117 m_send_elem_idx = 0; 118 m_elem_to_send = 0; 119 } 120 121 ocsd_datapath_resp_t OcsdGenElemStack::sendElements() 122 { 123 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 124 if (!isInit()) 125 return OCSD_RESP_FATAL_NOT_INIT; 126 127 while (m_elem_to_send && OCSD_DATA_RESP_IS_CONT(resp)) 128 { 129 resp = m_sendIf->first()->TraceElemIn(m_pElemArray[m_send_elem_idx].trc_pkt_idx, m_CSID, *(m_pElemArray[m_send_elem_idx].pElem)); 130 m_send_elem_idx++; 131 m_elem_to_send--; 132 } 133 134 // clear the indexes if we are done. 135 if (!m_elem_to_send) 136 resetIndexes(); 137 return resp; 138 } 139 140 ocsd_err_t OcsdGenElemStack::growArray() 141 { 142 elemPtr_t *p_new_array = 0; 143 const int increment = 4; 144 145 p_new_array = new (std::nothrow) elemPtr_t[m_elemArraySize + increment]; 146 147 if (p_new_array != 0) 148 { 149 OcsdTraceElement *pElem = 0; 150 151 // fill the last increment elements with new objects 152 for (int i = 0; i < increment; i++) 153 { 154 pElem = new (std::nothrow) OcsdTraceElement(); 155 if (!pElem) 156 return OCSD_ERR_MEM; 157 pElem->init(); 158 p_new_array[m_elemArraySize + i].pElem = pElem; 159 } 160 161 // copy the existing objects from the old array to the start of the new one 162 if (m_elemArraySize > 0) 163 { 164 for (int i = 0; i < m_elemArraySize; i++) 165 { 166 p_new_array[i].pElem = m_pElemArray[i].pElem; 167 p_new_array[i].trc_pkt_idx = m_pElemArray[i].trc_pkt_idx; 168 } 169 } 170 171 // delete the old pointer array. 172 delete[] m_pElemArray; 173 m_elemArraySize += increment; 174 m_pElemArray = p_new_array; 175 } 176 else 177 return OCSD_ERR_MEM; 178 179 return OCSD_OK; 180 } 181 182 void OcsdGenElemStack::copyPersistentData(int src, int dst) 183 { 184 m_pElemArray[dst].pElem->copyPersistentData(*(m_pElemArray[src].pElem)); 185 } 186 187 const bool OcsdGenElemStack::isInit() 188 { 189 if (!m_is_init) { 190 if (m_elemArraySize && m_pElemArray && m_sendIf) 191 m_is_init = true; 192 } 193 return m_is_init; 194 } 195 196 197 /* End of File ocsd_gen_elem_stack.cpp */ 198