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

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

Cosmetic: Improving debug.

  • Property svn:executable set to *
File size: 11.0 KB
RevLine 
[258]1//////////////////////////////////////////////////////////////////////////////////
[450]2// File     : mwmr_channel.c         
[258]3// Date     : 01/04/2012
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
[461]8#include "mwmr_channel.h"
9#include "giet_config.h"
10#include "stdio.h"
11#include "user_lock.h"
[258]12
[450]13//////////////////////////////////////
14void mwmr_init( mwmr_channel_t*  mwmr,
[461]15                unsigned int*    buffer,     // buffer base address
16                unsigned int     width,      // number of words per item
17                unsigned int     nitems )    // max number of items
[450]18{
19
[468]20#if GIET_DEBUG_USER_MWMR
[461]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
[450]30    mwmr->ptw   = 0;
31    mwmr->ptr   = 0;
32    mwmr->sts   = 0;
33    mwmr->width = width;
[461]34    mwmr->depth = width * nitems;
35    mwmr->data  = buffer;
[450]36
[461]37    lock_init( &mwmr->lock );
[450]38}
39
40
41///////////////////////////////////////////////////
[461]42unsigned int nb_mwmr_write( mwmr_channel_t * mwmr, 
43                            unsigned int *   buffer, 
44                            unsigned int     items)
[450]45{
[258]46
[468]47#if GIET_DEBUG_USER_MWMR
[461]48unsigned int    x;
49unsigned int    y;
50unsigned int    lpid;
51giet_proc_xyp( &x, &y, &lpid );
52#endif
[258]53
[461]54    unsigned int n;
[258]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
[461]62    if (items == 0) return 0;
[258]63
64    // get the lock
[461]65    lock_acquire( &mwmr->lock );
[258]66
67    // access fifo status
[461]68    depth  = mwmr->depth;
69    width  = mwmr->width;
70    sts    = mwmr->sts;
71    ptw    = mwmr->ptw;
[258]72    spaces = depth - sts;
[461]73    nwords = width * items;
[258]74
[461]75    if (spaces >= nwords) // transfer items, release lock and return
[450]76    { 
[461]77        for (n = 0; n < nwords; n++) 
[450]78        {
[461]79            mwmr->data[ptw] = buffer[n];
[450]80            if ((ptw + 1) == depth)  ptw = 0; 
81            else                     ptw = ptw + 1;
[258]82        }
83        mwmr->sts = mwmr->sts + nwords;
84        mwmr->ptw = ptw;
[461]85
[468]86#if GIET_DEBUG_USER_MWMR
[461]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;
[258]93    }
[450]94    else if (spaces < width) // release lock and return
95    {
[461]96        lock_release( &mwmr->lock );
[258]97        return 0;
98    }
[450]99    else // transfer as many items as possible, release lock and return
100    {
[258]101        nwords = (spaces / width) * width;    // integer number of items
[461]102        for (n = 0; n < nwords; n++) 
[450]103        {
[461]104            mwmr->data[ptw] = buffer[n];
[450]105            if ((ptw + 1) == depth) ptw = 0;
106            else                    ptw = ptw + 1;
[258]107        }
108        mwmr->sts = sts + nwords;
109        mwmr->ptw = ptw;
[461]110
[468]111#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]117        return (nwords / width);
118    }
119} // end nb_mwmr_write()
120
121
[450]122
123//////////////////////////////////////////////////
124unsigned int nb_mwmr_read( mwmr_channel_t * mwmr, 
125                           unsigned int *   buffer,
[461]126                           unsigned int     items) 
[450]127{
128
[468]129#if GIET_DEBUG_USER_MWMR
[461]130unsigned int    x;
131unsigned int    y;
132unsigned int    lpid;
133giet_proc_xyp( &x, &y, &lpid );
134#endif
[450]135
[461]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
[450]145    // get the lock
[461]146    lock_acquire( &mwmr->lock );
[450]147
148    // access fifo status
[461]149    depth  = mwmr->depth;
150    width  = mwmr->width;
151    sts    = mwmr->sts;
152    ptr    = mwmr->ptr;
153    nwords = width * items;
[450]154
[461]155    if (sts >= nwords) // transfer items, release lock and return
[450]156    {
[461]157        for (n = 0; n < nwords; n++) 
[450]158        {
[461]159            buffer[n] = mwmr->data[ptr];
[450]160            if ((ptr + 1) == depth)  ptr = 0;
161            else                     ptr = ptr + 1;
162        }
163        mwmr->sts = mwmr->sts - nwords;
164        mwmr->ptr = ptr;
[461]165
[468]166#if GIET_DEBUG_USER_MWMR
[461]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;
[450]173    }
174    else if (sts < width) // release lock and return
175    {
[461]176
[468]177#if GIET_DEBUG_USER_MWMR
[461]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 );
[450]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
[461]188        for (n = 0 ; n < nwords ; n++) 
[450]189        {
[461]190            buffer[n] = mwmr->data[ptr];
[450]191            if ((ptr + 1) == depth)  ptr = 0;
192            else                     ptr = ptr + 1;
193        }
194        mwmr->sts = sts - nwords;
195        mwmr->ptr = ptr;
[461]196
[468]197#if GIET_DEBUG_USER_MWMR
[461]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 );
[450]203        return (nwords / width);
204    }
205} // nb_mwmr_read()
206
207
208
209////////////////////////////////////////
210void mwmr_write( mwmr_channel_t * mwmr, 
211                 unsigned int *   buffer, 
[461]212                 unsigned int     items ) 
[450]213{
[461]214
[468]215#if GIET_DEBUG_USER_MWMR
[461]216unsigned int    x;
217unsigned int    y;
218unsigned int    lpid;
219giet_proc_xyp( &x, &y, &lpid );
220#endif
221
222    unsigned int n;
[258]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
[461]230    if (items == 0)  return;
[258]231
[450]232    while (1) 
233    {
[258]234        // get the lock
[461]235        lock_acquire( &mwmr->lock );
[258]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;
[461]243        nwords = width * items;
[258]244
[450]245        if (spaces >= nwords) // write nwords, release lock and return
246        {
[461]247            for (n = 0; n < nwords; n++) 
[450]248            {
[461]249                mwmr->data[ptw] = buffer[n];
[450]250                if ((ptw + 1) == depth)  ptw = 0; 
251                else                     ptw = ptw + 1;
[258]252            }
253            mwmr->ptw = ptw;
254            mwmr->sts = sts + nwords;
[461]255
[468]256#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]262            return;
263        }
[461]264        else if (spaces < width) // release lock and retry           
[450]265        {
[461]266            lock_release( &mwmr->lock );
[258]267        }
[461]268        else // write as many items as possible, release lock and retry
[450]269        {
[258]270            nwords = (spaces / width) * width;  // integer number of items
[461]271            for (n = 0; n < nwords; n++) 
[450]272            {
[461]273                mwmr->data[ptw] = buffer[n];
[450]274                if ((ptw + 1) == depth)  ptw = 0; 
275                else                     ptw = ptw + 1;
[258]276            }
277            mwmr->sts = sts + nwords;
278            mwmr->ptw = ptw;
279            buffer = buffer + nwords;
[461]280            items = items - (nwords/width);
281
[468]282#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]288        }
[461]289
290        // we could deschedule before retry...
291        // giet_context_switch();
[258]292    }
293} // end mwmr_write()
294
295
[450]296//////////////////////////////////////
297void mwmr_read( mwmr_channel_t * mwmr, 
298                unsigned int *   buffer, 
[461]299                unsigned int     items) 
[450]300{
[461]301
[468]302#if GIET_DEBUG_USER_MWMR
[461]303unsigned int    x;
304unsigned int    y;
305unsigned int    lpid;
306giet_proc_xyp( &x, &y, &lpid );
307#endif
308
309    unsigned int n;
[258]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
[461]316    if (items == 0) return;
[258]317
[450]318    while (1) 
319    {
[258]320        // get the lock
[461]321        lock_acquire( &mwmr->lock );
[258]322
323        // compute nwords
[461]324        depth  = mwmr->depth;
325        width  = mwmr->width;
326        sts    = mwmr->sts;
327        ptr    = mwmr->ptr;
328        nwords = width * items;
[258]329
[450]330        if (sts >= nwords) // read nwords, release lock and return
331        {
[461]332            for (n = 0; n < nwords; n++) 
[450]333            {
[461]334                buffer[n] = mwmr->data[ptr];
[450]335                if ((ptr + 1) == depth)  ptr = 0;
336                else                     ptr = ptr + 1;
[258]337            }
338            mwmr->sts = mwmr->sts - nwords;
339            mwmr->ptr = ptr;
[461]340
[468]341#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]347            return;
348        }
[461]349        else if (sts < width) // release lock and retry
[450]350        {
[461]351            lock_release( &mwmr->lock );
[258]352        }
[461]353        else // read as many items as possible, release lock and retry
[450]354        {   
[258]355            nwords = (sts / width) * width; // integer number of items
[461]356            for (n = 0; n < nwords; n++) 
[450]357            {
[461]358                buffer[n] = mwmr->data[ptr];
[450]359                if ((ptr + 1) == depth) ptr = 0;
360                else                    ptr = ptr + 1;
[258]361            }
362            mwmr->sts = sts - nwords;
363            mwmr->ptr = ptr;
364            buffer = buffer + nwords;
[461]365            items = items - (nwords/width);
366
[468]367#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]373        }
[461]374
375        // we could deschedule before retry...
376        // giet_context_switch();
[258]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.