source: proiecte/swift/trunk/test/qsort_ws.c @ 176

Last change on this file since 176 was 176, checked in by (none), 14 years ago
  • imported repo from "guagal"
File size: 5.7 KB
Line 
1/*
2 * swift_context.c
3 *
4 * (c) 2009 Ionut Rosoiu <ionut.rosoiu@gmail.com>
5 *
6 */
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <omp.h>
11#include "swift.h"
12
13int limit;
14
15extern void read_array(char *filename, int **arr, int *n);
16extern void free_array(int *arr);
17extern void check_array(int *arr, int n);
18
19typedef struct qs_data {
20        int *a;
21        int l;
22        int r;
23
24        char _pad1[SWIFT_CACHE_LINE_SIZE - sizeof(swift_size_t)];
25
26        swift_size_t sync_frames_remaining;
27
28        char _pad2[SWIFT_CACHE_LINE_SIZE - sizeof(swift_size_t)];
29} qs_data_t;
30
31/* forward declaration for the fibo() */
32void qs(swift_thread_t *thread, swift_frame_t *frame);
33
34
35inline
36void swap(int *a, int *b)
37{
38        int tmp = *a;
39        *a = *b;
40        *b = tmp;
41}
42
43inline
44int partition(int *a, int l, int r)
45{
46        int pivot = a[l];
47        int i = l;
48        int j = r + 1;
49
50        while (1) {
51                do {
52                        ++i;
53                } while (a[i] <= pivot && i <= r);
54
55                do {
56                        --j;
57                } while (a[j] > pivot);
58
59                if (i >= j) {
60                        break;
61                }
62
63                swap(&a[i], &a[j]);
64        }
65
66        swap(&a[l], &a[j]);
67        return j;
68}
69
70void qs_ws(swift_thread_t *thread, swift_frame_t *frame)
71{
72        qs_data_t *data = frame->private_data;
73        swift_status_t status;
74        int pivot, n;
75
76        SWIFT_LOG(INFO, "\n[%d] qs() c=%d f=%c.%d-%d (%d)\n", thread->id,
77                                                                SWIFT_PROC(frame->info), SWIFT_FRAME_NAME(frame->info),
78                                                                ((frame->dbg >> 16) & 0xFF), (frame->dbg & 0xFF),
79                                                                SWIFT_FRAME_ID(frame->info));
80
81        if (data->l < data->r) {
82                swift_frame_t frame1;
83                qs_data_t data1;
84
85                swift_frame_t frame2;
86                qs_data_t data2;
87
88#ifdef LOGGING_ON
89                int i;
90#endif
91
92                pivot = partition(data->a, data->l, data->r);
93
94#ifdef LOGGING_ON
95                for (i=data->l; i<=data->r; i++) {
96                        if (i == pivot) {
97                                fprintf(stderr, "%d<%d> ", i, data->a[i]);
98                        } else {
99                                fprintf(stderr, "%d(%d) ", i, data->a[i]);
100                        }
101                }
102                fprintf(stderr, "\n");
103#endif
104
105                // ---------- left ---------
106                frame1.closure = qs_ws;
107                frame1.flags = 0;
108#ifdef LOGGING_ON
109                frame1.creator_id = thread->id;
110                frame1.dbg = ((data->l & 0xFF) << 16) | ((pivot - 1) & 0xFF);
111#endif
112                data1.a = data->a;
113                data1.l = data->l;
114                data1.r = pivot - 1;
115
116                frame1.private_data = &data1;
117
118                SWIFT_WRITE_FRAME_INFO((&frame1), thread->id, 'q', thread->frame_no++);
119
120                frame1.dependencies_frame = NULL;
121                frame1.sync_frames_remaining = &data->sync_frames_remaining;
122
123                // ---------- right ---------
124                frame2.closure = qs_ws;
125                frame2.flags = 0;
126#ifdef LOGGING_ON
127                frame2.creator_id = thread->id;
128                frame2.dbg = (((pivot + 1) & 0xFF) << 16) | (data->r & 0xFF);
129#endif
130                data2.a = data->a;
131                data2.l = pivot + 1;
132                data2.r = data->r;
133
134                frame2.private_data = &data2;
135
136                SWIFT_WRITE_FRAME_INFO((&frame2), thread->id, 'q', thread->frame_no++);
137
138                frame2.dependencies_frame = NULL;
139                frame2.sync_frames_remaining = &data->sync_frames_remaining;
140
141                // ------------------------
142                // wait for 1&2 to finish
143                data->sync_frames_remaining = 2;
144
145                // put it into the workqueue
146                swift_deque_push(&thread->workque, &frame1, &status);
147                swift_deque_push(&thread->workque, &frame2, &status);
148
149                // sync
150                while ((n = SWIFT_ATOMIC_READ(data->sync_frames_remaining))) {
151                        SWIFT_LOG(INFO, "[%d] %s rem=%d c=%d f=%c.%d-%d (%d)\n", thread->id, "@sync", n,
152                                                        SWIFT_PROC(frame->info), SWIFT_FRAME_NAME(frame->info),
153                                                        ((frame->dbg >> 16) & 0xFF), (frame->dbg & 0xFF),
154                                                        SWIFT_FRAME_ID(frame->info));
155                        swift_scheduler_execute(thread);
156                }
157
158                SWIFT_LOG(INFO, "[%d] __qs(%d, %d)\n", thread->id, data->l, data->r);
159
160                if (SWIFT_FRAME_IS_END_PARALLEL(frame)) {
161                        SWIFT_LOG(INFO, "[%d] END_PARALLEL!!!\n", thread->id);
162                        thread->stop = 1;
163                }
164        }
165
166        swift_signal_frame_done(thread, frame);
167        swift_frame_done(thread->context, thread, frame);
168}
169
170void* thread_start(void *arg) {
171        swift_thread_t *thread = arg;
172        int i = 0;
173
174        SWIFT_LOG(INFO, "_____started thread %d\n", thread->id);
175
176        while(!thread->stop) {
177                swift_scheduler_execute(thread);
178        }
179
180        // inform all other threads that they must stop
181        for (i=0; i<thread->context->thread_num; i++) {
182                thread->context->threads[i].stop = 1;
183        }
184
185
186        SWIFT_LOG(INFO, "_____finished thread %d: %d frames processed\n", thread->id, thread->stats);
187        printf("_____finished thread %d: %d frames processed\n", thread->id, thread->stats);
188
189        return arg;
190}
191
192int quicksort(int *a, int size, int nthreads)
193{
194        swift_context_t context;
195        swift_frame_t frame;
196        qs_data_t data;
197        swift_status_t status;
198        int i;
199
200        SWIFT_LOG(INFO, "Started nthreads=%d\n", nthreads);
201
202        /* initialize the context */
203        swift_context_init(&context, nthreads);
204
205        /* push the first frame */
206        SWIFT_FRAME_SET_END_PARALLEL(&frame);
207        frame.closure = qs_ws;
208#ifdef LOGGING_ON
209        frame.dbg = size & 0xFF;
210        frame.creator_id = 0;
211#endif
212
213        data.a = a;
214        data.l = 0;
215        data.r = size - 1;
216        frame.private_data = &data;
217
218        SWIFT_WRITE_FRAME_INFO((&frame), 0, 'q', context.threads[0].frame_no++);
219        SWIFT_LOG_FRAME_INFO((&context.threads[0]), (&frame));
220
221        frame.dependencies_no = 0;
222        frame.dependencies_frame = NULL;
223        frame.sync_frames_remaining = &data.sync_frames_remaining;
224
225        swift_deque_push(&context.threads[0].workque, &frame, &status);
226        SWIFT_LOG(INFO, "pushed first frame\n");
227
228
229        /* start the threads */
230        for (i=0; i<nthreads; i++) {
231                swift_thread_start(&context.threads[i], thread_start);
232        }
233
234        /* wait for the threads to finish */
235        for (i=0; i<nthreads; i++) {
236                SWIFT_LOG(INFO, "_____waiting %d\n", i);
237                swift_thread_wait(&context.threads[i]);
238                SWIFT_LOG(INFO, "_____waiting %d done\n", i);
239        }
240
241        /* check the result */
242        printf("done with the first frame.\n");
243        swift_context_destroy(&context);
244        return 0;
245}
246
247int main(int argc, char **argv)
248{
249        int n, *a, nthreads;
250
251        if (argc != 4) {
252                fprintf(stderr, "usage: %s <input_file> <nthreads> <serial_limit>\n", argv[0]);
253                abort();
254        }
255
256        read_array(argv[1], &a, &n);
257
258        nthreads = strtol(argv[2], NULL, 10);
259        limit = strtol(argv[3], NULL, 10);
260
261        quicksort(a, n, nthreads);
262
263        check_array(a, n);
264
265        free_array(a);
266
267        printf("done.\n");
268        return 0;
269}
Note: See TracBrowser for help on using the repository browser.