1/*
2 *
3 * Copyright 2012 Samsung Electronics S.LSI Co. LTD
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * @file        Exynos_OSAL_ETC.c
20 * @brief
21 * @author      SeungBeom Kim (sbcrux.kim@samsung.com)
22 * @version     2.0.0
23 * @history
24 *   2012.02.20 : Create
25 */
26
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30#include <sys/time.h>
31
32#include "Exynos_OSAL_Memory.h"
33#include "Exynos_OSAL_ETC.h"
34#include "Exynos_OSAL_Log.h"
35
36static struct timeval perfStart[PERF_ID_MAX+1], perfStop[PERF_ID_MAX+1];
37static unsigned long perfTime[PERF_ID_MAX+1], totalPerfTime[PERF_ID_MAX+1];
38static unsigned int perfFrameCount[PERF_ID_MAX+1], perfOver30ms[PERF_ID_MAX+1];
39
40#ifndef HAVE_GETLINE
41ssize_t getline(char **ppLine, size_t *pLen, FILE *pStream)
42{
43    char *pCurrentPointer = NULL;
44    size_t const chunk = 512;
45
46    size_t defaultBufferSize = chunk + 1;
47    size_t retSize = 0;
48
49    if (*ppLine == NULL) {
50        *ppLine = (char *)malloc(defaultBufferSize);
51        if (*ppLine == NULL) {
52            retSize = -1;
53            goto EXIT;
54        }
55        *pLen = defaultBufferSize;
56    }
57    else {
58        if (*pLen < defaultBufferSize) {
59            *ppLine = (char *)realloc(*ppLine, defaultBufferSize);
60            if (*ppLine == NULL) {
61                retSize = -1;
62                goto EXIT;
63            }
64            *pLen = defaultBufferSize;
65        }
66    }
67
68    while (1) {
69        size_t i;
70        size_t j = 0;
71        size_t readByte = 0;
72
73        pCurrentPointer = *ppLine + readByte;
74
75        i = fread(pCurrentPointer, 1, chunk, pStream);
76        if (i < chunk && ferror(pStream)) {
77            retSize = -1;
78            goto EXIT;
79        }
80        while (j < i) {
81            ++j;
82            if (*pCurrentPointer++ == (char)'\n') {
83                *pCurrentPointer = '\0';
84                if (j != i) {
85                    if (fseek(pStream, j - i, SEEK_CUR)) {
86                        retSize = -1;
87                        goto EXIT;
88                }
89                    if (feof(pStream))
90                        clearerr(pStream);
91                }
92                readByte += j;
93                retSize = readByte;
94                goto EXIT;
95            }
96        }
97
98        readByte += j;
99        if (feof(pStream)) {
100            if (readByte) {
101                retSize = readByte;
102                goto EXIT;
103            }
104            if (!i) {
105                retSize = -1;
106                goto EXIT;
107            }
108        }
109
110        i = ((readByte + (chunk * 2)) / chunk) * chunk;
111        if (i != *pLen) {
112            *ppLine = (char *)realloc(*ppLine, i);
113            if (*ppLine == NULL) {
114                retSize = -1;
115                goto EXIT;
116        }
117            *pLen = i;
118        }
119    }
120
121EXIT:
122    return retSize;
123}
124#endif /* HAVE_GETLINE */
125
126OMX_PTR Exynos_OSAL_Strcpy(OMX_PTR dest, OMX_PTR src)
127{
128    return strcpy(dest, src);
129}
130
131OMX_PTR Exynos_OSAL_Strncpy(OMX_PTR dest, OMX_PTR src, size_t num)
132{
133    return strncpy(dest, src, num);
134}
135
136OMX_S32 Exynos_OSAL_Strcmp(OMX_PTR str1, OMX_PTR str2)
137{
138    return strcmp(str1, str2);
139}
140
141OMX_S32 Exynos_OSAL_Strncmp(OMX_PTR str1, OMX_PTR str2, size_t num)
142{
143    return strncmp(str1, str2, num);
144}
145
146OMX_PTR Exynos_OSAL_Strcat(OMX_PTR dest, OMX_PTR src)
147{
148    return strcat(dest, src);
149}
150
151OMX_PTR Exynos_OSAL_Strncat(OMX_PTR dest, OMX_PTR src, size_t num)
152{
153    return strncat(dest, src, num);
154}
155
156size_t Exynos_OSAL_Strlen(const char *str)
157{
158    return strlen(str);
159}
160
161static OMX_U32 MeasureTime(struct timeval *start, struct timeval *stop)
162{
163    unsigned long sec, usec, time;
164
165    sec = stop->tv_sec - start->tv_sec;
166    if (stop->tv_usec >= start->tv_usec) {
167        usec = stop->tv_usec - start->tv_usec;
168    } else {
169        usec = stop->tv_usec + 1000000 - start->tv_usec;
170        sec--;
171    }
172
173    time = sec * 1000000 + (usec);
174
175    return time;
176}
177
178void Exynos_OSAL_PerfInit(PERF_ID_TYPE id)
179{
180    memset(&perfStart[id], 0, sizeof(perfStart[id]));
181    memset(&perfStop[id], 0, sizeof(perfStop[id]));
182    perfTime[id] = 0;
183    totalPerfTime[id] = 0;
184    perfFrameCount[id] = 0;
185    perfOver30ms[id] = 0;
186}
187
188void Exynos_OSAL_PerfStart(PERF_ID_TYPE id)
189{
190    gettimeofday(&perfStart[id], NULL);
191}
192
193void Exynos_OSAL_PerfStop(PERF_ID_TYPE id)
194{
195    gettimeofday(&perfStop[id], NULL);
196
197    perfTime[id] = MeasureTime(&perfStart[id], &perfStop[id]);
198    totalPerfTime[id] += perfTime[id];
199    perfFrameCount[id]++;
200
201    if (perfTime[id] > 30000)
202        perfOver30ms[id]++;
203}
204
205OMX_U32 Exynos_OSAL_PerfFrame(PERF_ID_TYPE id)
206{
207    return perfTime[id];
208}
209
210OMX_U32 Exynos_OSAL_PerfTotal(PERF_ID_TYPE id)
211{
212    return totalPerfTime[id];
213}
214
215OMX_U32 Exynos_OSAL_PerfFrameCount(PERF_ID_TYPE id)
216{
217    return perfFrameCount[id];
218}
219
220int Exynos_OSAL_PerfOver30ms(PERF_ID_TYPE id)
221{
222    return perfOver30ms[id];
223}
224
225void Exynos_OSAL_PerfPrint(OMX_STRING prefix, PERF_ID_TYPE id)
226{
227    OMX_U32 perfTotal;
228    int frameCount;
229
230    frameCount = Exynos_OSAL_PerfFrameCount(id);
231    perfTotal = Exynos_OSAL_PerfTotal(id);
232
233    Exynos_OSAL_Log(EXYNOS_LOG_INFO, "%s Frame Count: %d", prefix, frameCount);
234    Exynos_OSAL_Log(EXYNOS_LOG_INFO, "%s Avg Time: %.2f ms, Over 30ms: %d",
235                prefix, (float)perfTotal / (float)(frameCount * 1000),
236                Exynos_OSAL_PerfOver30ms(id));
237}
238