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
OcsdGenElemStack()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
~OcsdGenElemStack()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
addElem(const ocsd_trc_index_t trc_pkt_idx)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
addElemType(const ocsd_trc_index_t trc_pkt_idx,ocsd_gen_trc_elem_t elem_type)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
resetElemStack()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
resetIndexes()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
sendElements()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
growArray()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
copyPersistentData(int src,int dst)182 void OcsdGenElemStack::copyPersistentData(int src, int dst)
183 {
184 m_pElemArray[dst].pElem->copyPersistentData(*(m_pElemArray[src].pElem));
185 }
186
isInit()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