lkml.org 
[lkml]   [1999]   [Nov]   [26]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    Date
    From
    SubjectRe: spin_unlock optimization(i386)
    On Fri, 26 Nov 1999, Manfred Spraul wrote:

    > You you please look at my program?

    I took a second look at it and it still looks like reads are getting
    reordered. I rewrote it a bit for my own readability, perhaps other people
    would like to look at this version:

    /*
    * movopt: test for Intel memory ordering.
    * Copyright (C) 1999 by Manfred Spraul.
    * restructuring by oxymoron@waste.org
    *
    * Redistribution of this file is permitted under the terms of the GNU
    * Public License (GPL)
    * $Header: /pub/cvs/ms/movopt/movopt.cpp,v 1.3 1999/11/25 23:38:44 manfreds Ex
    p $
    */

    /*
    cc -o foo -lpthreads foo.c

    NOTE: this code will run _extremely_ slowly on UP systems

    func1 and func2 are the functions that may race with each other

    cpu1 and cpu2 are thread functions that synchronize func1 and func2
    while adjusting timings
    */

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <unistd.h>
    #include <pthread.h>
    #include <assert.h>

    #define USE_MB 0
    #define USE_ASM 1

    volatile int start = 0;
    volatile int current_state = 0;
    volatile int lock = 1;
    volatile int ready = 0;
    volatile int go = 0;

    #if USE_ASM == 0 /* doesn't compile, here for explanation */

    static inline void func1()
    {
    set_current_state(1);
    if(lock!=1)
    while (current_state!=0)
    ;
    }

    static inline void func2()
    {
    lock=0;
    current_state=0;
    mb();
    }

    #else
    static inline void func1()
    {
    __asm__ __volatile(
    #if USE_MB == 0
    "movl $1,%1\n\t" /* set current_state = 1 */
    #else
    "lock;bts $0,%1\n\t"
    #endif
    "movl %0,%%eax\n\t" /* lock into %%eax */
    "cmpl $1,%%eax\n\t"
    "jne dont_sleep\n"
    "retry:\n\t"
    "movl %1, %%eax\n\t"
    "cmpl $0,%%eax\n\t"
    "jne retry\n"
    "dont_sleep:\n"
    : /* no output */
    : "m" (lock), "m" (current_state)
    : "eax", "cc", "memory");
    }

    static inline void func2()
    {
    __asm__ __volatile(
    "movl $0,%0\n\t"
    "movl $0,%1\n\t"
    "lock; addl $0,(%%esp)\n\t" /* flush our write buffers*/
    : /* no output */
    : "m" (lock), "m" (current_state)
    : "memory");
    }
    #endif

    void* cpu1(void* param)
    {
    /* 1: always sleep
    10 000: never sleep
    PII/350: lock-up at delay=217
    */
    volatile int delay = 1;

    int i=0,j;

    while(!start)
    ;

    for(;i<50000000;i++) {
    lock = 1;
    current_state = 0;
    go = 0;
    while(!ready)
    ;
    go = 1;

    for(j=0;j<delay;j++)
    ;

    func1();

    if((i%5000)==0) {
    printf("delay %d: ok\n",delay);
    delay++;
    }
    }

    printf("thread %d finished.\n",(int)param);
    exit(0);
    }

    void* cpu2(void* param)
    {
    /* increase this value if no lock-up occurs,
    eg: 2000
    */
    volatile int delay2 = 300;

    int i=0,j;

    while(!start)
    ;

    for(;;) {
    ready = 1;
    while(!go)
    ;
    ready = 0;
    go = 0;

    for(j=0;j<delay2;j++)
    ;

    func2();
    }
    }

    typedef void *threadfunc(void *);

    void start_thread(threadfunc *f)
    {
    pthread_t thread;
    int res;

    res = pthread_create(&thread,NULL,f,NULL);
    if(res != 0)
    assert(0);
    }

    int main()
    {
    printf("movopt:\n");
    start_thread(cpu1);
    start_thread(cpu2);
    printf(" starting, please wait.\n");
    fflush(stdout);
    start = 1;
    for(;;) sleep(1000);
    }

    --
    "Love the dolphins," she advised him. "Write by W.A.S.T.E.."


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

    \
     
     \ /
      Last update: 2005-03-22 13:55    [W:4.306 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site