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

Last change on this file since 284 was 258, checked in by alain, 11 years ago

This is a major release, including a deep restructuration of code.
The main evolutions are

  • use of the Tsar preloader to load the GIET boot-loader from disk
  • introduction of a FAT32 file system library,
  • use of this fat32 library by the boot-loader to load the map.bin data structure, and the various .elf files
  • reorganisation of drivers (one file per peripheral).
  • introduction of drivers for new peripherals: vci_chbuf_dma and vci_multi_ahci.
  • introduction of a new physical memory allocator in the boot code.

This release has been tested on the tsar_generic_iob architecture,
for the two following mappings: 4c_1p_iob_four.xml and 4c_1p_iob_sort.xml

  • Property svn:executable set to *
File size: 3.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///////////////////////////////////////////////////////////////////////////////////
17//     barrier_init()
18// This function makes a cooperative initialisation of the barrier:
19// several tasks try to initialize the barrier, but the initialisation
20// is done by only one task, using LL/SC instructions.
21///////////////////////////////////////////////////////////////////////////////////
22void barrier_init( giet_barrier_t * barrier, unsigned int value) {
23    unsigned int * pinit  = (unsigned int *) &barrier->init;
24    unsigned int * pcount = (unsigned int *) &barrier->count;
25
26    // parallel initialisation using atomic instructions LL/SC
27    // inputs : pinit, pcount, value
28    // no output
29    asm volatile ("_barrier_init_test:                  \n"
30            "ll   $2,     0(%0)                   \n" /* read initial value */
31            "bnez $2,     _barrier_init_done      \n"
32            "move $3,     %2                      \n"
33            "sc   $3,     0(%0)                   \n" /* write initial value */
34            "beqz $3,     _barrier_init_test      \n"
35            "move $3,     %2                      \n"
36            "sw   $3,     0(%1)                   \n" /* write count */
37            "_barrier_init_done:                  \n"
38            :
39            : "r"(pinit), "r"(pcount), "r"(value)
40            : "$2", "$3");
41}
42
43
44///////////////////////////////////////////////////////////////////////////////////
45//    barrier_wait()
46// This blocking function uses LL/SC to decrement the barrier's counter.
47// Then, it uses a busy_waiting mechanism if it is not the last.
48// (because the GIET does not support dynamic task scheduling/descheduling)
49///////////////////////////////////////////////////////////////////////////////////
50void barrier_wait(giet_barrier_t * barrier) {
51    unsigned int * pcount  = (unsigned int *) &barrier->count;
52    unsigned int maxcount = barrier->init;
53    unsigned int count;
54
55    // parallel decrement barrier counter using atomic instructions LL/SC
56    // - input : pointer on the barrier counter
57    // - output : counter value
58    asm volatile ("_barrier_decrement:          \n"
59            "ll   %0, 0(%1)               \n"
60            "addi $3, %0,     -1          \n"
61            "sc   $3, 0(%1)               \n"
62            "beqz $3, _barrier_decrement  \n"
63            : "=&r"(count)
64            : "r"(pcount)
65            : "$2", "$3");
66
67    // the last task re-initializes the barrier counter to the max value,
68    // waking up all other waiting tasks
69
70    if (count == 1) {
71        // last task
72        *pcount = maxcount;
73    }
74    else {
75        // other tasks busy-wait
76        while (*pcount != maxcount) asm volatile ("nop");
77    }
78}
79
80// Local Variables:
81// tab-width: 4
82// c-basic-offset: 4
83// c-file-offsets:((innamespace . 0)(inline-open . 0))
84// indent-tabs-mode: nil
85// End:
86// vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
87
Note: See TracBrowser for help on using the repository browser.