Ignore:
Timestamp:
Dec 5, 2014, 4:02:27 PM (10 years ago)
Author:
alain
Message:

1) replace the "giet_locks.c" library by the "user_lock.c" library (the new library uses a ticket allocator).
2) introduce new syscalls in the stdio.c file, to support the NIC peripheral.
3) modify the MWMR library to use the lock with ticket allocator, and to separate the fifo descriptor and the data buffer.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • soft/giet_vm/giet_libs/mwmr_channel.c

    r450 r461  
    66///////////////////////////////////////////////////////////////////////////////////
    77
    8 #include <mwmr_channel.h>
    9 #include <stdio.h>
     8#include "mwmr_channel.h"
     9#include "giet_config.h"
     10#include "stdio.h"
     11#include "user_lock.h"
    1012
    1113//////////////////////////////////////
    1214void mwmr_init( mwmr_channel_t*  mwmr,
    13                 unsigned int     width,      // numer of words per item
    14                 unsigned int     items )     // max number of items
    15 {
    16     if ( ((items * width)) > 1018 )
    17     giet_exit("[MWMR ERROR] in mwmr_init() : buffer size larger than 4072 bytes\n");
     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_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
    1829
    1930    mwmr->ptw   = 0;
     
    2132    mwmr->sts   = 0;
    2233    mwmr->width = width;
    23     mwmr->depth = width * items;
    24     mwmr->lock  = 0;
    25 
    26 #if GIET_DEBUG_MWMR
    27 giet_shr_printf("[MWMR DEBUG] Initialise MWMR channel\n"
    28                 " - vbase = %x\n"
    29                 " - width = %d\n"
    30                 " - depth = %d\n",
    31                 (unsigned int)mwmr, width, items );
    32 #endif
     34    mwmr->depth = width * nitems;
     35    mwmr->data  = buffer;
     36
     37    lock_init( &mwmr->lock );
    3338}
    34 
    35 
    36 ///////////////////////////////////////////////////
    37 static void mwmr_lock_acquire( unsigned int* lock )
    38 {
    39     register unsigned int*  plock = lock;
    40     register unsigned int   delay = 100;
    41     asm volatile (
    42             "1:                               \n"
    43             "ll   $2,    0(%0)                \n" /* $2 <= lock current value */
    44             "bnez $2,    2f                   \n" /* retry after delay if lock busy */
    45             "li   $3,    1                    \n" /* $3 <= argument for sc */
    46             "sc   $3,    0(%0)                \n" /* try to get lock */
    47             "bnez $3,    3f                   \n" /* exit if atomic */
    48             "2:                               \n"
    49             "move $4,    %1                   \n" /* $4 <= delay */
    50             "4:                               \n"
    51             "beqz $4,    4b                   \n" /* test end delay */
    52             "addi $4,    $4,  -1              \n" /* $4 <= $4 - 1 */
    53             "j           1b                   \n" /* retry ll */
    54             "nop                              \n"
    55             "3:                               \n"
    56             :
    57             :"r"(plock), "r"(delay)
    58             :"$2", "$3", "$4");
    59 }
    6039
    6140
    6241///////////////////////////////////////////////////
    6342unsigned int nb_mwmr_write( mwmr_channel_t * mwmr,
    64                             unsigned int * buffer,
    65                             unsigned int nitems)
    66 {
    67     unsigned int x;
     43                            unsigned int *   buffer,
     44                            unsigned int     items)
     45{
     46
     47#if GIET_DEBUG_MWMR
     48unsigned int    x;
     49unsigned int    y;
     50unsigned int    lpid;
     51giet_proc_xyp( &x, &y, &lpid );
     52#endif
     53
     54    unsigned int n;
    6855    unsigned int spaces; // number of empty slots (in words)
    6956    unsigned int nwords; // requested transfer length (in words)
     
    7360    unsigned int ptw;    // channel ptw
    7461
    75     if (nitems == 0) return 0;
     62    if (items == 0) return 0;
    7663
    7764    // get the lock
    78     mwmr_lock_acquire(&mwmr->lock);
     65    lock_acquire( &mwmr->lock );
    7966
    8067    // access fifo status
    81     depth = mwmr->depth;
    82     width = mwmr->width;
    83     sts = mwmr->sts;
    84     ptw = mwmr->ptw;
     68    depth  = mwmr->depth;
     69    width  = mwmr->width;
     70    sts    = mwmr->sts;
     71    ptw    = mwmr->ptw;
    8572    spaces = depth - sts;
    86     nwords = width * nitems;
    87 
    88     if (spaces >= nwords) // transfer nitems, release lock and return
     73    nwords = width * items;
     74
     75    if (spaces >= nwords) // transfer items, release lock and return
    8976    {
    90         for (x = 0; x < nwords; x++)
    91         {
    92             mwmr->data[ptw] = buffer[x];
     77        for (n = 0; n < nwords; n++)
     78        {
     79            mwmr->data[ptw] = buffer[n];
    9380            if ((ptw + 1) == depth)  ptw = 0;
    9481            else                     ptw = ptw + 1;
     
    9683        mwmr->sts = mwmr->sts + nwords;
    9784        mwmr->ptw = ptw;
    98         mwmr->lock = 0;
    99         return nitems;
     85
     86#if GIET_DEBUG_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;
    10093    }
    10194    else if (spaces < width) // release lock and return
    10295    {
    103         mwmr->lock = 0;
     96        lock_release( &mwmr->lock );
    10497        return 0;
    10598    }
     
    107100    {
    108101        nwords = (spaces / width) * width;    // integer number of items
    109         for (x = 0; x < nwords; x++)
    110         {
    111             mwmr->data[ptw] = buffer[x];
     102        for (n = 0; n < nwords; n++)
     103        {
     104            mwmr->data[ptw] = buffer[n];
    112105            if ((ptw + 1) == depth) ptw = 0;
    113106            else                    ptw = ptw + 1;
     
    115108        mwmr->sts = sts + nwords;
    116109        mwmr->ptw = ptw;
    117         mwmr->lock = 0;
     110
     111#if GIET_DEBUG_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 );
    118117        return (nwords / width);
    119118    }
     
    125124unsigned int nb_mwmr_read( mwmr_channel_t * mwmr,
    126125                           unsigned int *   buffer,
    127                            unsigned int     nitems)
    128 {
    129     unsigned int x;
    130     unsigned int nwords; // requested transfer length (in words)
    131     unsigned int depth;  // channel depth (in words)
    132     unsigned int width;  // channel width (in words)
    133     unsigned int sts;    // channel sts
    134     unsigned int ptr;    // channel ptr
    135 
    136     if (nitems == 0) return 0;
     126                           unsigned int     items)
     127{
     128
     129#if GIET_DEBUG_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;
    137144
    138145    // get the lock
    139     mwmr_lock_acquire(&mwmr->lock);
     146    lock_acquire( &mwmr->lock );
    140147
    141148    // access fifo status
    142     depth = mwmr->depth;
    143     width = mwmr->width;
    144     sts = mwmr->sts;
    145     ptr = mwmr->ptr;
    146     nwords = width * nitems;
    147 
    148     if (sts >= nwords) // transfer nitems, release lock and return
    149     {
    150         for (x = 0; x < nwords; x++)
    151         {
    152             buffer[x] = mwmr->data[ptr];
     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];
    153160            if ((ptr + 1) == depth)  ptr = 0;
    154161            else                     ptr = ptr + 1;
     
    156163        mwmr->sts = mwmr->sts - nwords;
    157164        mwmr->ptr = ptr;
    158         mwmr->lock = 0;
    159         return nitems;
     165
     166#if GIET_DEBUG_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;
    160173    }
    161174    else if (sts < width) // release lock and return
    162175    {
    163         mwmr->lock = 0;
     176
     177#if GIET_DEBUG_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 );
    164183        return 0;
    165184    }
     
    167186    {
    168187        nwords = (sts / width) * width; // integer number of items
    169         for (x = 0 ; x < nwords ; x++)
    170         {
    171             buffer[x] = mwmr->data[ptr];
     188        for (n = 0 ; n < nwords ; n++)
     189        {
     190            buffer[n] = mwmr->data[ptr];
    172191            if ((ptr + 1) == depth)  ptr = 0;
    173192            else                     ptr = ptr + 1;
     
    175194        mwmr->sts = sts - nwords;
    176195        mwmr->ptr = ptr;
    177         mwmr->lock = 0;
     196
     197#if GIET_DEBUG_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 );
    178203        return (nwords / width);
    179204    }
     
    185210void mwmr_write( mwmr_channel_t * mwmr,
    186211                 unsigned int *   buffer,
    187                  unsigned int     nitems )
    188 {
    189     unsigned int x;
     212                 unsigned int     items )
     213{
     214
     215#if GIET_DEBUG_MWMR
     216unsigned int    x;
     217unsigned int    y;
     218unsigned int    lpid;
     219giet_proc_xyp( &x, &y, &lpid );
     220#endif
     221
     222    unsigned int n;
    190223    unsigned int spaces; // number of empty slots (in words)
    191224    unsigned int nwords; // requested transfer length (in words)
     
    195228    unsigned int ptw;    // channel ptw
    196229
    197     if (nitems == 0)  return;
     230    if (items == 0)  return;
    198231
    199232    while (1)
    200233    {
    201234        // get the lock
    202         mwmr_lock_acquire(&mwmr->lock);
     235        lock_acquire( &mwmr->lock );
    203236
    204237        // compute spaces and nwords
     
    208241        ptw  = mwmr->ptw;
    209242        spaces = depth - sts;
    210         nwords = width * nitems;
     243        nwords = width * items;
    211244
    212245        if (spaces >= nwords) // write nwords, release lock and return
    213246        {
    214             for (x = 0; x < nwords; x++)
     247            for (n = 0; n < nwords; n++)
    215248            {
    216                 mwmr->data[ptw] = buffer[x];
     249                mwmr->data[ptw] = buffer[n];
    217250                if ((ptw + 1) == depth)  ptw = 0;
    218251                else                     ptw = ptw + 1;
     
    220253            mwmr->ptw = ptw;
    221254            mwmr->sts = sts + nwords;
    222             mwmr->lock = 0;
     255
     256#if GIET_DEBUG_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 );
    223262            return;
    224263        }
    225         else if (spaces < width) // release lock and deschedule           
    226         {
    227             mwmr->lock = 0;
    228         }
    229         else // write as many items as possible, release lock and deschedule
     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
    230269        {
    231270            nwords = (spaces / width) * width;  // integer number of items
    232             for (x = 0; x < nwords; x++)
     271            for (n = 0; n < nwords; n++)
    233272            {
    234                 mwmr->data[ptw] = buffer[x];
     273                mwmr->data[ptw] = buffer[n];
    235274                if ((ptw + 1) == depth)  ptw = 0;
    236275                else                     ptw = ptw + 1;
     
    239278            mwmr->ptw = ptw;
    240279            buffer = buffer + nwords;
    241             nitems = nitems - (nwords/width);
    242             mwmr->lock = 0;
    243         }
    244         giet_context_switch();
     280            items = items - (nwords/width);
     281
     282#if GIET_DEBUG_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();
    245292    }
    246293} // end mwmr_write()
     
    250297void mwmr_read( mwmr_channel_t * mwmr,
    251298                unsigned int *   buffer,
    252                 unsigned int     nitems)
    253 {
    254     unsigned int x;
     299                unsigned int     items)
     300{
     301
     302#if GIET_DEBUG_MWMR
     303unsigned int    x;
     304unsigned int    y;
     305unsigned int    lpid;
     306giet_proc_xyp( &x, &y, &lpid );
     307#endif
     308
     309    unsigned int n;
    255310    unsigned int nwords; // requested transfer length (in words)
    256311    unsigned int depth;  // channel depth (in words)
     
    259314    unsigned int ptr;    // channel ptr
    260315
    261     if (nitems == 0) return;
     316    if (items == 0) return;
    262317
    263318    while (1)
    264319    {
    265320        // get the lock
    266         mwmr_lock_acquire(&mwmr->lock);
     321        lock_acquire( &mwmr->lock );
    267322
    268323        // compute nwords
    269         depth = mwmr->depth;
    270         width = mwmr->width;
    271         sts = mwmr->sts;
    272         ptr = mwmr->ptr;
    273         nwords = width * nitems;
     324        depth  = mwmr->depth;
     325        width  = mwmr->width;
     326        sts    = mwmr->sts;
     327        ptr    = mwmr->ptr;
     328        nwords = width * items;
    274329
    275330        if (sts >= nwords) // read nwords, release lock and return
    276331        {
    277             for (x = 0; x < nwords; x++)
     332            for (n = 0; n < nwords; n++)
    278333            {
    279                 buffer[x] = mwmr->data[ptr];
     334                buffer[n] = mwmr->data[ptr];
    280335                if ((ptr + 1) == depth)  ptr = 0;
    281336                else                     ptr = ptr + 1;
     
    283338            mwmr->sts = mwmr->sts - nwords;
    284339            mwmr->ptr = ptr;
    285             mwmr->lock = 0;
     340
     341#if GIET_DEBUG_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 );
    286347            return;
    287348        }
    288         else if (sts < width) // release lock and deschedule
    289         {
    290             mwmr->lock = 0;
    291         }
    292         else // read as many items as possible, release lock and deschedule
     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
    293354        {   
    294355            nwords = (sts / width) * width; // integer number of items
    295             for (x = 0; x < nwords; x++)
     356            for (n = 0; n < nwords; n++)
    296357            {
    297                 buffer[x] = mwmr->data[ptr];
     358                buffer[n] = mwmr->data[ptr];
    298359                if ((ptr + 1) == depth) ptr = 0;
    299360                else                    ptr = ptr + 1;
     
    302363            mwmr->ptr = ptr;
    303364            buffer = buffer + nwords;
    304             nitems = nitems - (nwords/width);
    305             mwmr->lock = 0;
    306         }
    307         giet_context_switch();
     365            items = items - (nwords/width);
     366
     367#if GIET_DEBUG_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();
    308377    }
    309378} // end mwmr_read()
Note: See TracChangeset for help on using the changeset viewer.