1/*
2 * \file       ocsd_gen_elem_list.cpp
3 * \brief      OpenCSD : List of Generic trace elements for output.
4 *
5 * \copyright  Copyright (c) 2016, 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_list.h"
37
38OcsdGenElemList::OcsdGenElemList()
39{
40    m_firstElemIdx=0;
41    m_numUsed=0;
42    m_numPend=0;
43
44    m_elemArraySize = 0;
45    m_sendIf = 0;
46    m_CSID = 0;
47    m_pElemArray = 0;
48}
49
50OcsdGenElemList::~OcsdGenElemList()
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
60void OcsdGenElemList::reset()
61{
62    m_firstElemIdx=0;
63    m_numUsed=0;
64    m_numPend=0;
65}
66
67OcsdTraceElement *OcsdGenElemList::getNextElem(const ocsd_trc_index_t trc_pkt_idx)
68{
69    OcsdTraceElement *pElem = 0;
70    if(getNumElem() == m_elemArraySize) // all in use
71        growArray();
72
73    if(m_pElemArray != 0)
74    {
75        m_numUsed++;
76        int idx = getAdjustedIdx(m_firstElemIdx + m_numUsed - 1);
77        pElem = m_pElemArray[idx].pElem;
78        m_pElemArray[idx].trc_pkt_idx = trc_pkt_idx;
79    }
80    return pElem;
81}
82
83const ocsd_gen_trc_elem_t OcsdGenElemList::getElemType(const int entryN) const
84{
85    ocsd_gen_trc_elem_t elem_type =  OCSD_GEN_TRC_ELEM_UNKNOWN;
86    if(entryN < getNumElem())
87    {
88        int idx = getAdjustedIdx(m_firstElemIdx + entryN);
89        elem_type = m_pElemArray[idx].pElem->getType();
90    }
91    return elem_type;
92}
93
94ocsd_datapath_resp_t OcsdGenElemList::sendElements()
95{
96    ocsd_datapath_resp_t resp = OCSD_RESP_CONT;
97
98    if((m_elemArraySize == 0) || (m_sendIf == 0))
99        return OCSD_RESP_FATAL_NOT_INIT;
100
101    if(!m_sendIf->hasAttachedAndEnabled())
102        return OCSD_RESP_FATAL_NOT_INIT;
103
104    while(elemToSend() && OCSD_DATA_RESP_IS_CONT(resp))
105    {
106        resp = m_sendIf->first()->TraceElemIn(m_pElemArray[m_firstElemIdx].trc_pkt_idx, m_CSID, *(m_pElemArray[m_firstElemIdx].pElem));
107        m_firstElemIdx++;
108        if(m_firstElemIdx >= m_elemArraySize)
109            m_firstElemIdx = 0;
110        m_numUsed--;
111    }
112    return resp;
113}
114
115// this function will enlarge the array, and create extra element objects.
116// existing objects will be moved to the front of the array
117// called if all elements are in use. (sets indexes accordingly)
118void OcsdGenElemList::growArray()
119{
120    elemPtr_t *p_new_array = 0;
121
122    int increment;
123    if(m_elemArraySize == 0)
124        // starting from scratch...
125        increment = 8;
126    else
127        increment = m_elemArraySize / 2;    // grow by 50%
128
129
130    p_new_array = new (std::nothrow) elemPtr_t[m_elemArraySize+increment];
131
132    if(p_new_array != 0)
133    {
134        // fill the last increment elements with new objects
135        for(int i=0; i < increment; i++)
136        {
137            p_new_array[m_elemArraySize+i].pElem = new (std::nothrow) OcsdTraceElement();
138        }
139
140        // copy the existing objects from the old array to the start of the new one
141        // and adjust the indices.
142        if(m_elemArraySize > 0)
143        {
144            int inIdx = m_firstElemIdx;
145            for(int i = 0; i < m_elemArraySize; i++)
146            {
147                p_new_array[i].pElem = m_pElemArray[inIdx].pElem;
148                p_new_array[i].trc_pkt_idx = m_pElemArray[inIdx].trc_pkt_idx;
149                inIdx++;
150                if(inIdx >= m_elemArraySize)
151                    inIdx = 0;
152            }
153        }
154
155        // delete the old pointer array.
156        delete [] m_pElemArray;
157        m_elemArraySize += increment;
158    }
159    else
160         m_elemArraySize = 0;
161
162    // update the internal array pointers to the new array
163    if(m_firstElemIdx >= 0)
164        m_firstElemIdx = 0;
165    m_pElemArray = p_new_array;
166}
167
168/* End of File ocsd_gen_elem_list.cpp */
169