source: soft/giet_vm/giet_common/locks.c @ 465

Last change on this file since 465 was 455, checked in by alain, 10 years ago

Introducing the tty0.c/tty0.h files defining access function to TTY0 (including the _printf().
Introducing the locks.c/locks.h files defining two types of spin-lock (with and without a waiting queue).

File size: 5.4 KB
Line 
1///////////////////////////////////////////////////////////////////////////////////
2// File     : locks.c
3// Date     : 01/12/2014
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7
8#include "locks.h"
9#include "giet_config.h"
10#include "utils.h"
11
12///////////////////////////////////////////////////
13unsigned int _atomic_increment( unsigned int* ptr,
14                                unsigned int  increment )
15{
16    unsigned int value;
17
18    asm volatile (
19        "1234:                         \n"
20        "move $10,   %1                \n"   /* $10 <= ptr               */
21        "move $11,   %2                \n"   /* $11 <= increment         */
22        "ll   $12,   0($10)            \n"   /* $12 <= *ptr              */
23        "addu $13,   $11,    $12       \n"   /* $13 <= *ptr + increment  */
24        "sc   $13,   0($10)            \n"   /* M[ptr] <= new            */ 
25        "beqz $13,   1234b             \n"   /* retry if failure         */
26        "move %0,    $12               \n"   /* value <= *ptr if success */
27        : "=r" (value) 
28        : "r" (ptr), "r" (increment)
29        : "$10", "$11", "$12", "$13", "memory" );
30
31    return value;
32}
33
34////////////////////////////////////
35void _lock_init( spin_lock_t* lock )
36{
37    lock->current = 0;
38    lock->free    = 0;
39
40#if GIET_DEBUG_SYS_LOCK
41unsigned int    gpid = _get_procid();
42unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
43unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
44unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
45_printf("\n[SYS_LOCK DEBUG] P[%d,%d,%d] init lock %x"
46                " at cycle %d (current = %d / free = %d)\n",
47                x, y, l, (unsigned int)lock, 
48                _get_proctime(), lock->current, lock->free );
49#endif
50
51}
52
53
54////////////////////////////////////////
55void _lock_acquire( spin_lock_t* lock )
56{
57    // get next free slot index fromlock
58    unsigned int ticket = _atomic_increment( &lock->free, 1 );
59
60#if GIET_DEBUG_SYS_LOCK
61unsigned int    gpid = _get_procid();
62unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
63unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
64unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
65_printf("\n[SYS_LOCK DEBUG] P[%d,%d,%d] get ticket = %d"
66                " for lock %x at cycle %d (current = %d / free = %d)\n",
67                x, y, l, ticket, 
68                (unsigned int)lock, _get_proctime(), lock->current, lock->free );
69#endif
70
71
72    // poll the spin_lock current slot index
73    asm volatile("5678:                   \n"
74                 "lw   $10,  0(%0)        \n"
75                 "move $11,  %1           \n"
76                 "bne  $10,  $11,  5678b  \n"
77                 :
78                 : "r"(lock), "r"(ticket)
79                 : "$10", "$11" );
80
81#if GIET_DEBUG_SYS_LOCK
82_printf("\n[SYS_LOCK DEBUG] P[%d,%d,%d] get lock = %x"
83                " at cycle %d (current = %d / free = %d)\n",
84                x, y, l, (unsigned int)lock, 
85                _get_proctime(), lock->current, lock->free );
86#endif
87
88}
89
90////////////////////////////////////////
91void _lock_release( spin_lock_t* lock )
92{
93    unsigned int current = lock->current;
94
95    if ( current == (GIET_LOCK_MAX_TICKET - 1) ) current = 0;
96    else                                         current = current + 1;
97
98    asm volatile ( "sync                    \n"   /* for consistency                  */
99                   "sw   %1,    0(%0)       \n"   /* release lock                     */
100                   :
101                   : "r"(lock), "r"(current)
102                   : "memory" );
103   
104
105#if GIET_DEBUG_SYS_LOCK
106unsigned int    gpid = _get_procid();
107unsigned int    x    = gpid >> (Y_WIDTH + P_WIDTH);
108unsigned int    y    = (gpid >> P_WIDTH) & ((1<<Y_WIDTH)-1);
109unsigned int    l    = gpid & ((1<<P_WIDTH)-1);
110_printf("\n[SYS_LOCK DEBUG] P[%d,%d,%d] release lock = %x"
111                " at cycle %d (current = %d / free = %d)\n",
112                x, y, l, (unsigned int)lock, 
113                _get_proctime(), lock->current, lock->free );
114#endif
115
116}
117
118
119
120
121
122
123
124
125////////////////////////////////////////////////
126void _simple_lock_acquire( simple_lock_t* lock )
127{
128    asm volatile ( "1515:                   \n"
129                       "lw   $2,    0(%0)       \n"   /* $2 <= lock current value         */
130                       "bnez $2,    1515b       \n"   /* retry if lock already taken      */
131                   "ll   $2,    0(%0)       \n"   /* ll_buffer <= lock current value  */
132                   "bnez $2,    1515b       \n"   /* retry if lock already taken      */
133                   "li   $3,    1           \n"   /* $3 <= argument for sc            */
134                   "sc   $3,    0(%0)       \n"   /* try to set lock                  */
135                   "beqz $3,    1515b       \n"   /* retry if sc failure              */
136                   :
137                   : "r"(lock)
138                   : "$2", "$3", "memory" );
139}
140
141////////////////////////////////////////////////
142void _simple_lock_release( simple_lock_t* lock )
143{
144    asm volatile ( "sync                    \n"   /* for consistency                  */
145                   "sw   $0,    0(%0)       \n"   /* release lock                     */
146                   :
147                   : "r"(lock)
148                   : "memory" );
149}
150
151
152// Local Variables:
153// tab-width: 4
154// c-basic-offset: 4
155// c-file-offsets:((innamespace . 0)(inline-open . 0))
156// indent-tabs-mode: nil
157// End:
158// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
159
Note: See TracBrowser for help on using the repository browser.