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_is_init(false) 46 { 47 48 } 49 50 OcsdGenElemStack::~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 60 ocsd_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 83 ocsd_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 91 ocsd_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 108 void 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 120 ocsd_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 139 ocsd_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 181 void OcsdGenElemStack::copyPersistentData(int src, int dst) 182 { 183 m_pElemArray[dst].pElem->copyPersistentData(*(m_pElemArray[src].pElem)); 184 } 185 186 const 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