source: soft/giet_vm/giet_libs/mwmr_channel.c @ 685

Last change on this file since 685 was 479, checked in by alain, 10 years ago

Cosmetic: improve debug.

  • Property svn:executable set to *
File size: 11.8 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
2// File     : mwmr_channel.c         
3// Date     : 01/04/2012
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include "mwmr_channel.h"
9#include "giet_config.h"
10#include "stdio.h"
11#include "user_lock.h"
12
13//////////////////////////////////////
14void mwmr_init( mwmr_channel_t*  mwmr,
15                unsigned int*    buffer,     // buffer base address
16                unsigned int     width,      // number of words per item
17                unsigned int     nitems )    // max number of items
18{
19
20#if GIET_DEBUG_USER_MWMR
21unsigned int    x;
22unsigned int    y;
23unsigned int    lpid;
24giet_proc_xyp( &x, &y, &lpid );
25giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] initialises fifo %x / "
26                " buffer = %x / width = %d / nitems = %d\n",
27                x, y, lpid, (unsigned int)mwmr, (unsigned int)buffer, width, nitems );
28#endif
29
30    mwmr->ptw   = 0;
31    mwmr->ptr   = 0;
32    mwmr->sts   = 0;
33    mwmr->width = width;
34    mwmr->depth = width * nitems;
35    mwmr->data  = buffer;
36
37    lock_init( &mwmr->lock );
38}
39
40
41///////////////////////////////////////////////////
42unsigned int nb_mwmr_write( mwmr_channel_t * mwmr, 
43                            unsigned int *   buffer, 
44                            unsigned int     items)
45{
46
47#if GIET_DEBUG_USER_MWMR
48unsigned int    x;
49unsigned int    y;
50unsigned int    lpid;
51giet_proc_xyp( &x, &y, &lpid );
52giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] enters nb_mwmr_write()"
53                " : mwmr = %x / buffer = %x / items =  %d\n",
54                x, y, lpid, (unsigned int)mwmr, (unsigned int)buffer, items );
55#endif
56
57    unsigned int n;
58    unsigned int spaces; // number of empty slots (in words)
59    unsigned int nwords; // requested transfer length (in words)
60    unsigned int depth;  // channel depth (in words)
61    unsigned int width;  // channel width (in words)
62    unsigned int sts;    // channel sts
63    unsigned int ptw;    // channel ptw
64
65    if (items == 0) return 0;
66
67    // get the lock
68    lock_acquire( &mwmr->lock );
69
70    // access fifo status
71    depth  = mwmr->depth;
72    width  = mwmr->width;
73    sts    = mwmr->sts;
74    ptw    = mwmr->ptw;
75    spaces = depth - sts;
76    nwords = width * items;
77
78    if (spaces >= nwords) // transfer items, release lock and return
79    { 
80        for (n = 0; n < nwords; n++) 
81        {
82            mwmr->data[ptw] = buffer[n];
83            if ((ptw + 1) == depth)  ptw = 0; 
84            else                     ptw = ptw + 1;
85        }
86        mwmr->sts = mwmr->sts + nwords;
87        mwmr->ptw = ptw;
88
89#if GIET_DEBUG_USER_MWMR
90giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n",
91                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
92#endif
93
94        lock_release( &mwmr->lock );
95        return items;
96    }
97    else if (spaces < width) // release lock and return
98    {
99        lock_release( &mwmr->lock );
100        return 0;
101    }
102    else // transfer as many items as possible, release lock and return
103    {
104        nwords = (spaces / width) * width;    // integer number of items
105        for (n = 0; n < nwords; n++) 
106        {
107            mwmr->data[ptw] = buffer[n];
108            if ((ptw + 1) == depth) ptw = 0;
109            else                    ptw = ptw + 1;
110        }
111        mwmr->sts = sts + nwords;
112        mwmr->ptw = ptw;
113
114#if GIET_DEBUG_USER_MWMR
115giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n",
116                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
117#endif
118
119        lock_release( &mwmr->lock );
120        return (nwords / width);
121    }
122} // end nb_mwmr_write()
123
124
125
126//////////////////////////////////////////////////
127unsigned int nb_mwmr_read( mwmr_channel_t * mwmr, 
128                           unsigned int *   buffer,
129                           unsigned int     items) 
130{
131
132#if GIET_DEBUG_USER_MWMR
133unsigned int    x;
134unsigned int    y;
135unsigned int    lpid;
136giet_proc_xyp( &x, &y, &lpid );
137giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] enters nb_mwmr_read()"
138                " : mwmr = %x / buffer = %x / items =  %d\n",
139                x, y, lpid, (unsigned int)mwmr, (unsigned int)buffer, items );
140#endif
141
142    unsigned int n;
143    unsigned int nwords; // requested transfer length (words)
144    unsigned int depth;  // channel depth (words)
145    unsigned int width;  // channel width (words)
146    unsigned int sts;    // channel sts   (words)
147    unsigned int ptr;    // channel ptr   (words)
148
149    if (items == 0) return 0;
150
151    // get the lock
152    lock_acquire( &mwmr->lock );
153
154    // access fifo status
155    depth  = mwmr->depth;
156    width  = mwmr->width;
157    sts    = mwmr->sts;
158    ptr    = mwmr->ptr;
159    nwords = width * items;
160
161    if (sts >= nwords) // transfer items, release lock and return
162    {
163        for (n = 0; n < nwords; n++) 
164        {
165            buffer[n] = mwmr->data[ptr];
166            if ((ptr + 1) == depth)  ptr = 0;
167            else                     ptr = ptr + 1;
168        }
169        mwmr->sts = mwmr->sts - nwords;
170        mwmr->ptr = ptr;
171
172#if GIET_DEBUG_USER_MWMR
173giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n",
174                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
175#endif
176
177        lock_release( &mwmr->lock );
178        return items;
179    }
180    else if (sts < width) // release lock and return
181    {
182
183#if GIET_DEBUG_USER_MWMR
184giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read nothing in fifo %x : sts = %d\n",
185                x, y, lpid, (unsigned int)mwmr, mwmr->sts );
186#endif
187
188        lock_release( &mwmr->lock );
189        return 0;
190    }
191    else // transfer as many items as possible, release lock and return
192    {
193        nwords = (sts / width) * width; // integer number of items
194        for (n = 0 ; n < nwords ; n++) 
195        {
196            buffer[n] = mwmr->data[ptr];
197            if ((ptr + 1) == depth)  ptr = 0;
198            else                     ptr = ptr + 1;
199        }
200        mwmr->sts = sts - nwords;
201        mwmr->ptr = ptr;
202
203#if GIET_DEBUG_USER_MWMR
204giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n",
205                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
206#endif
207
208        lock_release( &mwmr->lock );
209        return (nwords / width);
210    }
211} // nb_mwmr_read()
212
213
214
215////////////////////////////////////////
216void mwmr_write( mwmr_channel_t * mwmr, 
217                 unsigned int *   buffer, 
218                 unsigned int     items ) 
219{
220
221#if GIET_DEBUG_USER_MWMR
222unsigned int    x;
223unsigned int    y;
224unsigned int    lpid;
225giet_proc_xyp( &x, &y, &lpid );
226giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] enters mwmr_write()"
227                " : mwmr = %x / buffer = %x / items =  %d\n",
228                x, y, lpid, (unsigned int)mwmr, (unsigned int)buffer, items );
229#endif
230
231    unsigned int n;
232    unsigned int spaces; // number of empty slots (in words)
233    unsigned int nwords; // requested transfer length (in words)
234    unsigned int depth;  // channel depth (in words)
235    unsigned int width;  // channel width (in words)
236    unsigned int sts;    // channel sts
237    unsigned int ptw;    // channel ptw
238
239    if (items == 0)  return;
240
241    while (1) 
242    {
243        // get the lock
244        lock_acquire( &mwmr->lock );
245
246        // compute spaces and nwords
247        depth = mwmr->depth;
248        width = mwmr->width;
249        sts  = mwmr->sts;
250        ptw  = mwmr->ptw;
251        spaces = depth - sts;
252        nwords = width * items;
253
254        if (spaces >= nwords) // write nwords, release lock and return
255        {
256            for (n = 0; n < nwords; n++) 
257            {
258                mwmr->data[ptw] = buffer[n];
259                if ((ptw + 1) == depth)  ptw = 0; 
260                else                     ptw = ptw + 1;
261            }
262            mwmr->ptw = ptw;
263            mwmr->sts = sts + nwords;
264
265#if GIET_DEBUG_USER_MWMR
266giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n",
267                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
268#endif
269
270            lock_release( &mwmr->lock );
271            return;
272        }
273        else if (spaces < width) // release lock and retry           
274        {
275            lock_release( &mwmr->lock );
276        }
277        else // write as many items as possible, release lock and retry
278        {
279            nwords = (spaces / width) * width;  // integer number of items
280            for (n = 0; n < nwords; n++) 
281            {
282                mwmr->data[ptw] = buffer[n];
283                if ((ptw + 1) == depth)  ptw = 0; 
284                else                     ptw = ptw + 1;
285            }
286            mwmr->sts = sts + nwords;
287            mwmr->ptw = ptw;
288            buffer = buffer + nwords;
289            items = items - (nwords/width);
290
291#if GIET_DEBUG_USER_MWMR
292giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] writes %d words in fifo %x : sts = %d\n",
293                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
294#endif
295
296            lock_release( &mwmr->lock );
297        }
298
299        // we could deschedule before retry...
300        // giet_context_switch();
301    }
302} // end mwmr_write()
303
304
305//////////////////////////////////////
306void mwmr_read( mwmr_channel_t * mwmr, 
307                unsigned int *   buffer, 
308                unsigned int     items) 
309{
310
311#if GIET_DEBUG_USER_MWMR
312unsigned int    x;
313unsigned int    y;
314unsigned int    lpid;
315giet_proc_xyp( &x, &y, &lpid );
316giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] enters mwmr_read()"
317                " : mwmr = %x / buffer = %x / items =  %d\n",
318                x, y, lpid, (unsigned int)mwmr, (unsigned int)buffer, items );
319#endif
320
321    unsigned int n;
322    unsigned int nwords; // requested transfer length (in words)
323    unsigned int depth;  // channel depth (in words)
324    unsigned int width;  // channel width (in words)
325    unsigned int sts;    // channel sts
326    unsigned int ptr;    // channel ptr
327
328    if (items == 0) return;
329
330    while (1) 
331    {
332        // get the lock
333        lock_acquire( &mwmr->lock );
334
335        // compute nwords
336        depth  = mwmr->depth;
337        width  = mwmr->width;
338        sts    = mwmr->sts;
339        ptr    = mwmr->ptr;
340        nwords = width * items;
341
342        if (sts >= nwords) // read nwords, release lock and return
343        {
344            for (n = 0; n < nwords; n++) 
345            {
346                buffer[n] = mwmr->data[ptr];
347                if ((ptr + 1) == depth)  ptr = 0;
348                else                     ptr = ptr + 1;
349            }
350            mwmr->sts = mwmr->sts - nwords;
351            mwmr->ptr = ptr;
352
353#if GIET_DEBUG_USER_MWMR
354giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n",
355                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
356#endif
357
358            lock_release( &mwmr->lock );
359            return;
360        }
361        else if (sts < width) // release lock and retry
362        {
363            lock_release( &mwmr->lock );
364        }
365        else // read as many items as possible, release lock and retry
366        {   
367            nwords = (sts / width) * width; // integer number of items
368            for (n = 0; n < nwords; n++) 
369            {
370                buffer[n] = mwmr->data[ptr];
371                if ((ptr + 1) == depth) ptr = 0;
372                else                    ptr = ptr + 1;
373            }
374            mwmr->sts = sts - nwords;
375            mwmr->ptr = ptr;
376            buffer = buffer + nwords;
377            items = items - (nwords/width);
378
379#if GIET_DEBUG_USER_MWMR
380giet_shr_printf("\n[MWMR DEBUG] Proc[%d,%d,%d] read %d words in fifo %x : sts = %d\n",
381                x, y, lpid, nwords, (unsigned int)mwmr, mwmr->sts );
382#endif
383
384            lock_release( &mwmr->lock );
385        }
386
387        // we could deschedule before retry...
388        // giet_context_switch();
389    }
390} // end mwmr_read()
391
392
393// Local Variables:
394// tab-width: 4
395// c-basic-offset: 4
396// c-file-offsets:((innamespace . 0)(inline-open . 0))
397// indent-tabs-mode: nil
398// End:
399// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
400
Note: See TracBrowser for help on using the repository browser.