source: soft/giet_vm/giet_libs/user_sqt_lock.c @ 693

Last change on this file since 693 was 693, checked in by guerin, 9 years ago

remove last references to giet_shr_printf()

File size: 9.1 KB
Line 
1
2#include "stdio.h"
3#include "malloc.h"
4#include "giet_config.h"
5#include "user_lock.h"
6#include "user_sqt_lock.h"
7
8static 
9void sqt_lock_build( sqt_lock_t*      lock,      // pointer on the SQT lock
10                      unsigned int     x,         // node X coordinate
11                      unsigned int     y,         // node Y coordinate
12                      unsigned int     level,     // node level
13                      sqt_lock_node_t* parent,    // pointer on parent node
14                      unsigned int     xmax,      // SQT X size
15                      unsigned int     ymax )     // SQT Y size
16{
17
18#if GIET_DEBUG_USER_LOCK
19
20unsigned int    px;
21unsigned int    py;
22unsigned int    pl;
23giet_proc_xyp( &px, &py, &pl );
24#endif
25
26    // get target node pointer
27    sqt_lock_node_t* node = lock->node[x][y][level];
28   
29    if (level == 0 )        // terminal case
30    {
31        // initializes target node
32        node->current  = 0;   
33        node->free     = 0;
34        node->level    = 0;
35        node->parent   = parent;
36        node->child[0] = NULL;
37        node->child[1] = NULL;
38        node->child[2] = NULL;
39        node->child[3] = NULL;
40
41#if GIET_DEBUG_USER_LOCK
42giet_tty_printf("\n[DEBUG USER SQT_LOCK] P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n"
43      " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n",
44      px , py , pl , x , y , level , 
45      (unsigned int)node->parent , 
46      (unsigned int)node->child[0] , 
47      (unsigned int)node->child[1] , 
48      (unsigned int)node->child[2] , 
49      (unsigned int)node->child[3] );
50#endif
51
52    }
53    else                   // non terminal case
54    {
55        unsigned int cx[4];      // x coordinate for children
56        unsigned int cy[4];      // y coordinate for children
57        unsigned int i;          // child index
58
59        // the child0 coordinates are equal to the parent coordinates
60        // other childs coordinates are incremented depending on the level value
61        cx[0] = x;
62        cy[0] = y;
63
64        cx[1] = x + (1 << (level-1));
65        cy[1] = y;
66
67        cx[2] = x;
68        cy[2] = y + (1 << (level-1));
69
70        cx[3] = x + (1 << (level-1));
71        cy[3] = y + (1 << (level-1));
72
73        // initializes target node
74        for ( i = 0 ; i < 4 ; i++ )
75        {
76            if ( (cx[i] < xmax) && (cy[i] < ymax) ) 
77                node->child[i] = lock->node[cx[i]][cy[i]][level-1];
78            else 
79                node->child[i] = NULL;
80        }
81        node->current  = 0;
82        node->free     = 0;
83        node->level    = level;
84        node->parent   = parent;
85
86#if GIET_DEBUG_USER_LOCK
87giet_tty_printf("\n[DEBUG USER SQT_LOCK] P[%d,%d,%d] initialises SQT node[%d,%d,%d] : \n"
88      " parent = %x / childO = %x / child1 = %x / child2 = %x / child3 = %x\n",
89      px , py , pl , x , y , level , 
90      (unsigned int)node->parent , 
91      (unsigned int)node->child[0] , 
92      (unsigned int)node->child[1] , 
93      (unsigned int)node->child[2] , 
94      (unsigned int)node->child[3] );
95#endif
96
97       // recursive calls for children nodes
98        for ( i = 0 ; i < 4 ; i++ )
99        {
100            if ( (cx[i] < xmax) && (cy[i] < ymax) ) 
101                sqt_lock_build( lock, 
102                                 cx[i], 
103                                 cy[i], 
104                                 level-1, 
105                                 node, 
106                                 xmax, 
107                                 ymax );
108        }
109    }
110}  // end _sqt_lock_build()
111
112
113
114/////////////////////////////////////////////////////////////////////////////////
115void sqt_lock_init( sqt_lock_t*  lock,
116                       unsigned int         x_size,    // number of clusters in a row
117                       unsigned int         y_size,    // number of clusters in a col
118                       unsigned int         ntasks )   // tasks per clusters
119{
120    // check parameters
121    if ( x_size > 16 ) giet_exit("SQT LOCK ERROR : x_size too large");
122    if ( y_size > 16 ) giet_exit("SQT LOCK ERROR : y_size too large");
123    if ( ntasks > 8  ) giet_exit("SQT LOCK ERROR : ntasks too large");
124   
125    // compute SQT levels
126    unsigned int levels; 
127    unsigned int z = (x_size > y_size) ? x_size : y_size;
128    levels = (z < 2) ? 1 : (z < 3) ? 2 : (z < 5) ? 3 : (z < 9) ? 4 : 5;
129
130#if GIET_DEBUG_USER_LOCK
131unsigned int    px;
132unsigned int    py;
133unsigned int    pl;
134giet_proc_xyp(&px, &py, &pl);
135unsigned int side   = (z < 2) ? 1 : (z < 3) ? 2 : (z < 5) ? 4 : (z < 9) ? 8 : 16;
136giet_tty_printf("\n[DEBUG USER SQT_LOCK] sqt_nodes allocation\n"
137                " x_size = %d / y_size = %d / levels = %d / side = %d\n",
138                x_size , y_size , levels , side );
139#endif
140
141   
142    unsigned int x;              // x coordinate for one SQT node
143    unsigned int y;              // y coordinate for one SQT node
144    unsigned int l;              // level for one SQT node
145
146    for ( x = 0 ; x < x_size ; x++ )
147    {
148        for ( y = 0 ; y < y_size ; y++ )
149        {
150            for ( l = 0 ; l < levels ; l++ )             // level 0 nodes
151            {
152               
153                if ( ( (l == 0) && ((x&0x00) == 0) && ((y&0x00) == 0) ) ||
154                     ( (l == 1) && ((x&0x01) == 0) && ((y&0x01) == 0) ) ||
155                     ( (l == 2) && ((x&0x03) == 0) && ((y&0x03) == 0) ) ||
156                     ( (l == 3) && ((x&0x07) == 0) && ((y&0x07) == 0) ) ||
157                     ( (l == 4) && ((x&0x0F) == 0) && ((y&0x0F) == 0) ) )
158                 {
159                     lock->node[x][y][l] = 
160                     (sqt_lock_node_t*)remote_malloc( sizeof(sqt_lock_node_t),
161                                                       x, y );
162
163#if GIET_DEBUG_USER_LOCK
164giet_tty_printf("\n[DEBUG USER SQT_LOCK] P[%d,%d,%d] allocates SQT node[%d,%d,%d]"
165               " : vaddr = %x\n",
166               px , py , pl , x , y , l , (unsigned int)lock->node[x][y][l] );
167#endif
168                 }
169            }
170        }
171    }
172           
173    // recursively initialize all SQT nodes from root to bottom
174    sqt_lock_build( lock,
175                     0,
176                     0,
177                     levels-1,
178                     NULL,
179                     x_size,
180                     y_size );
181
182    asm volatile ("sync" ::: "memory");
183
184#if GIET_DEBUG_USER_LOCK
185giet_tty_printf("\n[DEBUG USER SQT_LOCK] SQT nodes initialisation completed\n"); 
186#endif
187
188} // end sqt_lock_init()
189
190
191//////////////////////////////////////////////////////////////////////////////////
192static 
193void sqt_lock_take( sqt_lock_node_t* node )
194{
195    // get next free ticket from local lock
196    unsigned int ticket = atomic_increment( &node->free, 1 );
197
198#if GIET_DEBUG_USER_LOCK
199unsigned int    x;
200unsigned int    y;
201unsigned int    l;
202giet_proc_xyp(&x, &y, &l);
203giet_tty_printf("\n[DEBUG USER SQT_LOCK] P[%d,%d,%d] get ticket %d for SQT lock %x"
204               " / level = %d / current = %d / free = %d\n",
205               x , y , l , ticket , (unsigned int)node ,
206               node->level , node->current , node->free );
207#endif
208
209    // poll the local lock current index
210    while ( (*(volatile unsigned int *)( &node->current )) != ticket ) asm volatile( "nop" );
211
212#if GIET_DEBUG_USER_LOCK
213giet_tty_printf("\n[DEBUG SQT_LOCK] P[%d,%d,%d] get SQT lock %x"
214               " / level = %d / current = %d / free = %d\n",
215               x , y , l , (unsigned int)node ,
216               node->level , node->current , node->free );
217#endif
218
219    // try to take the parent node lock until top is reached
220    if ( node->parent != NULL ) sqt_lock_take( node->parent );
221
222} // end _sqt_lock_take()
223
224
225/////////////////////////////////////////////////////////////////////////////////
226void sqt_lock_acquire( sqt_lock_t*  lock )
227{
228    unsigned int x;
229    unsigned int y;
230    unsigned int p;
231    // get cluster coordinates
232    giet_proc_xyp( &x, &y, &p );
233
234    // try to recursively take the distributed locks (from bottom to top)
235    sqt_lock_take( lock->node[x][y][0] );
236}
237
238/////////////////////////////////////////////////////////////////////////////////
239static 
240void sqt_lock_give( sqt_lock_node_t* node )
241{
242    // release the local lock
243    node->current = node->current + 1;
244
245#if GIET_DEBUG_USER_LOCK
246unsigned int    x;
247unsigned int    y;
248unsigned int    l;
249giet_proc_xyp(&x, &y, &l);
250giet_tty_printf("\n[DEBUG USER SQT_LOCK] P[%d,%d,%d] release SQT lock %x"
251               " / level = %d / current = %d / free = %d\n",
252               x , y , l , (unsigned int)node, 
253               node->level , node->current , node->free );
254#endif
255
256    // reset parent node until top is reached
257    if ( node->parent != NULL ) sqt_lock_give( node->parent );
258
259} // end _sqt_lock_give()
260
261/////////////////////////////////////////////////////////////////////////////////
262void sqt_lock_release( sqt_lock_t*  lock )
263{
264    asm volatile ( "sync" );   // for consistency
265
266    unsigned int x;
267    unsigned int y;
268    unsigned int p;
269    // get cluster coordinates
270    giet_proc_xyp( &x, &y, &p );
271
272    // recursively reset the distributed locks (from bottom to top)
273    sqt_lock_give( lock->node[x][y][0] );
274}
275
276// Local Variables:
277// tab-width: 4
278// c-basic-offset: 4
279// c-file-offsets:((innamespace . 0)(inline-open . 0))
280// indent-tabs-mode: nil
281// End:
282// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
283
Note: See TracBrowser for help on using the repository browser.