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

Last change on this file since 337 was 295, checked in by alain, 11 years ago

Introducing a major release, to suppoort the tsar_generic_leti platform
and the various (external or internal) peripherals configurations.
The map.xml format has been modified, in order to support the new
vci_iopic componentand a new policy for peripherals initialisation.
The IRQs are nom described in the XICU and IOPIC components
(and not anymore in the processors).
To enforce this major change, the map.xml file signature changed:
The signature value must be: 0xDACE2014

This new release has been tested on the tsar_generic_leti platform
for the following mappings:

  • 4c_4p_sort_leti
  • 4c_4p_sort_leti_ext
  • 4c_4p_transpose_leti
  • 4c_4p_transpose_leti_ext
  • 4c_1p_four_leti_ext
  • Property svn:executable set to *
File size: 2.6 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{
22    barrier->init  = value;
23    barrier->count = value;
[258]24}
25
26
27///////////////////////////////////////////////////////////////////////////////////
28// This blocking function uses LL/SC to decrement the barrier's counter.
29// Then, it uses a busy_waiting mechanism if it is not the last.
30///////////////////////////////////////////////////////////////////////////////////
[295]31void barrier_wait( giet_barrier_t* barrier ) 
32{
[258]33    unsigned int * pcount  = (unsigned int *) &barrier->count;
34    unsigned int maxcount = barrier->init;
35    unsigned int count;
36
37    // parallel decrement barrier counter using atomic instructions LL/SC
38    // - input : pointer on the barrier counter
39    // - output : counter value
[295]40    asm volatile ("_barrier_decrement:    \n"
[258]41            "ll   %0, 0(%1)               \n"
42            "addi $3, %0,     -1          \n"
43            "sc   $3, 0(%1)               \n"
44            "beqz $3, _barrier_decrement  \n"
45            : "=&r"(count)
46            : "r"(pcount)
47            : "$2", "$3");
48
49    // the last task re-initializes the barrier counter to the max value,
50    // waking up all other waiting tasks
51
[295]52    if (count == 1) 
53    {
[258]54        // last task
55        *pcount = maxcount;
56    }
57    else {
58        // other tasks busy-wait
59        while (*pcount != maxcount) asm volatile ("nop");
60    }
61}
62
63// Local Variables:
64// tab-width: 4
65// c-basic-offset: 4
66// c-file-offsets:((innamespace . 0)(inline-open . 0))
67// indent-tabs-mode: nil
68// End:
69// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
70
Note: See TracBrowser for help on using the repository browser.