source: soft/giet_vm/giet_libs/user_lock.c @ 477

Last change on this file since 477 was 461, checked in by alain, 10 years ago

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.

  • Property svn:executable set to *
File size: 4.5 KB
RevLine 
[461]1//////////////////////////////////////////////////////////////////////////////////
2// File     : user_lock.c         
3// Date     : 01/12/2014
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The user_lock.c and user_lock.h files are part of the GIET-VM nano-kernel.
8///////////////////////////////////////////////////////////////////////////////////
9
10#include "user_lock.h"
11#include "giet_config.h"
12#include "stdio.h"
13
14//////////////////////////////////////////////////////////////////////////////////
15// This function uses LL/SC to make an atomic increment.
16//////////////////////////////////////////////////////////////////////////////////
17unsigned int atomic_increment( unsigned int*  ptr,
18                               unsigned int   increment )
19{
20    unsigned int value;
21
22    asm volatile (
23        "1234:                         \n"
24        "move $10,   %1                \n"   /* $10 <= ptr               */
25        "move $11,   %2                \n"   /* $11 <= increment         */
26        "ll   $12,   0($10)            \n"   /* $12 <= *ptr              */
27        "addu $13,   $11,    $12       \n"   /* $13 <= *ptr + increment  */
28        "sc   $13,   0($10)            \n"   /* M[ptr] <= new            */ 
29        "beqz $13,   1234b             \n"   /* retry if failure         */
30        "move %0,    $12               \n"   /* value <= *ptr if success */
31        : "=r" (value) 
32        : "r" (ptr), "r" (increment)
33        : "$10", "$11", "$12", "$13", "memory" );
34
35    return value;
36}
37
38///////////////////////////////////////////////////////////////////////////////////
39// This blocking function returns only when the lock has been taken.
40///////////////////////////////////////////////////////////////////////////////////
41void lock_acquire( user_lock_t* lock ) 
42{
43    // get next free slot index from user_lock
44    unsigned int ticket = atomic_increment( &lock->free, 1 );
45
46#if GIET_DEBUG_USER_LOCK
47unsigned int    x;
48unsigned int    y;
49unsigned int    lpid;
50giet_proc_xyp( &x, &y, &lpid );
51giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] get ticket = %d"
52                " for lock %x at cycle %d (current = %d / free = %d)\n",
53                x, y, lpid, ticket, 
54                (unsigned int)lock, giet_proctime(), lock->current, lock->free );
55#endif
56
57    // poll the current slot index
58    asm volatile("1793:                       \n"
59                 "lw   $10,  0(%0)            \n"
60                 "move $11,  %1               \n"
61                 "bne  $10,  $11,  1793b      \n"
62                 :
63                 : "r"(lock), "r"(ticket)
64                 : "$10", "$11" );
65               
66#if GIET_DEBUG_USER_LOCK
67giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] get lock %x"
68                " at cycle %d (current = %d / free = %d)\n",
69                x, y, lpid, (unsigned int)lock, 
70                giet_proctime(), lock->current, lock->free );
71#endif
72
73}
74
75//////////////////////////////////////////////////////////////////////////////
76// This function releases the lock.
77//////////////////////////////////////////////////////////////////////////////
78void lock_release( user_lock_t* lock ) 
79{
80    unsigned int current = lock->current;
81
82    if ( current == (GIET_LOCK_MAX_TICKET - 1) ) lock->current = 0;
83    else                                         lock->current = current + 1;
84
85#if GIET_DEBUG_USER_LOCK
86unsigned int    x;
87unsigned int    y;
88unsigned int    lpid;
89giet_proc_xyp( &x, &y, &lpid );
90giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] release lock %x"
91                " at cycle %d (current = %d / free = %d)\n",
92                x, y, lpid, (unsigned int)lock, 
93                giet_proctime(), lock->current, lock->free );
94#endif
95
96}
97
98//////////////////////////////////////////////////////////////////////////////
99// This function initializes the lock.
100//////////////////////////////////////////////////////////////////////////////
101void lock_init( user_lock_t* lock )
102{
103    lock->current = 0;
104    lock->free    = 0;
105
106#if GIET_DEBUG_USER_LOCK
107unsigned int    x;
108unsigned int    y;
109unsigned int    lpid;
110giet_proc_xyp( &x, &y, &lpid );
111giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] init lock %x"
112                " at cycle %d (current = %d / free = %d)\n",
113                x, y, lpid, (unsigned int)lock,
114                giet_proctime(), lock->current, lock->free );
115#endif
116
117}
118
119
120// Local Variables:
121// tab-width: 4
122// c-basic-offset: 4
123// c-file-offsets:((innamespace . 0)(inline-open . 0))
124// indent-tabs-mode: nil
125// End:
126// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
127
Note: See TracBrowser for help on using the repository browser.