OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [stdlib/] [malloc-simple/] [alloc.c] - Blame information for rev 1325

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/* alloc.c
2
 *
3
 * Written by Erik Andersen <andersee@debian.org>
4
 * LGPLv2
5
 *
6
 * Parts of the memalign code were stolen from malloc-930716.
7
 */
8
 
9
#include <features.h>
10
#include <unistd.h>
11
#include <stdio.h>
12
#include <stdlib.h>
13
#include <string.h>
14
#include <unistd.h>
15
#include <sys/mman.h>
16
 
17
 
18
#ifdef L_malloc
19
void *malloc(size_t size)
20
{
21
    void *result;
22
 
23
    if (unlikely(size == 0)) {
24
#if defined(__MALLOC_GLIBC_COMPAT__)
25
        size++;
26
#else
27
        /* Some programs will call malloc (0).  Lets be strict and return NULL */
28
        return 0;
29
#endif
30
    }
31
 
32
#ifdef __UCLIBC_HAS_MMU__
33
    result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE,
34
            MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
35
    if (result == MAP_FAILED)
36
        return 0;
37
    * (size_t *) result = size;
38
    return(result + sizeof(size_t));
39
#else
40
    result = mmap((void *) 0, size, PROT_READ | PROT_WRITE,
41
            MAP_SHARED | MAP_ANONYMOUS, -1, 0);
42
    if (result == MAP_FAILED)
43
        return 0;
44
    return(result);
45
#endif
46
}
47
#endif
48
 
49
#ifdef L_calloc
50
void * calloc(size_t nmemb, size_t lsize)
51
{
52
        void *result;
53
        size_t size=lsize * nmemb;
54
 
55
        /* guard vs integer overflow, but allow nmemb
56
         * to fall through and call malloc(0) */
57
        if (nmemb && lsize != (size / nmemb)) {
58
                __set_errno(ENOMEM);
59
                return NULL;
60
        }
61
        result=malloc(size);
62
#if 0
63
        /* Standard unix mmap using /dev/zero clears memory so calloc
64
         * doesn't need to actually zero anything....
65
         */
66
        if (result != NULL) {
67
                memset(result, 0, size);
68
        }
69
#endif
70
        return result;
71
}
72
#endif
73
 
74
#ifdef L_realloc
75
void *realloc(void *ptr, size_t size)
76
{
77
    void *newptr = NULL;
78
 
79
    if (!ptr)
80
        return malloc(size);
81
    if (!size) {
82
        free(ptr);
83
        return malloc(0);
84
    }
85
 
86
    newptr = malloc(size);
87
    if (newptr) {
88
        memcpy(newptr, ptr,
89
#ifdef __UCLIBC_HAS_MMU__
90
                *((size_t *) (ptr - sizeof(size_t)))
91
#else
92
                size
93
#endif
94
              );
95
        free(ptr);
96
    }
97
    return newptr;
98
}
99
#endif
100
 
101
#ifdef L_free
102
extern int weak_function __libc_free_aligned(void *ptr);
103
void free(void *ptr)
104
{
105
    if (ptr == NULL)
106
        return;
107
    if (unlikely(__libc_free_aligned!=NULL)) {
108
        if (__libc_free_aligned(ptr)) {
109
            return;
110
        }
111
    }
112
#ifdef __UCLIBC_HAS_MMU__
113
    ptr -= sizeof(size_t);
114
    munmap(ptr, * (size_t *) ptr + sizeof(size_t));
115
#else
116
    munmap(ptr, 0);
117
#endif
118
}
119
#endif
120
 
121
#ifdef L_memalign
122
#ifdef __UCLIBC_HAS_THREADS__
123
#include <pthread.h>
124
extern pthread_mutex_t __malloclock;
125
# define LOCK   __pthread_mutex_lock(&__malloclock)
126
# define UNLOCK __pthread_mutex_unlock(&__malloclock);
127
#else
128
# define LOCK
129
# define UNLOCK
130
#endif
131
 
132
/* List of blocks allocated with memalign or valloc */
133
struct alignlist
134
{
135
    struct alignlist *next;
136
    __ptr_t aligned;    /* The address that memaligned returned.  */
137
    __ptr_t exact;      /* The address that malloc returned.  */
138
};
139
struct alignlist *_aligned_blocks;
140
 
141
/* Return memory to the heap. */
142
int __libc_free_aligned(void *ptr)
143
{
144
    struct alignlist *l;
145
 
146
    if (ptr == NULL)
147
        return 0;
148
 
149
    LOCK;
150
    for (l = _aligned_blocks; l != NULL; l = l->next) {
151
        if (l->aligned == ptr) {
152
            /* Mark the block as free */
153
            l->aligned = NULL;
154
            ptr = l->exact;
155
#ifdef __UCLIBC_HAS_MMU__
156
            ptr -= sizeof(size_t);
157
            munmap(ptr, * (size_t *) ptr + sizeof(size_t));
158
#else
159
            munmap(ptr, 0);
160
#endif
161
            return 1;
162
        }
163
    }
164
    UNLOCK;
165
    return 0;
166
}
167
void * memalign (size_t alignment, size_t size)
168
{
169
    void * result;
170
    unsigned long int adj;
171
 
172
    result = malloc (size + alignment - 1);
173
    if (result == NULL)
174
        return NULL;
175
    adj = (unsigned long int) ((unsigned long int) ((char *) result -
176
                (char *) NULL)) % alignment;
177
    if (adj != 0)
178
    {
179
        struct alignlist *l;
180
        LOCK;
181
        for (l = _aligned_blocks; l != NULL; l = l->next)
182
            if (l->aligned == NULL)
183
                /* This slot is free.  Use it.  */
184
                break;
185
        if (l == NULL)
186
        {
187
            l = (struct alignlist *) malloc (sizeof (struct alignlist));
188
            if (l == NULL) {
189
                free(result);
190
                UNLOCK;
191
                return NULL;
192
            }
193
            l->next = _aligned_blocks;
194
            _aligned_blocks = l;
195
        }
196
        l->exact = result;
197
        result = l->aligned = (char *) result + alignment - adj;
198
        UNLOCK;
199
    }
200
 
201
    return result;
202
}
203
#endif
204
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.