source: soft/giet_vm/sort/main.c @ 262

Last change on this file since 262 was 258, checked in by alain, 11 years ago

This is a major release, including a deep restructuration of code.
The main evolutions are

  • use of the Tsar preloader to load the GIET boot-loader from disk
  • introduction of a FAT32 file system library,
  • use of this fat32 library by the boot-loader to load the map.bin data structure, and the various .elf files
  • reorganisation of drivers (one file per peripheral).
  • introduction of drivers for new peripherals: vci_chbuf_dma and vci_multi_ahci.
  • introduction of a new physical memory allocator in the boot code.

This release has been tested on the tsar_generic_iob architecture,
for the two following mappings: 4c_1p_iob_four.xml and 4c_1p_iob_sort.xml

  • Property svn:executable set to *
File size: 6.8 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2// File :
3//     
4//      main.c
5//
6// Date :
7//     
8//      November 2013
9//
10// Author :
11//
12//      Cesar Fuguet Tortolero <cesar.fuguet-tortolero@lip6.fr>
13//
14// Description :
15//
16//      Sort application using the GIET-VM OS. This application uses the
17//      barrier routines to apply a sort algorithm in several stages.
18//
19//      Considerations :
20//
21//          - It supports up to 256 processors and the number of processors
22//            must be a power of 2.
23//
24//          - If there is only one TTY available, this application uses a spin
25//            lock to avoid several threads writting at the same time.
26//
27//          - This application must be executed on a cache coherent
28//            architecture. Otherwise some modifications must be applied
29//
30//          - The processors executing this application must have a contiguous
31//            processor id and the first processor must have id 0.
32//
33//      TODO: Replace processor id based identification mechanism by one based
34//            on thread id
35//
36///////////////////////////////////////////////////////////////////////////////
37
38#include "stdio.h"
39#include "hard_config.h"
40#include "barrier.h"
41#include "spin_lock.h"
42
43//////////////////////////////////////////////////////////////////////////
44// The NPROCS constant must be modified depending on the desired number of
45// threads
46
47#define NPROCS          4
48#define ARRAY_LENGTH    (NPROCS * 128)
49#define IPP             (ARRAY_LENGTH / NPROCS) // ITEMS PER PROCESSOR
50
51////////////////////////////////////////////////////////////////////////////////
52// Processors other than 0 display algorithm state
53// The processor 0 always displays some information so this does not affect him
54
55#define VERBOSE         1
56
57///////////////////////////////////////////////////////////////////////
58// Define printf according to verbosity option and number of available
59// TTY
60
61#if (VERBOSE == 1)
62#   if (NB_TTY_CHANNELS > 1)
63#       define printf(...)     giet_tty_printf(__VA_ARGS__)
64#       define puts(...)       giet_tty_puts(__VA_ARGS__)
65
66#   else    // NB_TTY_CHANNELS == 0
67#       define printf(...) \
68        lock_acquire(&tty_lock); \
69        giet_tty_printf(__VA_ARGS__); \
70        lock_release(&tty_lock); 
71#   endif
72#else       // VERBOSE == 0
73#   define printf(...)
74#   define puts(...)
75#endif
76
77#define task0_printf(...) if(procid() == 0) giet_tty_printf(__VA_ARGS__)
78
79#define exit    giet_exit
80#define procid  giet_procid
81#define rand    giet_rand
82
83int array0[ARRAY_LENGTH];
84int array1[ARRAY_LENGTH];
85
86volatile int init_ok = 0;
87
88void bubbleSort(
89        int * array,
90        unsigned int length,
91        unsigned int init_pos);
92
93void merge(
94        int * array,
95        int * result,
96        int length,
97        int init_pos_a,
98        int init_pos_b,
99        int init_pos_result);
100
101///////////////////////////////////////////////////
102// This application support at most 256 processors
103// Number of barriers = log2(NPROCS)
104
105giet_barrier_t barrier[8];
106giet_lock_t tty_lock;
107
108__attribute__ ((constructor)) void sort()
109{
110    int proc_id = procid();
111    int * src_array;
112    int * dst_array;
113    int i;
114
115    task0_printf("Starting SORT application\n");
116
117    ////////////////////////
118    // Array Initialization
119
120    for (i = IPP * proc_id; i < IPP * (proc_id + 1); i++)
121    {
122        array0[i] = rand();
123    }
124
125    ///////////////////////////
126    // Barriers Initialization
127
128    while((proc_id != 0) && (init_ok == 0));
129
130    if (proc_id == 0)
131    {
132        for (i = 0; i < __builtin_ctz(NPROCS); i++)
133        {
134            task0_printf("Initializing barrier %d with %d\n", i, NPROCS >> i);
135            barrier_init(&barrier[i], NPROCS >> i);
136        }
137
138        asm volatile ("sync");
139        init_ok = 1;
140    }
141
142    asm volatile ("sync");
143    barrier_wait(&barrier[0]);
144
145    ///////////////////////////////////
146    // Parallel sort of array elements
147
148    printf("Proc %d Stage 0: Processor Sorting...\n\r", proc_id);
149
150    bubbleSort(array0, IPP, IPP * proc_id);
151
152    printf("Proc %d Finishing Stage 0...\n\r", proc_id);
153
154    for (i = 0; i < __builtin_ctz(NPROCS); i++)
155    {
156        asm volatile ("sync");
157        barrier_wait(&barrier[i]);
158
159        printf("Proc %d Stage %d: Starting...\n\r", proc_id, i+1);
160
161        if((proc_id % (2 << i)) != 0) exit();
162
163        if((i % 2) == 0)
164        {
165            src_array = &array0[0];
166            dst_array = &array1[0];
167        }
168        else
169        {
170            src_array = &array1[0];
171            dst_array = &array0[0];
172        }
173
174        merge(src_array, dst_array
175                , IPP << i
176                , IPP * proc_id
177                , IPP * (proc_id + (1 << i))
178                , IPP * proc_id
179                );
180
181        printf("Proc %d Finishing Stage %d...\n\r", proc_id, i + 1);
182    }
183
184    int success;
185    int failure_index;
186
187    //////////////////////////////
188    // Verify the resulting array
189
190    if(proc_id == 0)
191    {
192        success = 1;
193
194        for(i=0; i<(ARRAY_LENGTH-1); i++)
195        {
196            if(dst_array[i] > dst_array[i+1])
197            {
198
199                success = 0;
200                failure_index = i;
201                break;
202            }
203        }
204
205        if (success)
206        {
207            printf("Success!!\n\r");
208        }
209        else
210        {
211            printf("Failure!! Incorrect element: %d\n\r", failure_index);
212
213
214            for(i=0; i<ARRAY_LENGTH; i++)
215            {
216                printf("array[%d] = %d\n", i, dst_array[i]);
217            }
218        }
219    }
220
221    exit();
222}
223
224void bubbleSort(
225        int * array,
226        unsigned int length,
227        unsigned int init_pos)
228{
229    int i;
230    int j;
231    int aux;
232
233    for(i = 0; i < length; i++)
234    {
235        for(j = init_pos; j < (init_pos + length - i - 1); j++)
236        {
237            if(array[j] > array[j + 1])
238            {
239                aux          = array[j + 1];
240                array[j + 1] = array[j];
241                array[j]     = aux;
242            }
243        }
244    }
245}
246
247void merge(
248        int * array,
249        int * result,
250        int length,
251        int init_pos_a,
252        int init_pos_b,
253        int init_pos_result)
254{
255    int i;
256    int j;
257    int k;
258
259    i = 0;
260    j = 0;
261    k = init_pos_result;
262
263    while((i < length) || (j < length))
264    {
265        if((i < length) && (j < length))
266        {
267            if(array[init_pos_a + i] < array[init_pos_b + j])
268            {
269                result[k++] = array[init_pos_a + i];
270                i++;
271            }
272            else
273            {
274                result[k++] = array[init_pos_b + j];
275                j++;
276            }
277        }
278        else if(i < length)
279        {
280            result[k++] = array[init_pos_a + i];
281            i++;
282        }
283        else
284        {
285            result[k++] = array[init_pos_b + j];
286            j++;
287        }
288    }
289}
290
291/* vim: tabstop=4 : shiftwidth=4 : expandtab
292*/
Note: See TracBrowser for help on using the repository browser.