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

Last change on this file since 573 was 501, checked in by alain, 10 years ago

Introduce user-level, distributed barriers and locks (quad-tree based).

  • Property svn:executable set to *
File size: 4.4 KB
Line 
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    asm volatile( "sync" );
81
82    lock->current = lock->current + 1;
83
84#if GIET_DEBUG_USER_LOCK
85unsigned int    x;
86unsigned int    y;
87unsigned int    lpid;
88giet_proc_xyp( &x, &y, &lpid );
89giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] release lock %x"
90                " at cycle %d (current = %d / free = %d)\n",
91                x, y, lpid, (unsigned int)lock, 
92                giet_proctime(), lock->current, lock->free );
93#endif
94
95}
96
97//////////////////////////////////////////////////////////////////////////////
98// This function initializes the lock.
99//////////////////////////////////////////////////////////////////////////////
100void lock_init( user_lock_t* lock )
101{
102    lock->current = 0;
103    lock->free    = 0;
104
105#if GIET_DEBUG_USER_LOCK
106unsigned int    x;
107unsigned int    y;
108unsigned int    lpid;
109giet_proc_xyp( &x, &y, &lpid );
110giet_shr_printf("\n[USER_LOCK DEBUG] P[%d,%d,%d] init lock %x"
111                " at cycle %d (current = %d / free = %d)\n",
112                x, y, lpid, (unsigned int)lock,
113                giet_proctime(), lock->current, lock->free );
114#endif
115
116}
117
118
119// Local Variables:
120// tab-width: 4
121// c-basic-offset: 4
122// c-file-offsets:((innamespace . 0)(inline-open . 0))
123// indent-tabs-mode: nil
124// End:
125// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
126
Note: See TracBrowser for help on using the repository browser.