source: soft/giet_vm/giet_libs/barrier.c @ 351

Last change on this file since 351 was 345, checked in by cfuguet, 11 years ago

giet_vm optimizations:

  • Several modifications in GIET_VM in order to support compilation with GCC optimizations (-O2) activated.
  • Adding missing volatile in some global variables.
  • Using ioread and iowrite utility functions in peripheral drivers which prevent GCC to remove writes or reads in hardware memory mapped registers.
  • Code refactoring of stdio printf functions. Now, shr_printf and tty_printf function reuse the same function body. The only difference is that shr_printf wraps printf function call with TTY get lock and release lock.
  • Property svn:executable set to *
File size: 2.8 KB
RevLine 
[258]1//////////////////////////////////////////////////////////////////////////////////
2// File     : barrier.c     
3// Date     : 01/04/2012
4// Author   : alain greiner
5// Copyright (c) UPMC-LIP6
6///////////////////////////////////////////////////////////////////////////////////
7// These barrier.c and barrier.h files are part of the GIET nano-kernel.
8// This user-level library provides a synchronisation service between several
9// tasks sharing the same address space in a parallel multi-tasks application.
10// Neither the barrier_init(), nor the barrier_wait() function require a syscall.
11// The barrier itself must have been allocated in a shared data segment.
12///////////////////////////////////////////////////////////////////////////////////
13
14#include "barrier.h"
15
16///////////////////////////////////////////////////////////////////////////////////
[295]17// This function initializes the barrier: this should be done by a single task.
[258]18///////////////////////////////////////////////////////////////////////////////////
[295]19void barrier_init( giet_barrier_t* barrier, 
20                   unsigned int    value ) 
21{
[345]22    barrier->init  = (volatile unsigned int)value;
23    barrier->count = (volatile unsigned int)value;
24    asm volatile ("sync" ::: "memory");
[258]25}
26
27
28///////////////////////////////////////////////////////////////////////////////////
29// This blocking function uses LL/SC to decrement the barrier's counter.
30// Then, it uses a busy_waiting mechanism if it is not the last.
31///////////////////////////////////////////////////////////////////////////////////
[295]32void barrier_wait( giet_barrier_t* barrier ) 
33{
[345]34    volatile unsigned int * pcount = (unsigned int *) &barrier->count;
35    volatile unsigned int maxcount = barrier->init;
36    volatile unsigned int count;
[258]37
38    // parallel decrement barrier counter using atomic instructions LL/SC
39    // - input : pointer on the barrier counter
40    // - output : counter value
[345]41    asm volatile (
42            "_barrier_decrement:                \n"
43            "ll     %0,   0(%1)                 \n"
44            "addi   $3,   %0,     -1            \n"
45            "sc     $3,   0(%1)                 \n"
46            "beqz   $3,   _barrier_decrement    \n"
47            : "+r"(count)
[258]48            : "r"(pcount)
[345]49            : "$3", "memory");
[258]50
51    // the last task re-initializes the barrier counter to the max value,
52    // waking up all other waiting tasks
53
[295]54    if (count == 1) 
55    {
[258]56        // last task
57        *pcount = maxcount;
58    }
59    else {
60        // other tasks busy-wait
[345]61        while (*pcount != maxcount);
[258]62    }
[345]63
64    asm volatile ("sync" ::: "memory");
[258]65}
66
67// Local Variables:
68// tab-width: 4
69// c-basic-offset: 4
70// c-file-offsets:((innamespace . 0)(inline-open . 0))
71// indent-tabs-mode: nil
72// End:
73// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
74
Note: See TracBrowser for help on using the repository browser.