1 /* 2 * \file ocsd_gen_elem_list.cpp 3 * \brief OpenCSD : List of Generic trace elements for output. 4 * 5 * \copyright Copyright (c) 2016, 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_list.h" 37 38 OcsdGenElemList::OcsdGenElemList() 39 { 40 m_firstElemIdx=0; 41 m_numUsed=0; 42 m_numPend=0; 43 44 m_elemArraySize = 0; 45 m_sendIf = 0; 46 m_CSID = 0; 47 m_pElemArray = 0; 48 } 49 50 OcsdGenElemList::~OcsdGenElemList() 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 void OcsdGenElemList::reset() 61 { 62 m_firstElemIdx=0; 63 m_numUsed=0; 64 m_numPend=0; 65 } 66 67 OcsdTraceElement *OcsdGenElemList::getNextElem(const ocsd_trc_index_t trc_pkt_idx) 68 { 69 OcsdTraceElement *pElem = 0; 70 if(getNumElem() == m_elemArraySize) // all in use 71 growArray(); 72 73 if(m_pElemArray != 0) 74 { 75 m_numUsed++; 76 int idx = getAdjustedIdx(m_firstElemIdx + m_numUsed - 1); 77 pElem = m_pElemArray[idx].pElem; 78 m_pElemArray[idx].trc_pkt_idx = trc_pkt_idx; 79 } 80 return pElem; 81 } 82 83 const ocsd_gen_trc_elem_t OcsdGenElemList::getElemType(const int entryN) const 84 { 85 ocsd_gen_trc_elem_t elem_type = OCSD_GEN_TRC_ELEM_UNKNOWN; 86 if(entryN < getNumElem()) 87 { 88 int idx = getAdjustedIdx(m_firstElemIdx + entryN); 89 elem_type = m_pElemArray[idx].pElem->getType(); 90 } 91 return elem_type; 92 } 93 94 ocsd_datapath_resp_t OcsdGenElemList::sendElements() 95 { 96 ocsd_datapath_resp_t resp = OCSD_RESP_CONT; 97 98 if((m_elemArraySize == 0) || (m_sendIf == 0)) 99 return OCSD_RESP_FATAL_NOT_INIT; 100 101 if(!m_sendIf->hasAttachedAndEnabled()) 102 return OCSD_RESP_FATAL_NOT_INIT; 103 104 while(elemToSend() && OCSD_DATA_RESP_IS_CONT(resp)) 105 { 106 resp = m_sendIf->first()->TraceElemIn(m_pElemArray[m_firstElemIdx].trc_pkt_idx, m_CSID, *(m_pElemArray[m_firstElemIdx].pElem)); 107 m_firstElemIdx++; 108 if(m_firstElemIdx >= m_elemArraySize) 109 m_firstElemIdx = 0; 110 m_numUsed--; 111 } 112 return resp; 113 } 114 115 // this function will enlarge the array, and create extra element objects. 116 // existing objects will be moved to the front of the array 117 // called if all elements are in use. (sets indexes accordingly) 118 void OcsdGenElemList::growArray() 119 { 120 elemPtr_t *p_new_array = 0; 121 122 int increment; 123 if(m_elemArraySize == 0) 124 // starting from scratch... 125 increment = 8; 126 else 127 increment = m_elemArraySize / 2; // grow by 50% 128 129 130 p_new_array = new (std::nothrow) elemPtr_t[m_elemArraySize+increment]; 131 132 if(p_new_array != 0) 133 { 134 // fill the last increment elements with new objects 135 for(int i=0; i < increment; i++) 136 { 137 p_new_array[m_elemArraySize+i].pElem = new (std::nothrow) OcsdTraceElement(); 138 } 139 140 // copy the existing objects from the old array to the start of the new one 141 // and adjust the indices. 142 if(m_elemArraySize > 0) 143 { 144 int inIdx = m_firstElemIdx; 145 for(int i = 0; i < m_elemArraySize; i++) 146 { 147 p_new_array[i].pElem = m_pElemArray[inIdx].pElem; 148 p_new_array[i].trc_pkt_idx = m_pElemArray[inIdx].trc_pkt_idx; 149 inIdx++; 150 if(inIdx >= m_elemArraySize) 151 inIdx = 0; 152 } 153 } 154 155 // delete the old pointer array. 156 delete [] m_pElemArray; 157 m_elemArraySize += increment; 158 } 159 else 160 m_elemArraySize = 0; 161 162 // update the internal array pointers to the new array 163 if(m_firstElemIdx >= 0) 164 m_firstElemIdx = 0; 165 m_pElemArray = p_new_array; 166 } 167 168 /* End of File ocsd_gen_elem_list.cpp */ 169