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