apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From i...@apache.org
Subject cvs commit: apr/include apr_atomic.h
Date Tue, 19 Feb 2002 23:15:40 GMT
ianh        02/02/19 15:15:40

  Modified:    test     testatomic.c
               atomic/unix apr_atomic.c
               include  apr_atomic.h
  Log:
  re-introduce the CAS apr call.
  doxygenize the header
  testing is now harder
  
  Revision  Changes    Path
  1.4       +84 -20    apr/test/testatomic.c
  
  Index: testatomic.c
  ===================================================================
  RCS file: /home/cvs/apr/test/testatomic.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- testatomic.c	18 Feb 2002 06:23:40 -0000	1.3
  +++ testatomic.c	19 Feb 2002 23:15:39 -0000	1.4
  @@ -71,12 +71,72 @@
   
   apr_pool_t *context;
   apr_atomic_t y;      /* atomic locks */
  -#if !APR_HAS_HREADS
  +
  +static apr_status_t check_basic_atomics(volatile apr_atomic_t*p)
  +{
  +    apr_uint32_t oldval;
  +    apr_atomic_set(&y,0);
  +    printf("%-60s", "testing CAS");
  +    oldval = apr_atomic_cas(&y,12,0);
  +    if (oldval != 0) {
  +        fprintf(stderr, "Failed\noldval =%d should be zero\n",oldval);
  +        return APR_EGENERAL;
  +    }
  +    printf("OK\n");
  +    printf("debug\n y=%d\n",y);
  +    printf("%-60s", "testing CAS - match non-null");
  +    oldval = apr_atomic_cas(&y,23,12);
  +    if (oldval != 12) {
  +        fprintf(stderr, "Failed\noldval =%d should be 12 y=%d\n",
  +                oldval,
  +                apr_atomic_read(&y));
  +        return APR_EGENERAL;
  +    }
  +    printf("OK\n");
  +    printf("%-60s", "testing CAS - no match");
  +    oldval = apr_atomic_cas(&y,23,12);
  +    if (oldval != 23 ) {
  +        fprintf(stderr, "Failed\noldval =%d should be 23 y=%d\n",
  +                oldval, 
  +                apr_atomic_read(&y));
  +        return APR_EGENERAL;
  +    }
  +    printf("OK\n");
  +
  +    printf("%-60s", "testing add");
  +    oldval = apr_atomic_add(&y,4);
  +    if (oldval != 23) {
  +        fprintf(stderr, "Failed\nAtomic Add should return the old value expecting 23 got
%d\n",
  +                oldval);
  +        exit(-1);
  +    }
  +    if (apr_atomic_read(&y) != 27) {
  +        fprintf(stderr, "Failed\nAtomic Add doesn't add up ;( expected 27 got %d\n",
  +            oldval);
  +        exit(-1);
  +    }
  + 
  +    printf("OK\n");
  +    printf("%-60s", "testing add/inc");
  +    apr_atomic_set(&y,0);
  +    apr_atomic_add(&y,20);
  +    apr_atomic_inc(&y);
  +    if (apr_atomic_read(&y) != 21) {
  +        fprintf(stderr, "Failed.\natomics do not add up\n");
  +        return APR_EGENERAL;
  +    }
  +    fprintf(stdout, "OK\n");
  +
  +    return APR_SUCCESS;
  +}
  +
  +#if !APR_HAS_THREADS
   int main(void)
   {
       apr_status_t rv;
  +
       fprintf(stderr,
  -            "This program won't work on this platform because there is no "
  +            "This program won't work fully on this platform because there is no "
               "support for threads.\n");
       if (apr_pool_create(&context, NULL) != APR_SUCCESS) {
           fflush(stdout);
  @@ -86,17 +146,13 @@
       rv = apr_atomic_init(context);
       if (rv != APR_SUCCESS) {
           fprintf(stderr, "Failed.\nCould not initialize atomics\n");
  +        exit(-1);
       }
  -    apr_atomic_set(&y,0);
  -    apr_atomic_add(&y,20);
  -    apr_atomic_inc(&y);
  -    if (apr_atomic_read(&y) != 21) {
  -        fprintf(stderr, "Failed.\natomics do not add up\n");
  -    }
  -    else {
  -        fprintf(stdout, "no threads .. OK\n");
  +    rv = check_basic_atomics(&y);
  +    if (rv != APR_SUCCESS) {
  +        fprintf(stderr, "Failed.\n");
  +        exit(-1);
       }
  -
       return 0;
   }
   #else /* !APR_HAS_THREADS */
  @@ -158,6 +214,7 @@
       apr_thread_exit(thd, exit_ret_val);
       return NULL;
   }
  +
   int main(int argc, char**argv)
   {
       apr_thread_t *t1[NUM_THREADS];
  @@ -190,19 +247,26 @@
   
       apr_thread_once_init(&control, context);
   
  -    printf("%-60s", "Initializing the lock"); 
  -    rv = apr_lock_create(&thread_lock, APR_MUTEX, APR_INTRAPROCESS, 
  -                         APR_LOCK_DEFAULT, "lock.file", context); 
  +    if (mutex==1) {
  +        printf("%-60s", "Initializing the lock"); 
  +        rv = apr_lock_create(&thread_lock, APR_MUTEX, APR_INTRAPROCESS, 
  +                             APR_LOCK_DEFAULT, "lock.file", context); 
  +        if (rv != APR_SUCCESS) {
  +            fflush(stdout);
  +            fprintf(stderr, "Failed\nCould not create lock\n");
  +            exit(-1);
  +        }
  +        printf("OK\n");
  +    }
  +    rv = apr_atomic_init( context);
  +
  +    rv = check_basic_atomics(&y);
       if (rv != APR_SUCCESS) {
  -        fflush(stdout);
  -        fprintf(stderr, "Failed\nCould not create lock\n");
  +        fprintf(stderr, "Failed.\n");
           exit(-1);
       }
  -    rv = apr_atomic_init( context);
       apr_atomic_set(&y,0);
   
  -    printf("OK\n");
  -
       printf("%-60s", "Starting all the threads"); 
       for (i=0;i<NUM_THREADS;i++) {
           if (mutex ==1) 
  @@ -249,7 +313,7 @@
               fflush(stdout);
               fprintf(stderr, 
                       "No!\nThe atomics didn't work?? y = %ld instead of %ld\n",
  -                    apr_atomic_read(&y),
  +                    (long)apr_atomic_read(&y),
                       (long)NUM_THREADS*NUM_ITERATIONS);
           }
           else
  
  
  
  1.6       +17 -17    apr/atomic/unix/apr_atomic.c
  
  Index: apr_atomic.c
  ===================================================================
  RCS file: /home/cvs/apr/atomic/unix/apr_atomic.c,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- apr_atomic.c	17 Feb 2002 20:17:54 -0000	1.5
  +++ apr_atomic.c	19 Feb 2002 23:15:39 -0000	1.6
  @@ -58,10 +58,10 @@
   #include "apr_thread_mutex.h"
   #include "apr_atomic.h"
   
  -#if defined(APR_ATOMIC_NEED_DEFAULT) 
  -
   #if APR_HAS_THREADS
   
  +#if defined(APR_ATOMIC_NEED_DEFAULT) 
  +
   #define NUM_ATOMIC_HASH 7
   /* shift by 2 to get rid of alignment issues */
   #define ATOMIC_HASH(x) (int)(((long)x>>2)%NUM_ATOMIC_HASH)
  @@ -79,10 +79,10 @@
       }
       return APR_SUCCESS;
   }
  -apr_uint32_t apr_atomic_add(volatile apr_atomic_t *mem, long val) 
  +apr_uint32_t apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val) 
   {
       apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
  -    long prev;
  +    apr_uint32_t prev;
          
       if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
           prev = *mem;
  @@ -90,12 +90,13 @@
           apr_thread_mutex_unlock(lock);
           return prev;
       }
  +    printf("debug no workee\n");
       return *mem;
   }
  -apr_uint32_t apr_atomic_set(volatile apr_atomic_t *mem, long val) 
  +apr_uint32_t apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val) 
   {
       apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
  -    long prev;
  +    apr_uint32_t prev;
   
       if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
           prev = *mem;
  @@ -109,7 +110,7 @@
   apr_uint32_t apr_atomic_inc( volatile apr_uint32_t *mem) 
   {
       apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
  -    long prev;
  +    apr_uint32_t prev;
   
       if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
           prev = *mem;
  @@ -122,7 +123,7 @@
   apr_uint32_t apr_atomic_dec(volatile apr_atomic_t *mem) 
   {
       apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
  -    long prev;
  +    apr_uint32_t prev;
   
       if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
           prev = *mem;
  @@ -132,15 +133,13 @@
       }
       return *mem;
   }
  -#if 0
  -/*
  - * linux doesn't have a easy to do this 
  - * so comment it out for the moment
  - */
  -apr_uint32_t apr_atomic_cas(volatile apr_atomic_t *mem,apr_uint32_t with, apr_uint32_t
cmp)
  +
  +#if defined(APR_ATOMIC_NEED_CAS_DEFAULT)
  +
  +long apr_atomic_cas(volatile apr_atomic_t *mem,long with, long cmp)
   {
       apr_thread_mutex_t *lock = hash_mutex[ATOMIC_HASH(mem)];
  -    long prev;
  +    apr_uint32_t prev;
   
       if (apr_thread_mutex_lock(lock) == APR_SUCCESS) {
           prev = *mem;
  @@ -152,7 +151,8 @@
       }
       return *mem;
   }
  -#endif
  -#endif /* APR_HAS_THREADS */
  +#endif /* APR_ATOMIC_NEED_CAS_DEFAULT */
   
   #endif /* APR_ATOMIC_NEED_DEFAULT */
  +
  +#endif /* APR_HAS_THREADS */
  
  
  
  1.7       +89 -5     apr/include/apr_atomic.h
  
  Index: apr_atomic.h
  ===================================================================
  RCS file: /home/cvs/apr/include/apr_atomic.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- apr_atomic.h	18 Feb 2002 06:24:13 -0000	1.6
  +++ apr_atomic.h	19 Feb 2002 23:15:40 -0000	1.7
  @@ -63,6 +63,78 @@
   extern "C" {
   #endif
   
  +/**
  + * @file apr_atomic.h
  + * @brief APR Atomic Operations
  + */
  +/**
  + * @defgroup APR_Atomic Atomic operations
  + * @ingroup APR
  + * @{
  + */
  +
  +/* easiest way to get these documented for the moment */
  +#if defined(DOXYGEN)
  +/**
  + * structure for holding a atomic value.
  + * this number >only< has a 24 bit size on some platforms
  + */
  +typedef apr_atomic_t;
  +
  +/**
  + * @param pool 
  + * this function is required on some platforms to initiliaze the
  + * atomic operation's internal structures
  + * returns APR_SUCCESS on successfull completion
  + */
  +apr_status_t apr_atomic_init(apr_pool_t *p);
  +/**
  + * read the value stored in a atomic variable
  + * @param the pointer
  + * @warning on certain platforms (linux) this number is not
  + * stored directly in the pointer. in others it is 
  + */
  +apr_uint32_t apr_atomic_read(volatile apr_atomic_t *mem);
  +/**
  + * set the value for atomic.
  + * @param the pointer
  + * @param the value
  + * @warning the return value is undefined at the moment
  + */
  +apr_uint32_t apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val);
  +/**
  + * Add 'val' to the atomic variable
  + * @param mem pointer to the atomic value
  + * @param val the addition
  + * @return the old value of the atomic
  + */
  +apr_uint32_t apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val);
  +
  +/**
  + * increment the atomic variable by 1
  + * @param mem pointer to the atomic value
  + * @return the old value of the atomic
  + */
  +apr_uint32_t apr_atomic_inc(volatile apr_atomic_t *mem);
  +
  +/**
  + * decrement the atomic variable by 1
  + * @param mem pointer to the atomic value
  + * @return the old value of the atomic
  + */
  +apr_uint32_t apr_atomic_dec(volatile apr_atomic_t *mem);
  +
  +/**
  + * compare the atomic's value with cmp.
  + * If they are the same swap the value with 'with'
  + * @param mem pointer to the atomic value
  + * @param with what to swap it with
  + * @param the value to compare it to
  + * @return the old value of the atomic
  + */
  +long apr_atomic_cas(volatile apr_atomic_t *mem,long with,long cmp);
  +#else /* !DOXYGEN */
  +
   #ifdef WIN32
   
   #define apr_atomic_t LONG;
  @@ -72,7 +144,7 @@
   #define apr_atomic_inc(mem)          InterlockedIncrement(mem)
   #define apr_atomic_set(mem, val)     InterlockedExchange(mem, val)
   #define apr_atomic_read(mem)         *mem
  -/* #define apr_atomic_cas(mem,with,cmp) InterlockedCompareExchange(mem,with,cmp)*/
  +#define apr_atomic_cas(mem,with,cmp) InterlockedCompareExchange(mem,with,cmp)
   #define apr_atomic_init(pool)        APR_SUCCESS
   
   #elif defined(__linux)
  @@ -86,6 +158,7 @@
   #define apr_atomic_set(mem, val)     atomic_set(mem, val)
   #define apr_atomic_read(mem)         atomic_read(mem)
   #define apr_atomic_init(pool)        APR_SUCCESS
  +#define APR_ATOMIC_NEED_CAS_DEFAULT 1
   
   #elif defined(__FreeBSD__) && (__FreeBSD__ >= 4)
   #include <machine/atomic.h>
  @@ -98,36 +171,47 @@
   #define apr_atomic_read(mem)         *mem
   #define apr_atomic_init(pool)        APR_SUCCESS
   
  +#define APR_ATOMIC_NEED_CAS_DEFAULT 1
   
  -#elif defined(__sparc__not_ready_yet)
  +#elif defined(__sparc__not_yet)
   #define apr_atomic_t apr_uint32_t
   #define apr_atomic_read(p)  *p
   
   #define apr_atomic_add(mem, val)     apr_atomic_add_sparc(mem,val)
   #define apr_atomic_dec(mem)          apr_atomic_sub_sparc(mem,1)
   #define apr_atomic_inc(mem)          apr_atomic_add_sparc(mem,1)
  +#define apr_atomic_cas(mem,val,cond) apr_atomic_cas_sparc(mem,val,cond)
  +#define apr_atomic_casptr(mem,val,cond) apr_atomic_casptr_sparc(mem,val,cond)
   #define apr_atomic_set(mem, val)     *mem= val
   #define apr_atomic_init(pool)        APR_SUCCESS
   
   apr_uint32_t apr_atomic_add_sparc( volatile apr_atomic_t* mem, apr_uint32_t add);
   apr_uint32_t apr_atomic_sub_sparc( volatile apr_atomic_t* mem, apr_uint32_t sub);
  +long apr_atomic_cas_sparc(volatile apr_atomic_t *mem,long with,long cmp);
  +
   #else
   #if APR_HAS_THREADS
   
   #define apr_atomic_t apr_uint32_t
   #define apr_atomic_read(p)  *p
   apr_status_t apr_atomic_init(apr_pool_t *p);
  -apr_uint32_t apr_atomic_set(volatile apr_atomic_t *mem, long val);
  -apr_uint32_t apr_atomic_add(volatile apr_atomic_t *mem, long val);
  +apr_uint32_t apr_atomic_set(volatile apr_atomic_t *mem, apr_uint32_t val);
  +apr_uint32_t apr_atomic_add(volatile apr_atomic_t *mem, apr_uint32_t val);
   apr_uint32_t apr_atomic_inc(volatile apr_atomic_t *mem);
   apr_uint32_t apr_atomic_dec(volatile apr_atomic_t *mem);
  -/*long apr_atomic_cas(volatile apr_atomic_t *mem,long with,long cmp);*/
   
   #define APR_ATOMIC_NEED_DEFAULT 1
  +#define APR_ATOMIC_NEED_CAS_DEFAULT 1
  +
   #endif /* APR_HAS_THREADS */
   
   #endif /* !defined(WIN32) && !defined(__linux) */
   
  +#if defined(APR_ATOMIC_NEED_CAS_DEFAULT)
  +long apr_atomic_cas(volatile apr_atomic_t *mem,long with,long cmp);
  +#endif
  +
  +#endif /* DOXYGEN */
   #ifdef __cplusplus
   }
   #endif
  
  
  

Mime
View raw message