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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [uClibc/] [libc/] [stdlib/] [malloc-standard/] [memalign.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1325 phoenix
/*
2
  This is a version (aka dlmalloc) of malloc/free/realloc written by
3
  Doug Lea and released to the public domain.  Use, modify, and
4
  redistribute this code without permission or acknowledgement in any
5
  way you wish.  Send questions, comments, complaints, performance
6
  data, etc to dl@cs.oswego.edu
7
 
8
  VERSION 2.7.2 Sat Aug 17 09:07:30 2002  Doug Lea  (dl at gee)
9
 
10
  Note: There may be an updated version of this malloc obtainable at
11
           ftp://gee.cs.oswego.edu/pub/misc/malloc.c
12
  Check before installing!
13
 
14
  Hacked up for uClibc by Erik Andersen <andersen@codepoet.org>
15
*/
16
 
17
#include <features.h>
18
#include <stddef.h>
19
#include <unistd.h>
20
#include <errno.h>
21
#include <string.h>
22
#include "malloc.h"
23
 
24
 
25
/* ------------------------------ memalign ------------------------------ */
26
void* memalign(size_t alignment, size_t bytes)
27
{
28
    size_t nb;             /* padded  request size */
29
    char*           m;              /* memory returned by malloc call */
30
    mchunkptr       p;              /* corresponding chunk */
31
    char*           brk;            /* alignment point within p */
32
    mchunkptr       newp;           /* chunk to return */
33
    size_t newsize;        /* its size */
34
    size_t leadsize;       /* leading space before alignment point */
35
    mchunkptr       remainder;      /* spare room at end to split off */
36
    unsigned long    remainder_size; /* its size */
37
    size_t size;
38
 
39
    /* If need less alignment than we give anyway, just relay to malloc */
40
 
41
    if (alignment <= MALLOC_ALIGNMENT) return malloc(bytes);
42
 
43
    /* Otherwise, ensure that it is at least a minimum chunk size */
44
 
45
    if (alignment <  MINSIZE) alignment = MINSIZE;
46
 
47
    /* Make sure alignment is power of 2 (in case MINSIZE is not).  */
48
    if ((alignment & (alignment - 1)) != 0) {
49
        size_t a = MALLOC_ALIGNMENT * 2;
50
        while ((unsigned long)a < (unsigned long)alignment) a <<= 1;
51
        alignment = a;
52
    }
53
 
54
    LOCK;
55
    checked_request2size(bytes, nb);
56
 
57
    /* Strategy: find a spot within that chunk that meets the alignment
58
     * request, and then possibly free the leading and trailing space.  */
59
 
60
 
61
    /* Call malloc with worst case padding to hit alignment. */
62
 
63
    m  = (char*)(malloc(nb + alignment + MINSIZE));
64
 
65
    if (m == 0) {
66
        UNLOCK;
67
        return 0; /* propagate failure */
68
    }
69
 
70
    p = mem2chunk(m);
71
 
72
    if ((((unsigned long)(m)) % alignment) != 0) { /* misaligned */
73
 
74
        /*
75
           Find an aligned spot inside chunk.  Since we need to give back
76
           leading space in a chunk of at least MINSIZE, if the first
77
           calculation places us at a spot with less than MINSIZE leader,
78
           we can move to the next aligned spot -- we've allocated enough
79
           total room so that this is always possible.
80
           */
81
 
82
        brk = (char*)mem2chunk((unsigned long)(((unsigned long)(m + alignment - 1)) &
83
                    -((signed long) alignment)));
84
        if ((unsigned long)(brk - (char*)(p)) < MINSIZE)
85
            brk += alignment;
86
 
87
        newp = (mchunkptr)brk;
88
        leadsize = brk - (char*)(p);
89
        newsize = chunksize(p) - leadsize;
90
 
91
        /* For mmapped chunks, just adjust offset */
92
        if (chunk_is_mmapped(p)) {
93
            newp->prev_size = p->prev_size + leadsize;
94
            set_head(newp, newsize|IS_MMAPPED);
95
            UNLOCK;
96
            return chunk2mem(newp);
97
        }
98
 
99
        /* Otherwise, give back leader, use the rest */
100
        set_head(newp, newsize | PREV_INUSE);
101
        set_inuse_bit_at_offset(newp, newsize);
102
        set_head_size(p, leadsize);
103
        free(chunk2mem(p));
104
        p = newp;
105
 
106
        assert (newsize >= nb &&
107
                (((unsigned long)(chunk2mem(p))) % alignment) == 0);
108
    }
109
 
110
    /* Also give back spare room at the end */
111
    if (!chunk_is_mmapped(p)) {
112
        size = chunksize(p);
113
        if ((unsigned long)(size) > (unsigned long)(nb + MINSIZE)) {
114
            remainder_size = size - nb;
115
            remainder = chunk_at_offset(p, nb);
116
            set_head(remainder, remainder_size | PREV_INUSE);
117
            set_head_size(p, nb);
118
            free(chunk2mem(remainder));
119
        }
120
    }
121
 
122
    check_inuse_chunk(p);
123
    UNLOCK;
124
    return chunk2mem(p);
125
}
126
 

powered by: WebSVN 2.1.0

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