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