1/* Copyright (C) 2008 The Android Open Source Project
2**
3** This software is licensed under the terms of the GNU General Public
4** License version 2, as published by the Free Software Foundation, and
5** may be copied, distributed, and modified under those terms.
6**
7** This program is distributed in the hope that it will be useful,
8** but WITHOUT ANY WARRANTY; without even the implied warranty of
9** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10** GNU General Public License for more details.
11*/
12#include "android/utils/system.h"
13#include "android/utils/assert.h"
14#include <stdlib.h>
15#include <stdio.h>
16#ifdef _WIN32
17#  define WIN32_LEAN_AND_MEAN
18#  include <windows.h>  /* for Sleep */
19#else
20#  include <unistd.h>  /* for usleep */
21#endif
22
23void*
24android_alloc( size_t  size )
25{
26    void*   block;
27
28    if (size == 0)
29        return NULL;
30
31    block = malloc(size);
32    if (block != NULL)
33        return block;
34
35    fprintf(stderr, "PANIC: not enough memory\n");
36    exit(1);
37    return NULL;
38}
39
40void*
41android_alloc0( size_t  size )
42{
43    void*   block;
44
45    if (size == 0)
46        return NULL;
47
48    block = calloc(1, size);
49    if (block != NULL)
50        return block;
51
52    fprintf(stderr, "PANIC: not enough memory\n");
53    exit(1);
54    return NULL;
55}
56
57void*
58android_realloc( void*  block, size_t  size )
59{
60    void*   block2;
61
62    if (size == 0) {
63        free(block);
64        return NULL;
65    }
66    block2 = realloc(block, size);
67    if (block2 != NULL)
68        return block2;
69
70    fprintf(stderr, "PANIC: not enough memory to reallocate %u bytes\n",
71            (unsigned)size);
72    exit(1);
73    return NULL;
74}
75
76void
77android_free( void*  block )
78{
79    if (block)
80        free(block);
81}
82
83void*
84_android_array_alloc( size_t  itemSize, size_t  count )
85{
86#if ACONFIG_USE_ASSERT
87    size_t  maxSize;
88
89    if (itemSize == 0)
90        AASSERT_FAIL("item size is 0\n");
91
92    maxSize = (~(size_t)0) / itemSize;
93    if (count > maxSize)
94        AASSERT_FAIL("allocation too large (%d > %d)\n", count, maxSize);
95#endif
96    return android_alloc(itemSize * count);
97}
98
99void*
100_android_array_alloc0( size_t  itemSize, size_t  count )
101{
102    void*  block = _android_array_alloc(itemSize, count);
103    memset(block, 0, itemSize*count);
104    return block;
105}
106
107void*
108_android_array_realloc( void* block, size_t  itemSize, size_t  count )
109{
110#if ACONFIG_USE_ASSERT
111    size_t  maxSize;
112
113    if (itemSize == 0)
114        AASSERT_FAIL("item size is 0\n");
115
116    maxSize = (~(size_t)0) / itemSize;
117    if (count > maxSize)
118        AASSERT_FAIL("reallocation of %d-bytes array too large (%d > %d)\n",
119                     itemSize, count, maxSize);
120#endif
121    return android_realloc(block, itemSize*count);
122}
123
124char*
125android_strdup( const char*  str )
126{
127    int    len;
128    char*  copy;
129
130    if (str == NULL)
131        return NULL;
132
133    len  = strlen(str);
134    copy = malloc(len+1);
135    memcpy(copy, str, len);
136    copy[len] = 0;
137
138    return copy;
139}
140
141#ifdef _WIN32
142char*
143win32_strsep(char**  pline, const char*  delim)
144{
145    char*  line = *pline;
146    char*  p    = line;
147
148    if (p == NULL)
149        return NULL;
150
151    for (;;) {
152        int          c = *p++;
153        const char*  q = delim;
154
155        if (c == 0) {
156            p = NULL;
157            break;
158        }
159
160        while (*q) {
161            if (*q == c) {
162                p[-1] = 0;
163                goto Exit;
164            }
165            q++;
166        }
167    }
168Exit:
169    *pline = p;
170    return line;
171}
172#endif
173
174
175void
176disable_sigalrm( signal_state_t  *state )
177{
178#ifdef _WIN32
179    (void)state;
180#else
181    sigset_t  set;
182
183    sigemptyset(&set);
184    sigaddset(&set, SIGALRM);
185    pthread_sigmask (SIG_BLOCK, &set, &state->old);
186#endif
187}
188
189void
190restore_sigalrm( signal_state_t  *state )
191{
192#ifdef _WIN32
193    (void)state;
194#else
195    pthread_sigmask (SIG_SETMASK, &state->old, NULL);
196#endif
197}
198
199void
200sleep_ms( int  timeout_ms )
201{
202#ifdef _WIN32
203    if (timeout_ms <= 0)
204        return;
205
206    Sleep( timeout_ms );
207#else
208    if (timeout_ms <= 0)
209        return;
210
211    BEGIN_NOSIGALRM
212    usleep( timeout_ms*1000 );
213    END_NOSIGALRM
214#endif
215}
216