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