source: soft/giet_vm/libs/spin_lock.c @ 247

Last change on this file since 247 was 244, checked in by brejon, 12 years ago
  • Update malloc (remote free)
  • bugfix in spin_lock (bad register used in asm inline)
  • memo/Makefile clean rule : added "-f" option to rm command
  • main Makefile :
    • added spin_lock.o in dhrystone object files
    • added rules to compile spin_lock
File size: 3.2 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
2// File     : spin_lock.c         
3// Date     : 01/04/2012
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// The spin_lock.c and spin_lock.h files are part of the GIET nano-kernel.
8// This  middlewre implements a user-level lock (busy waiting mechanism,
9// because the GIET does not support task scheduling / descheduling).
10// It is a simple binary lock, without waiting queue.
11//
12// The lock_acquire() and lock_release() functions do not require a system call.
13// The barrier itself must have been allocated in a non cacheable segment,
14// if the platform does not provide hardwate cache coherence.
15//
16// ALL locks must be defined in the mapping_info data structure,
17// to be initialised by the GIET in the boot phase.
18// The vobj_get_vbase() system call (defined in stdio.c and stdio.h files)
19// can be used to get the virtual base address of the lock fro it's name.
20///////////////////////////////////////////////////////////////////////////////////
21
22#include <spin_lock.h>
23#include <stdio.h>
24
25///////////////////////////////////////////////////////////////////////////////////
26// lock_acquire()
27// This blocking function returns only when the lock has been taken.
28// If the lock is already taken a random delay is introduced before retry.
29///////////////////////////////////////////////////////////////////////////////////
30void lock_acquire(giet_lock_t * lock) {
31    unsigned int * plock = &lock->value;
32
33    asm volatile (
34            "move $16, %0                   \n"
35            "giet_lock_try :                \n"
36            "ll   $2,    0($16)             \n" /* $2 <= lock current value */
37            "bnez $2,    giet_lock_delay    \n" /* retry if lock already taken */
38            "li   $3,    1                  \n" /* $3 <= argument for sc */
39            "sc   $3,    0($16)             \n" /* try to get lock */
40            "bnez $3,    giet_lock_ok       \n" /* exit if atomic */
41
42            "giet_lock_delay:               \n"
43            "jal  giet_rand                 \n" /* giet_rand() system call */
44            "nop                            \n"
45            "andi $4,    $2,    0xFF        \n" /* $4 <= delay < 256 cycles */
46
47            "giet_lock_loop:                \n"
48            "addi $4,    $4,  -1            \n" /* $4 <= $4 - 1 */
49            "beqz $4,    giet_lock_loop     \n" /* test end delay */
50            "nop                            \n"
51            "j           giet_lock_try      \n" /* retry */
52            "nop                            \n"
53            "giet_lock_ok:                  \n"
54            :
55            :"r"(plock)
56            :"$2", "$3", "$4", "$16");
57}
58
59
60//////////////////////////////////////////////////////////////////////////////
61// lock_release()
62//////////////////////////////////////////////////////////////////////////////
63void lock_release(giet_lock_t * lock) {
64    lock->value = 0;
65}
66
67
68// Local Variables:
69// tab-width: 4
70// c-basic-offset: 4
71// c-file-offsets:((innamespace . 0)(inline-open . 0))
72// indent-tabs-mode: nil
73// End:
74// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
75
Note: See TracBrowser for help on using the repository browser.