lkml.org 
[lkml]   [2006]   [Jan]   [21]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: set_bit() is broken on i386?
    In-Reply-To: <Pine.LNX.4.63.0601210245280.8060@alpha.polcom.net>

    (Resent because I forgot the cc: list; Grzegorz, please don't
    reply to my original.)

    On Sat, 21 Jan 2006, Grzegorz Kulewski wrote:

    > > On Fri, 20 Jan 2006 19:53:14 EST, Chuck Ebbert said:
    > >> /*
    > >> * setbit.c -- test the Linux set_bit() function
    > >> *
    > >> * Compare the output of this program with and without the
    > >> * -finline-functions option to GCC.
    > >> *
    > >> * If they are not the same, set_bit is broken.

    I should have said "If they do not both output '00010001' then
    set_bit() is broken."

    You got:

    > gcc-3.4.5 (GCC) 3.4.5 (Gentoo 3.4.5, ssp-3.4.5-1.0, pie-8.7.9)
    > 00000001
    > 00000001
    >
    > gcc-4.0.2 (GCC) 4.0.2 (Gentoo 4.0.2-r3, pie-8.7.8)
    > 00000001
    > 00000001
    >
    > gcc-4.1.0-beta20060113 (GCC) 4.1.0-beta20060113 (prerelease)
    > 00000001
    > 00000001
    >
    > gcc (GCC) 3.3.5-20050130 (Gentoo 3.3.5.20050130-r1, ssp-3.3.5.20050130-1,

    pie-8.7.7.1)
    > 00010001
    > 00000001

    So the macro is broken even without -finline-functions on all but the
    last compiler.

    I couldn't break this new program, which assumes 'nr' is a constant:

    /*
    * setbit2.c -- test an alternate Linux set_bit() function
    *
    * Compare the output of this program with and without the
    * -finline-functions option to GCC.
    *
    * If they do not both contain two ones, set_bit is broken.
    *
    * Result on i386 with gcc 4.0.2 (Fedora Core 4):
    *
    * [me@d2 t]$ gcc -O2 -o setbit2.ex setbit2.c ; ./setbit2.ex
    * 0x00010001
    * [me@d2 t]$ gcc -O2 -o setbit2.ex -finline-functions setbit2.c ;
    ./setbit2.ex
    * 0x00010001
    */
    #define _GNU_SOURCE
    #include <stdio.h>
    #include <stdlib.h>

    #define inline __attribute__((always_inline))
    #define LONGBITS (8 * sizeof(unsigned long))

    /*
    * new set_bit() for testing; assumes nr is a compile-time constant
    */
    #define ADDR (*(volatile long *) addr)
    static inline void set_bit(int nr, volatile unsigned long * addr)
    {
    __asm__ __volatile__( "lock ; "
    "btsl %2,%1"
    :"=m" (*(addr + nr/LONGBITS))
    :"m" (*addr),"Ir" (nr),"m" (*(addr + nr/LONGBITS))
    );
    }

    unsigned long a = 1;
    unsigned long b[3];

    #define WORD 2
    int main(int argc, char * const argv[])
    {
    b[WORD] = a;
    set_bit(WORD * LONGBITS + LONGBITS / 2, b);
    printf("0x%08x\n", b[WORD]);
    return 0;
    }

    --
    Chuck
    -
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2006-01-21 21:56    [W:0.027 / U:0.124 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site