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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [language/] [c/] [libc/] [stdlib/] [v2_0/] [src/] [qsort.cxx] - Blame information for rev 27

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

Line No. Rev Author Line
1 27 unneback
//===========================================================================
2
//
3
//      qsort.cxx
4
//
5
//      ANSI standard sorting function defined in section 7.10.5.2
6
//      of the standard
7
//
8
//===========================================================================
9
//####ECOSGPLCOPYRIGHTBEGIN####
10
// -------------------------------------------
11
// This file is part of eCos, the Embedded Configurable Operating System.
12
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13
//
14
// eCos is free software; you can redistribute it and/or modify it under
15
// the terms of the GNU General Public License as published by the Free
16
// Software Foundation; either version 2 or (at your option) any later version.
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21
// for more details.
22
//
23
// You should have received a copy of the GNU General Public License along
24
// with eCos; if not, write to the Free Software Foundation, Inc.,
25
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26
//
27
// As a special exception, if other files instantiate templates or use macros
28
// or inline functions from this file, or you compile this file and link it
29
// with other works to produce a work based on this file, this file does not
30
// by itself cause the resulting work to be covered by the GNU General Public
31
// License. However the source code for this file must still be made available
32
// in accordance with section (3) of the GNU General Public License.
33
//
34
// This exception does not invalidate any other reasons why a work based on
35
// this file might be covered by the GNU General Public License.
36
//
37
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38
// at http://sources.redhat.com/ecos/ecos-license/
39
// -------------------------------------------
40
//####ECOSGPLCOPYRIGHTEND####
41
//===========================================================================
42
//#####DESCRIPTIONBEGIN####
43
//
44
// Author(s):    jlarmour
45
// Contributors: 
46
// Date:         2000-04-30
47
// Purpose:     
48
// Description: 
49
// Usage:       
50
//
51
//####DESCRIPTIONEND####
52
//
53
//===========================================================================
54
//
55
// This code is based on original code with the following copyright:
56
//
57
/*-
58
 * Copyright (c) 1992, 1993
59
 *      The Regents of the University of California.  All rights reserved.
60
 *
61
 * Redistribution and use in source and binary forms, with or without
62
 * modification, are permitted provided that the following conditions
63
 * are met:
64
 * 1. Redistributions of source code must retain the above copyright
65
 *    notice, this list of conditions and the following disclaimer.
66
 * 2. Redistributions in binary form must reproduce the above copyright
67
 *    notice, this list of conditions and the following disclaimer in the
68
 *    documentation and/or other materials provided with the distribution.
69
 * 3. Neither the name of the University nor the names of its contributors
70
 *    may be used to endorse or promote products derived from this software
71
 *    without specific prior written permission.
72
 *
73
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83
 * SUCH DAMAGE.
84
 */
85
 
86
 
87
 
88
// CONFIGURATION
89
 
90
#include <pkgconf/libc_stdlib.h>   // Configuration header
91
 
92
// INCLUDES
93
 
94
#include <cyg/infra/cyg_type.h>    // Common type definitions and support
95
#include <cyg/infra/cyg_trac.h>    // Tracing support
96
#include <cyg/infra/cyg_ass.h>     // Assertion support
97
#include <stdlib.h>                // Header for all stdlib functions
98
                                   // (like this one)
99
 
100
// TRACING
101
 
102
# if defined(CYGDBG_USE_TRACING) && defined(CYGNUM_LIBC_QSORT_TRACE_LEVEL)
103
static int qsort_trace = CYGNUM_LIBC_QSORT_TRACE_LEVEL;
104
#  define TL1 (0 < qsort_trace)
105
# else
106
#  define TL1 (0)
107
# endif
108
 
109
 
110
// FUNCTION PROTOTYPES
111
 
112
static __inline__ char *med3(char *, char *, char *, __qsort_comparison_fn_t);
113
static __inline__ void swapfunc(char *, char *, int, int);
114
 
115
 
116
// MACRO FUNCTIONS
117
 
118
#define min(a, b)       ((a) < (b) ? (a) : (b))
119
 
120
//
121
// Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
122
//
123
 
124
#define swapcode(TYPE, parmi, parmj, n) do {            \
125
        long i = (n) / sizeof (TYPE);                   \
126
        TYPE *pi = (TYPE *) (parmi);                    \
127
        TYPE *pj = (TYPE *) (parmj);                    \
128
        do {                                            \
129
                TYPE   t = *pi;                         \
130
                *pi++ = *pj;                            \
131
                *pj++ = t;                              \
132
        } while (--i > 0);                              \
133
} while (0)
134
 
135
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
136
        es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
137
 
138
 
139
#define swap(a, b)                                      \
140
        if (swaptype == 0) {                            \
141
                long t = *(long *)(a);                  \
142
                *(long *)(a) = *(long *)(b);            \
143
                *(long *)(b) = t;                       \
144
        } else                                          \
145
                swapfunc(a, b, size, swaptype)
146
 
147
#define vecswap(a, b, n)        if ((n) > 0) swapfunc(a, b, n, swaptype)
148
 
149
 
150
// FUNCTIONS
151
 
152
// Debug wrapper for comparison function
153
static __inline__ int
154
cmp_wrapper( __qsort_comparison_fn_t cmp, void *x, void *y )
155
{
156
    int retval;
157
    CYG_TRACE3( TL1, "Calling comparison function address %08x with args "
158
                "( %08x, %08x )", cmp, x, y );
159
    retval = cmp(x, y);
160
 
161
    CYG_TRACE1( TL1, "Comparison function returned %d", retval );
162
 
163
    return retval;
164
} // cmp_wrapper()
165
 
166
static __inline__ void
167
swapfunc( char *a, char *b, int n, int swaptype)
168
{
169
    if(swaptype <= 1)
170
        swapcode(long, a, b, n);
171
    else
172
        swapcode(char, a, b, n);
173
} // swapfunc()
174
 
175
 
176
static __inline__ char *
177
med3( char *a, char *b, char *c, __qsort_comparison_fn_t cmp )
178
{
179
    return cmp_wrapper(cmp, a, b) < 0 ?
180
        (cmp_wrapper(cmp, b, c) < 0 ? b : (cmp_wrapper(cmp, a, c) < 0 ? c : a ))
181
        :(cmp_wrapper(cmp, b, c) > 0 ? b : (cmp_wrapper(cmp, a, c) < 0 ? a : c ));
182
} // med3()
183
 
184
 
185
void
186
qsort( void *base, size_t nmemb, size_t size, __qsort_comparison_fn_t compar )
187
{
188
    char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
189
    int d, r, swaptype, swap_cnt;
190
 
191
    CYG_REPORT_FUNCNAME( "qsort" );
192
    CYG_REPORT_FUNCARG4( "base=%08x, nmemb=%d, size=%d, compar=%08x",
193
                         base, nmemb, size, compar );
194
 
195
    CYG_CHECK_DATA_PTR( base, "base is not a valid pointer!" );
196
    CYG_CHECK_FUNC_PTR( compar, "compar is not a valid function pointer!" );
197
 
198
loop:
199
    SWAPINIT(base, size);
200
    swap_cnt = 0;
201
    if (nmemb < 7) {
202
        for (pm = (char *) base + size;
203
             pm < (char *) base + nmemb * size;
204
             pm += size)
205
            for (pl = pm; pl > (char *) base && cmp_wrapper( compar, pl - size, pl) > 0;
206
                 pl -= size)
207
                swap(pl, pl - size);
208
        {
209
            CYG_REPORT_RETURN();
210
            return;
211
        } // for
212
    } // if
213
    pm = (char *) base + (nmemb / 2) * size;
214
    if (nmemb > 7) {
215
        pl = (char *) base;
216
        pn = (char *) base + (nmemb - 1) * size;
217
        if (nmemb > 40) {
218
            d = (nmemb / 8) * size;
219
            pl = med3(pl, pl + d, pl + 2 * d, compar);
220
            pm = med3(pm - d, pm, pm + d, compar);
221
            pn = med3(pn - 2 * d, pn - d, pn, compar);
222
        } // if
223
        pm = med3(pl, pm, pn, compar);
224
    } // if
225
    swap( (char *)base, pm );
226
    pa = pb = (char *) base + size;
227
 
228
    pc = pd = (char *) base + (nmemb - 1) * size;
229
    for (;;) {
230
        while (pb <= pc && (r = cmp_wrapper( compar, pb, base)) <= 0) {
231
            if (r == 0) {
232
                swap_cnt = 1;
233
                swap(pa, pb);
234
                pa += size;
235
            } // if
236
            pb += size;
237
        } // while
238
        while (pb <= pc && (r = cmp_wrapper( compar, pc, base)) >= 0) {
239
            if (r == 0) {
240
                swap_cnt = 1;
241
                swap(pc, pd);
242
                pd -= size;
243
            } // if
244
            pc -= size;
245
        } // while
246
        if (pb > pc)
247
            break;
248
        swap(pb, pc);
249
        swap_cnt = 1;
250
        pb += size;
251
        pc -= size;
252
    } // for
253
    if (swap_cnt == 0) {  // Switch to insertion sort
254
        for (pm = (char *) base + size;
255
             pm < (char *) base + nmemb * size;
256
             pm += size)
257
            for (pl = pm; pl > (char *) base && cmp_wrapper( compar, pl - size, pl) > 0;
258
                 pl -= size)
259
                swap(pl, pl - size);
260
        {
261
            CYG_REPORT_RETURN();
262
            return;
263
        } // for
264
    } //if
265
 
266
    pn = (char *) base + nmemb * size;
267
    r = min(pa - (char *)base, pb - pa);
268
    vecswap((char *)base, pb - r, r);
269
    r = min( (unsigned)(pd - pc), pn - pd - size );
270
    vecswap(pb, pn - r, r);
271
    if ((unsigned)(r = pb - pa) > size)
272
        qsort(base, r / size, size, compar);
273
    if ((unsigned)(r = pd - pc) > size) {
274
        // Iterate rather than recurse to save stack space
275
        base = pn - r;
276
        nmemb = r / size;
277
        goto loop;
278
    } // if
279
/*              qsort(pn - r, r / size, size, compar);*/
280
 
281
    CYG_REPORT_RETURN();
282
} // qsort()
283
 
284
// EOF qsort.cxx

powered by: WebSVN 2.1.0

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