OSAtomic built-in operations

  • Hi All!

    I would like to use OSAtomicCompareAndSwap32 and OSAtomicOr32Orig using the same variable. Unfortunately, the first requires a signed int, the other an unsigned int.

    How can I get this to work?

    Example:

    enum {
    State_Canceling = 1U << 7;
    };

    int _state; // would like to have an uint32_t

    int new_state = OSAtomicCompareAndSwap32(State_0, State_1, &_state);


    if (OSAtomicOr32Orig(State_Canceling, &_state) != 0) {
    // canceling
    }

    The solution would be a "OSAtomicCompareAndSwapU32", or is it save to pass a signed int where an unsigned int is required, considering strong Alias rules and whatever optimizations the compiler applies?

    Thanks for tips!

    Reagards
    Andreas
  • On 06.05.2012, at 02:05, Andreas Grosam wrote:

    > I would like to use OSAtomicCompareAndSwap32 and OSAtomicOr32Orig using the same variable. Unfortunately, the first requires a signed int, the other an unsigned int.
    >
    > How can I get this to work?

    Have you tried union{} ?

        union {
            int32_t s;
            uint32_t u;
        } atomicvar;
        atomicvar.u = 0;
        OSAtomicCompareAndSwap32(0, 1, &atomicvar.s);
        OSAtomicOr32Orig(0, &atomicvar.u);

    -Stefan
  • On May 6, 2012, at 17:11 , Stefan Werner wrote:

    > Have you tried union{} ?
    >
    > union {
    > int32_t s;
    > uint32_t u;
    > } atomicvar;
    > atomicvar.u = 0;
    > OSAtomicCompareAndSwap32(0, 1, &atomicvar.s);
    > OSAtomicOr32Orig(0, &atomicvar.u);

    I've seen this technique in other places. Why is that better than just casting pointer types? Like this:

    int32_t        s;
    uint32_t    u;

    u = *(uint32_t*) &s;

    --
    Rick
  • >>    union {
    >>        int32_t s;
    >>        uint32_t u;
    >>    } atomicvar;
    >>    atomicvar.u = 0;
    >>    OSAtomicCompareAndSwap32(0, 1, &atomicvar.s);
    >>    OSAtomicOr32Orig(0, &atomicvar.u);
    >
    > I've seen this technique in other places. Why is that better than just casting pointer types? Like this:
    >
    > int32_t         s;
    > uint32_t        u;
    >
    > u = *(uint32_t*) &s;

    Indeed -- and my understanding is C only guarantees that the most
    recently-assigned member of a union to be valid. So if the OP is
    worried about correctness, it would seem the union approach doesn't
    help.
  • On 06.05.2012, at 21:29, Rick Mann wrote:

    > I've seen this technique in other places. Why is that better than just casting pointer types? Like this:
    >
    > int32_t        s;
    > uint32_t    u;
    >
    > u = *(uint32_t*) &s;

    Your code has two variables and make it the programmer's job to keep them in sync. When using a union, you have two names for the same memory address. Also, the union approach is type safe where a C-style pointer cast will allow you to cast anything to a uint32_t* without the compiler warning you about it.

    -Stefan
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today