Ignore:
Timestamp:
2013-12-29T14:32:55Z (10 years ago)
Author:
Martin Decky <martin@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4c14b88, 6fa9a99d, 9be30cdf, aacdb8e
Parents:
2a13328
Message:

cherrypick important fixes and updates from lp:~jceel/helenos/leon3

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/sparc32/include/arch/atomic.h

    r2a13328 r208b5f5  
    3737
    3838#include <typedefs.h>
     39#include <arch/asm.h>
    3940#include <arch/barrier.h>
    4041#include <preemption.h>
     
    4748    REQUIRES(val->count < ATOMIC_COUNT_MAX)
    4849{
    49         // FIXME TODO
     50        // FIXME: Isn't there any intrinsic atomic operation?
     51        ipl_t ipl = interrupts_disable();
    5052        val->count++;
     53        interrupts_restore(ipl);
    5154}
    5255
     
    5659    REQUIRES(val->count > ATOMIC_COUNT_MIN)
    5760{
    58         // FIXME TODO
     61        // FIXME: Isn't there any intrinsic atomic operation?
     62        ipl_t ipl = interrupts_disable();
    5963        val->count--;
     64        interrupts_restore(ipl);
    6065}
    6166
     
    6570    REQUIRES(val->count < ATOMIC_COUNT_MAX)
    6671{
    67         // FIXME TODO
     72        // FIXME: Isn't there any intrinsic atomic operation?
    6873       
     74        ipl_t ipl = interrupts_disable();
    6975        atomic_count_t prev = val->count;
    7076       
    7177        val->count++;
     78        interrupts_restore(ipl);
    7279        return prev;
    7380}
     
    7885    REQUIRES(val->count > ATOMIC_COUNT_MIN)
    7986{
    80         // FIXME TODO
     87        // FIXME: Isn't there any intrinsic atomic operation?
    8188       
     89        ipl_t ipl = interrupts_disable();
    8290        atomic_count_t prev = val->count;
    8391       
    8492        val->count--;
     93        interrupts_restore(ipl);
    8594        return prev;
    8695}
     
    93102    REQUIRES_EXTENT_MUTABLE(val)
    94103{
    95         // FIXME TODO
     104        atomic_count_t prev;
     105        volatile uintptr_t ptr = (uintptr_t) &val->count;
    96106       
    97         atomic_count_t prev = val->count;
    98         val->count = 1;
     107        asm volatile (
     108                "ldstub [%[ptr]] %[prev]\n"
     109                : [prev] "=r" (prev)
     110                : [ptr] "r" (ptr)
     111                : "memory"
     112        );
     113       
    99114        return prev;
    100115}
     
    104119    REQUIRES_EXTENT_MUTABLE(val)
    105120{
    106         // FIXME TODO
     121        atomic_count_t tmp1 = 0;
    107122       
    108         do {
    109                 while (val->count);
    110         } while (test_and_set(val));
     123        volatile uintptr_t ptr = (uintptr_t) &val->count;
     124       
     125        preemption_disable();
     126       
     127        asm volatile (
     128                "0:\n"
     129                        "ldstub %0, %1\n"
     130                        "tst %1\n"
     131                        "be 2f\n"
     132                        "nop\n"
     133                "1:\n"
     134                        "ldub %0, %1\n"
     135                        "tst %1\n"
     136                        "bne 1b\n"
     137                        "nop\n"
     138                        "ba,a 0b\n"
     139                "2:\n"
     140                : "+m" (*((atomic_count_t *) ptr)),
     141                  "+r" (tmp1)
     142                : "r" (0)
     143        );
     144       
     145        /*
     146         * Prevent critical section code from bleeding out this way up.
     147         */
     148        CS_ENTER_BARRIER();
    111149}
    112150
Note: See TracChangeset for help on using the changeset viewer.