summaryrefslogtreecommitdiffstats
path: root/decoder/source/ocsd_gen_elem_stack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'decoder/source/ocsd_gen_elem_stack.cpp')
-rw-r--r--decoder/source/ocsd_gen_elem_stack.cpp197
1 files changed, 197 insertions, 0 deletions
diff --git a/decoder/source/ocsd_gen_elem_stack.cpp b/decoder/source/ocsd_gen_elem_stack.cpp
new file mode 100644
index 0000000..66fe75d
--- /dev/null
+++ b/decoder/source/ocsd_gen_elem_stack.cpp
@@ -0,0 +1,197 @@
+/*
+* \file ocsd_gen_elem_stack.cpp
+* \brief OpenCSD : List of Generic trace elements for output.
+*
+* \copyright Copyright (c) 2020, ARM Limited. All Rights Reserved.
+*/
+
+
+/*
+* Redistribution and use in source and binary forms, with or without modification,
+* are permitted provided that the following conditions are met:
+*
+* 1. Redistributions of source code must retain the above copyright notice,
+* this list of conditions and the following disclaimer.
+*
+* 2. Redistributions in binary form must reproduce the above copyright notice,
+* this list of conditions and the following disclaimer in the documentation
+* and/or other materials provided with the distribution.
+*
+* 3. Neither the name of the copyright holder nor the names of its contributors
+* may be used to endorse or promote products derived from this software without
+* specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "common/ocsd_gen_elem_stack.h"
+
+OcsdGenElemStack::OcsdGenElemStack() :
+ m_pElemArray(0),
+ m_elemArraySize(0),
+ m_elem_to_send(0),
+ m_curr_elem_idx(0),
+ m_send_elem_idx(0),
+ m_CSID(0),
+ m_sendIf(NULL),
+ m_is_init(false)
+{
+
+}
+
+OcsdGenElemStack::~OcsdGenElemStack()
+{
+ for (int i = 0; i<m_elemArraySize; i++)
+ {
+ delete m_pElemArray[i].pElem;
+ }
+ delete [] m_pElemArray;
+ m_pElemArray = 0;
+}
+
+ocsd_err_t OcsdGenElemStack::addElem(const ocsd_trc_index_t trc_pkt_idx)
+{
+ ocsd_err_t err = OCSD_OK;
+
+ if (((m_curr_elem_idx + 1) == m_elemArraySize) || !m_pElemArray)
+ {
+ err = growArray();
+ if (err)
+ return err;
+ }
+
+ // if there is a least one element then copy and increment
+ // otherwise we are at base of stack.
+ if (m_elem_to_send)
+ {
+ copyPersistentData(m_curr_elem_idx, m_curr_elem_idx + 1);
+ m_curr_elem_idx++;
+ }
+ m_pElemArray[m_curr_elem_idx].trc_pkt_idx = trc_pkt_idx;
+ m_elem_to_send++;
+ return err;
+}
+
+ocsd_err_t OcsdGenElemStack::addElemType(const ocsd_trc_index_t trc_pkt_idx, ocsd_gen_trc_elem_t elem_type)
+{
+ ocsd_err_t err = addElem(trc_pkt_idx);
+ if (!err)
+ getCurrElem().setType(elem_type);
+ return err;
+}
+
+ocsd_err_t OcsdGenElemStack::resetElemStack()
+{
+ ocsd_err_t err = OCSD_OK;
+ if (!m_pElemArray)
+ {
+ err = growArray();
+ if (err)
+ return err;
+ }
+
+ if (!isInit())
+ return OCSD_ERR_NOT_INIT;
+
+ resetIndexes();
+ return err;
+}
+
+void OcsdGenElemStack::resetIndexes()
+{
+ // last time there was more than one element on stack
+ if (m_curr_elem_idx > 0)
+ copyPersistentData(m_curr_elem_idx, 0);
+
+ // indexes to bottom of stack, nothing in use at present
+ m_curr_elem_idx = 0;
+ m_send_elem_idx = 0;
+ m_elem_to_send = 0;
+}
+
+ocsd_datapath_resp_t OcsdGenElemStack::sendElements()
+{
+ ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
+ if (!isInit())
+ return OCSD_RESP_FATAL_NOT_INIT;
+
+ while (m_elem_to_send && OCSD_DATA_RESP_IS_CONT(resp))
+ {
+ resp = m_sendIf->first()->TraceElemIn(m_pElemArray[m_send_elem_idx].trc_pkt_idx, m_CSID, *(m_pElemArray[m_send_elem_idx].pElem));
+ m_send_elem_idx++;
+ m_elem_to_send--;
+ }
+
+ // clear the indexes if we are done.
+ if (!m_elem_to_send)
+ resetIndexes();
+ return resp;
+}
+
+ocsd_err_t OcsdGenElemStack::growArray()
+{
+ elemPtr_t *p_new_array = 0;
+ const int increment = 4;
+
+ p_new_array = new (std::nothrow) elemPtr_t[m_elemArraySize + increment];
+
+ if (p_new_array != 0)
+ {
+ OcsdTraceElement *pElem = 0;
+
+ // fill the last increment elements with new objects
+ for (int i = 0; i < increment; i++)
+ {
+ pElem = new (std::nothrow) OcsdTraceElement();
+ if (!pElem)
+ return OCSD_ERR_MEM;
+ pElem->init();
+ p_new_array[m_elemArraySize + i].pElem = pElem;
+ }
+
+ // copy the existing objects from the old array to the start of the new one
+ if (m_elemArraySize > 0)
+ {
+ for (int i = 0; i < m_elemArraySize; i++)
+ {
+ p_new_array[i].pElem = m_pElemArray[i].pElem;
+ p_new_array[i].trc_pkt_idx = m_pElemArray[i].trc_pkt_idx;
+ }
+ }
+
+ // delete the old pointer array.
+ delete[] m_pElemArray;
+ m_elemArraySize += increment;
+ m_pElemArray = p_new_array;
+ }
+ else
+ return OCSD_ERR_MEM;
+
+ return OCSD_OK;
+}
+
+void OcsdGenElemStack::copyPersistentData(int src, int dst)
+{
+ m_pElemArray[dst].pElem->copyPersistentData(*(m_pElemArray[src].pElem));
+}
+
+const bool OcsdGenElemStack::isInit()
+{
+ if (!m_is_init) {
+ if (m_elemArraySize && m_pElemArray && m_sendIf)
+ m_is_init = true;
+ }
+ return m_is_init;
+}
+
+
+/* End of File ocsd_gen_elem_stack.cpp */