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

Last change on this file since 256 was 255, checked in by meunier, 11 years ago
  • Added a syscall and some user functions to manipulate the Simulation Helper
  • Changed the the way the Vseg -> Pseg mapping is made during the boot to better utilize the address space (+ adaptation of the algorithm in memo)
  • Fixed a bug in boot_init (vobj_init): the vobj initialization could only be made for the first application (ptpr was not changed)
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            "nop                            \n"
42
43            "giet_lock_delay:               \n"
44            "jal  giet_rand                 \n" /* giet_rand() system call */
45            "nop                            \n"
46            "andi $4,    $2,    0xFF        \n" /* $4 <= delay < 256 cycles */
47
48            "giet_lock_loop:                \n"
49            "addi $4,    $4,  -1            \n" /* $4 <= $4 - 1 */
50            "beqz $4,    giet_lock_loop     \n" /* test end delay */
51            "nop                            \n"
52            "j           giet_lock_try      \n" /* retry */
53            "nop                            \n"
54            "giet_lock_ok:                  \n"
55            :
56            :"r"(plock)
57            :"$2", "$3", "$4", "$16");
58}
59
60
61//////////////////////////////////////////////////////////////////////////////
62// lock_release()
63//////////////////////////////////////////////////////////////////////////////
64void lock_release(giet_lock_t * lock) {
65    lock->value = 0;
66}
67
68
69// Local Variables:
70// tab-width: 4
71// c-basic-offset: 4
72// c-file-offsets:((innamespace . 0)(inline-open . 0))
73// indent-tabs-mode: nil
74// End:
75// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
76
Note: See TracBrowser for help on using the repository browser.