On Mon, Jun 16, 2008 at 01:53:44PM -0500, [EMAIL PROTECTED] wrote:
> From: Sonny Rao <[EMAIL PROTECTED]>
> 
> Adds a character driver for BSR support on IBM POWER systems including 
> Power5 and Power6.  The BSR is an optional processor facility not currently 
> implemented by any other processors.  It's primary purpose is large SMP 
> synchronization.  More details on the BSR are in comments to the code which 
> follows.
> 


Here's a basic, quick n' dirty testcase I have
Remember to link w/ -lpthread


#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <pthread.h>

static void rw_test(char *map, unsigned bytes)
{
        unsigned i;
        printf("reading current bsr values\n");
        for (i=0 ; i < bytes;i++) {
                printf("bsr[%u] = 0x%x\n",
                       i, map[i]);
        }
        printf("writing all 1s into bsr\n");
        for (i=0; i< bytes; i++) {
                map[i] = 0xff;
        }
        printf("reading current bsr values\n");
        for (i=0 ; i < bytes;i++) {
                printf("bsr[%u] = 0x%x\n",
                       i, map[i]);
        }
        printf("writing all byte numbers into bsr\n");
        for (i=0; i< bytes; i++) {
                map[i] = i;
        }
        printf("reading current bsr values\n");
        for (i=0 ; i < bytes;i++) {
                printf("bsr[%u] = 0x%x\n",
                       i, map[i]);
        }

}

struct thread_data {
        pthread_t thread;
        volatile char *map;
        unsigned id;
        uint64_t counter;
};

#define be_busy(cycles) do { \
  __asm__ __volatile__ ("1: addic. %0,%0,-1\n" \
                        "   bne 1b\n" : :"r" (cycles) : "cr0"); } while(0)
#define  __sync() do { \
  __asm__ __volatile__ ("sync\n" ::: "memory"); } while(0)

static
void * thread_fn(void * data)
{
        struct thread_data *mydata = data;

        __sync();
        mydata->map[mydata->id]++;
        __sync();
        while (mydata->map[0] == 0) {
                /* be_busy(10); */
                mydata->counter++;
        }
        return NULL;
}

static
void pthread_test(volatile char *map, unsigned num)
{
        struct thread_data *pthreads;
        unsigned i;

        pthreads = malloc(sizeof(struct thread_data) * num);
        if (!pthreads) {
                perror("malloc");
                return;
        }
        for (i=0; i<num; i++) {
                map[i] = 0;
        }
        __sync();
        for (i=1; i< num;i++) {
                struct thread_data *cur = &pthreads[i];
                cur->map = map;
                cur->id  = i;
                if (pthread_create(&cur->thread, NULL, thread_fn, cur)) {
                        perror("pthread_create");
                        exit(1);
                }
        }
        for (i=1; i<num;i++) {
                char status;
                do {
                        status = map[i];
                } while(status == 0);
        }
        __sync();
        map[0] = 1;
        __sync();
        for (i=1; i<num;i++) {
                if (pthread_join(pthreads[i].thread, NULL)) {
                        perror("pthread_join");
                }
                printf("%03u %llu\n", pthreads[i].id, pthreads[i].counter);
        }
        free(pthreads);
}

int main (int argc, char *argv[])
{
        char *file;
        int fd;
        char *map;
        int pagesize = getpagesize();
        unsigned  bytes;

        if (argc < 3) {
                fprintf(stderr, "usage: <bsr dev> <num bytes>\n");
                return 1;
        }
        file = argv[1];
        bytes = strtoul(argv[2], NULL, 0);
        fd = open(file, O_RDWR);
        if (fd < 0) {
                perror("open");
                return 1;
        }
        map = mmap(NULL, pagesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if (!map) {
                perror("mmap");
                close(fd);
                return 1;
        }

        rw_test(map, bytes);
        pthread_test(map, bytes);
        close(fd);
        return 0;
}
_______________________________________________
Linuxppc-dev mailing list
Linuxppc-dev@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-dev

Reply via email to