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

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

Cosmetic: improve debug.

  • Property svn:executable set to *
File size: 11.8 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 );
[479]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 );
[461]55#endif
[258]56
[461]57    unsigned int n;
[258]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
[461]65    if (items == 0) return 0;
[258]66
67    // get the lock
[461]68    lock_acquire( &mwmr->lock );
[258]69
70    // access fifo status
[461]71    depth  = mwmr->depth;
72    width  = mwmr->width;
73    sts    = mwmr->sts;
74    ptw    = mwmr->ptw;
[258]75    spaces = depth - sts;
[461]76    nwords = width * items;
[258]77
[461]78    if (spaces >= nwords) // transfer items, release lock and return
[450]79    { 
[461]80        for (n = 0; n < nwords; n++) 
[450]81        {
[461]82            mwmr->data[ptw] = buffer[n];
[450]83            if ((ptw + 1) == depth)  ptw = 0; 
84            else                     ptw = ptw + 1;
[258]85        }
86        mwmr->sts = mwmr->sts + nwords;
87        mwmr->ptw = ptw;
[461]88
[468]89#if GIET_DEBUG_USER_MWMR
[461]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;
[258]96    }
[450]97    else if (spaces < width) // release lock and return
98    {
[461]99        lock_release( &mwmr->lock );
[258]100        return 0;
101    }
[450]102    else // transfer as many items as possible, release lock and return
103    {
[258]104        nwords = (spaces / width) * width;    // integer number of items
[461]105        for (n = 0; n < nwords; n++) 
[450]106        {
[461]107            mwmr->data[ptw] = buffer[n];
[450]108            if ((ptw + 1) == depth) ptw = 0;
109            else                    ptw = ptw + 1;
[258]110        }
111        mwmr->sts = sts + nwords;
112        mwmr->ptw = ptw;
[461]113
[468]114#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]120        return (nwords / width);
121    }
122} // end nb_mwmr_write()
123
124
[450]125
126//////////////////////////////////////////////////
127unsigned int nb_mwmr_read( mwmr_channel_t * mwmr, 
128                           unsigned int *   buffer,
[461]129                           unsigned int     items) 
[450]130{
131
[468]132#if GIET_DEBUG_USER_MWMR
[461]133unsigned int    x;
134unsigned int    y;
135unsigned int    lpid;
136giet_proc_xyp( &x, &y, &lpid );
[479]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 );
[461]140#endif
[450]141
[461]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
[450]151    // get the lock
[461]152    lock_acquire( &mwmr->lock );
[450]153
154    // access fifo status
[461]155    depth  = mwmr->depth;
156    width  = mwmr->width;
157    sts    = mwmr->sts;
158    ptr    = mwmr->ptr;
159    nwords = width * items;
[450]160
[461]161    if (sts >= nwords) // transfer items, release lock and return
[450]162    {
[461]163        for (n = 0; n < nwords; n++) 
[450]164        {
[461]165            buffer[n] = mwmr->data[ptr];
[450]166            if ((ptr + 1) == depth)  ptr = 0;
167            else                     ptr = ptr + 1;
168        }
169        mwmr->sts = mwmr->sts - nwords;
170        mwmr->ptr = ptr;
[461]171
[468]172#if GIET_DEBUG_USER_MWMR
[461]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;
[450]179    }
180    else if (sts < width) // release lock and return
181    {
[461]182
[468]183#if GIET_DEBUG_USER_MWMR
[461]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 );
[450]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
[461]194        for (n = 0 ; n < nwords ; n++) 
[450]195        {
[461]196            buffer[n] = mwmr->data[ptr];
[450]197            if ((ptr + 1) == depth)  ptr = 0;
198            else                     ptr = ptr + 1;
199        }
200        mwmr->sts = sts - nwords;
201        mwmr->ptr = ptr;
[461]202
[468]203#if GIET_DEBUG_USER_MWMR
[461]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 );
[450]209        return (nwords / width);
210    }
211} // nb_mwmr_read()
212
213
214
215////////////////////////////////////////
216void mwmr_write( mwmr_channel_t * mwmr, 
217                 unsigned int *   buffer, 
[461]218                 unsigned int     items ) 
[450]219{
[461]220
[468]221#if GIET_DEBUG_USER_MWMR
[461]222unsigned int    x;
223unsigned int    y;
224unsigned int    lpid;
225giet_proc_xyp( &x, &y, &lpid );
[479]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 );
[461]229#endif
230
231    unsigned int n;
[258]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
[461]239    if (items == 0)  return;
[258]240
[450]241    while (1) 
242    {
[258]243        // get the lock
[461]244        lock_acquire( &mwmr->lock );
[258]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;
[461]252        nwords = width * items;
[258]253
[450]254        if (spaces >= nwords) // write nwords, release lock and return
255        {
[461]256            for (n = 0; n < nwords; n++) 
[450]257            {
[461]258                mwmr->data[ptw] = buffer[n];
[450]259                if ((ptw + 1) == depth)  ptw = 0; 
260                else                     ptw = ptw + 1;
[258]261            }
262            mwmr->ptw = ptw;
263            mwmr->sts = sts + nwords;
[461]264
[468]265#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]271            return;
272        }
[461]273        else if (spaces < width) // release lock and retry           
[450]274        {
[461]275            lock_release( &mwmr->lock );
[258]276        }
[461]277        else // write as many items as possible, release lock and retry
[450]278        {
[258]279            nwords = (spaces / width) * width;  // integer number of items
[461]280            for (n = 0; n < nwords; n++) 
[450]281            {
[461]282                mwmr->data[ptw] = buffer[n];
[450]283                if ((ptw + 1) == depth)  ptw = 0; 
284                else                     ptw = ptw + 1;
[258]285            }
286            mwmr->sts = sts + nwords;
287            mwmr->ptw = ptw;
288            buffer = buffer + nwords;
[461]289            items = items - (nwords/width);
290
[468]291#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]297        }
[461]298
299        // we could deschedule before retry...
300        // giet_context_switch();
[258]301    }
302} // end mwmr_write()
303
304
[450]305//////////////////////////////////////
306void mwmr_read( mwmr_channel_t * mwmr, 
307                unsigned int *   buffer, 
[461]308                unsigned int     items) 
[450]309{
[461]310
[468]311#if GIET_DEBUG_USER_MWMR
[461]312unsigned int    x;
313unsigned int    y;
314unsigned int    lpid;
315giet_proc_xyp( &x, &y, &lpid );
[479]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 );
[461]319#endif
320
321    unsigned int n;
[258]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
[461]328    if (items == 0) return;
[258]329
[450]330    while (1) 
331    {
[258]332        // get the lock
[461]333        lock_acquire( &mwmr->lock );
[258]334
335        // compute nwords
[461]336        depth  = mwmr->depth;
337        width  = mwmr->width;
338        sts    = mwmr->sts;
339        ptr    = mwmr->ptr;
340        nwords = width * items;
[258]341
[450]342        if (sts >= nwords) // read nwords, release lock and return
343        {
[461]344            for (n = 0; n < nwords; n++) 
[450]345            {
[461]346                buffer[n] = mwmr->data[ptr];
[450]347                if ((ptr + 1) == depth)  ptr = 0;
348                else                     ptr = ptr + 1;
[258]349            }
350            mwmr->sts = mwmr->sts - nwords;
351            mwmr->ptr = ptr;
[461]352
[468]353#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]359            return;
360        }
[461]361        else if (sts < width) // release lock and retry
[450]362        {
[461]363            lock_release( &mwmr->lock );
[258]364        }
[461]365        else // read as many items as possible, release lock and retry
[450]366        {   
[258]367            nwords = (sts / width) * width; // integer number of items
[461]368            for (n = 0; n < nwords; n++) 
[450]369            {
[461]370                buffer[n] = mwmr->data[ptr];
[450]371                if ((ptr + 1) == depth) ptr = 0;
372                else                    ptr = ptr + 1;
[258]373            }
374            mwmr->sts = sts - nwords;
375            mwmr->ptr = ptr;
376            buffer = buffer + nwords;
[461]377            items = items - (nwords/width);
378
[468]379#if GIET_DEBUG_USER_MWMR
[461]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 );
[258]385        }
[461]386
387        // we could deschedule before retry...
388        // giet_context_switch();
[258]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.