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

Last change on this file since 476 was 468, checked in by alain, 10 years ago

Cosmetic: Improving debug.

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