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

Last change on this file since 366 was 352, checked in by alain, 10 years ago

Avoid GCC warnings for some missing initialisations.

  • Property svn:executable set to *
File size: 2.8 KB
Line 
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///////////////////////////////////////////////////////////////////////////////////
17// This function initializes the barrier: this should be done by a single task.
18///////////////////////////////////////////////////////////////////////////////////
19void barrier_init( giet_barrier_t* barrier, 
20                   unsigned int    value ) 
21{
22    barrier->init  = (volatile unsigned int)value;
23    barrier->count = (volatile unsigned int)value;
24    asm volatile ("sync" ::: "memory");
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///////////////////////////////////////////////////////////////////////////////////
32void barrier_wait( giet_barrier_t* barrier ) 
33{
34    volatile unsigned int * pcount = (unsigned int *) &barrier->count;
35    volatile unsigned int maxcount = barrier->init;
36    volatile unsigned int count = 0;
37
38    // parallel decrement barrier counter using atomic instructions LL/SC
39    // - input : pointer on the barrier counter
40    // - output : counter value
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)
48            : "r"(pcount)
49            : "$3", "memory");
50
51    // the last task re-initializes the barrier counter to the max value,
52    // waking up all other waiting tasks
53
54    if (count == 1) 
55    {
56        // last task
57        *pcount = maxcount;
58    }
59    else {
60        // other tasks busy-wait
61        while (*pcount != maxcount);
62    }
63
64    asm volatile ("sync" ::: "memory");
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.