edits
[cdsspec-compiler.git] / benchmark / linuxrwlocks / linuxrwlocks.c
index 7fb604c52d72259e2ee55c073cdf08b5c61456d9..1f7059f828004926926c0b0682b52cf909804c9d 100644 (file)
@@ -2,11 +2,22 @@
 #include <threads.h>
 #include <stdatomic.h>
 
+#include <spec_lib.h>
+#include <stdlib.h>
+#include <cdsannotate.h>
+#include <specannotation.h>
+#include <model_memory.h>
+#include "common.h"
+
 #include "librace.h"
 
 #define RW_LOCK_BIAS            0x00100000
 #define WRITE_LOCK_CMP          RW_LOCK_BIAS
 
+typedef union {
+       atomic_int lock;
+} rwlock_t;
+
 /** Example implementation of linux rw lock along with 2 thread test
  *  driver... */
 
 
 /**
        @Begin
+       @Options:
+               LANG = C;
        @Global_define:
-               bool __writer_lock_acquired = false;
-               int __reader_lock_cnt = 0;
-       
+               @DeclareVar:
+                       bool writer_lock_acquired;
+                       int reader_lock_cnt;
+               @InitVar:
+                       writer_lock_acquired = false;
+                       reader_lock_cnt = 0;
        @Happens_before:
                # Since commit_point_set has no ID attached, A -> B means that for any B,
                # the previous A happens before B.
+               #Read_Unlock -> Read_Lock
                Read_Unlock -> Write_Lock
                Read_Unlock -> Write_Trylock(HB_Write_Trylock_Succ)
-               
+               #Read_Unlock -> Read_Trylock(HB_Read_Trylock_Succ)
+
                Write_Unlock -> Write_Lock
                Write_Unlock -> Write_Trylock(HB_Write_Trylock_Succ)
 
                Write_Unlock -> Read_Lock
                Write_Unlock -> Read_Trylock(HB_Read_Trylock_Succ)
-       @End
-*/
+       
+       @Commutativity: Read_Lock <-> Read_Lock: true
+       @Commutativity: Read_Lock <-> Read_Unlock: true
+       @Commutativity: Read_Lock <-> Read_Trylock: true
+       @Commutativity: Read_Lock <-> Write_Trylock: !_Method2.__RET__
+       
+       @Commutativity: Read_Unlock <-> Read_Unlock: true
+       @Commutativity: Read_Unlock <-> Read_Trylock: true
+       @Commutativity: Read_Unlock <-> Write_Trylock: !_Method2.__RET__
 
-/**
-       */
+       @Commutativity: Read_Trylock <-> Read_Trylock: true
+       @Commutativity: Read_Trylock <-> Write_Trylock: !_Method1.__RET__ || !_Method2.__RET__
+       @Commutativity: Read_Trylock <-> Write_Lock: !_Method1.__RET__
+       @Commutativity: Read_Trylock <-> Write_Unlock: !_Method1.__RET__
 
-typedef union {
-       atomic_int lock;
-} rwlock_t;
+       @Commutativity: Write_Trylock <-> Write_Trylock: !_Method1.__RET__ || !_Method2.__RET__
+       @Commutativity: Write_Trylock <-> Write_Unlock: !_Method1.__RET__
+       @Commutativity: Write_Trylock <-> Write_Lock: !_Method1.__RET__
+       @End
+*/
 
 static inline int read_can_lock(rwlock_t *lock)
 {
@@ -77,21 +106,19 @@ static inline int write_can_lock(rwlock_t *lock)
 /**
        @Begin
        @Interface: Read_Lock
-       @Commit_point_set:
-               Read_Lock_Success_1 | Read_Lock_Success_2
-       @Check:
-               !__writer_lock_acquired
-       @Action:
-               @Code:
-               __reader_lock_cnt++;
+       @Commit_point_set: Read_Lock_Success_1 | Read_Lock_Success_2
+       @Check: !writer_lock_acquired
+       @Action: reader_lock_cnt++;
        @End
 */
 static inline void read_lock(rwlock_t *rw)
 {
+       
+       /**********  Admissibility  **********/
        int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
        /**
                @Begin
-               @Commit_point_define_check: __ATOMIC_RET__ > 0
+               @Commit_point_define_check: priorvalue > 0
                @Label:Read_Lock_Success_1
                @End
        */
@@ -100,10 +127,11 @@ static inline void read_lock(rwlock_t *rw)
                while (atomic_load_explicit(&rw->lock, memory_order_relaxed) <= 0) {
                        thrd_yield();
                }
+               /**********  Admissibility  **********/
                priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
                /**
                        @Begin
-                       @Commit_point_define_check: __ATOMIC_RET__ > 0
+                       @Commit_point_define_check: priorvalue > 0
                        @Label:Read_Lock_Success_2
                        @End
                */
@@ -114,21 +142,18 @@ static inline void read_lock(rwlock_t *rw)
 /**
        @Begin
        @Interface: Write_Lock
-       @Commit_point_set:
-               Write_Lock_Success_1 | Write_Lock_Success_2
-       @Check:
-               !__writer_lock_acquired && __reader_lock_cnt == 0
-       @Action:
-               @Code:
-               __writer_lock_acquired = true;
+       @Commit_point_set: Write_Lock_Success_1 | Write_Lock_Success_2
+       @Check: !writer_lock_acquired && reader_lock_cnt == 0
+       @Action: writer_lock_acquired = true;
        @End
 */
 static inline void write_lock(rwlock_t *rw)
 {
+       /**********  Admissibility  **********/
        int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
        /**
                @Begin
-               @Commit_point_define_check: __ATOMIC_RET__ == RW_LOCK_BIAS
+               @Commit_point_define_check: priorvalue == RW_LOCK_BIAS
                @Label: Write_Lock_Success_1
                @End
        */
@@ -137,10 +162,11 @@ static inline void write_lock(rwlock_t *rw)
                while (atomic_load_explicit(&rw->lock, memory_order_relaxed) != RW_LOCK_BIAS) {
                        thrd_yield();
                }
+               /**********  Admissibility  **********/
                priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
                /**
                        @Begin
-                       @Commit_point_define_check: __ATOMIC_RET__ == RW_LOCK_BIAS
+                       @Commit_point_define_check: priorvalue == RW_LOCK_BIAS
                        @Label: Write_Lock_Success_2
                        @End
                */
@@ -150,32 +176,42 @@ static inline void write_lock(rwlock_t *rw)
 /**
        @Begin
        @Interface: Read_Trylock
-       @Commit_point_set:
-               Read_Trylock_Point
-       @Condition:
-               __writer_lock_acquired == false
-       @HB_condition:
-               HB_Read_Trylock_Succ :: __RET__ == 1
+       @Commit_point_set: Read_Trylock_Succ_Point | Read_Trylock_Fail_Point
+       //@Condition: writer_lock_acquired == false
+       @HB_condition: HB_Read_Trylock_Succ :: __RET__ == 1
        @Action:
-               @Code:
-               if (COND_SAT)
-                       __reader_lock_cnt++;
-       @Post_check:
-               COND_SAT ? __RET__ == 1 : __RET__ == 0
+               if (__RET__)
+                       reader_lock_cnt++;
+       @Post_check: __RET__ == !writer_lock_acquired || !__RET__
        @End
 */
 static inline int read_trylock(rwlock_t *rw)
 {
+       /**********  Admissibility  **********/
        int priorvalue = atomic_fetch_sub_explicit(&rw->lock, 1, memory_order_acquire);
        /**
                @Begin
-               @Commit_point_define_check: true
-               @Label:Read_Trylock_Point
+               @Potential_commit_point_define: true
+               @Label: Potential_Read_Trylock_Point
                @End
        */
-       if (priorvalue > 0)
+       if (priorvalue > 0) {
+               /**
+                       @Begin
+                       @Commit_point_define: true
+                       @Potential_commit_point_label: Potential_Read_Trylock_Point
+                       @Label:  Read_Trylock_Succ_Point
+                       @End
+               */
                return 1;
-
+       }
+       /**
+               @Begin
+               @Commit_point_define: true
+               @Potential_commit_point_label: Potential_Read_Trylock_Point
+               @Label:  Read_Trylock_Fail_Point
+               @End
+       */
        atomic_fetch_add_explicit(&rw->lock, 1, memory_order_relaxed);
        return 0;
 }
@@ -183,32 +219,41 @@ static inline int read_trylock(rwlock_t *rw)
 /**
        @Begin
        @Interface: Write_Trylock
-       @Commit_point_set:
-               Write_Trylock_Point
-       @Condition:
-               !__writer_lock_acquired && __reader_lock_cnt == 0
-       @HB_condition:
-               HB_Write_Trylock_Succ :: __RET__ == 1
+       @Commit_point_set: Write_Trylock_Succ_Point | Write_Trylock_Fail_Point
+       @HB_condition: HB_Write_Trylock_Succ :: __RET__ == 1
        @Action:
-               @Code:
-               if (COND_SAT)
-                       __writer_lock_acquired = true;
-       @Post_check:
-               COND_SAT ? __RET__ == 1 : __RET__ == 0
+               if (__RET__ == 1)
+                       writer_lock_acquired = true;
        @End
 */
 static inline int write_trylock(rwlock_t *rw)
 {
+       /**********  Admissibility  **********/
        int priorvalue = atomic_fetch_sub_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_acquire);
+       //model_print("write_trylock: priorvalue: %d\n", priorvalue);
        /**
                @Begin
-               @Commit_point_define_check: true
-               @Label: Write_Trylock_Point
+               @Potential_commit_point_define: true
+               @Label: Potential_Write_Trylock_Point
                @End
        */
-       if (priorvalue == RW_LOCK_BIAS)
+       if (priorvalue == RW_LOCK_BIAS) {
+               /**
+                       @Begin
+                       @Commit_point_define: true
+                       @Potential_commit_point_label: Potential_Write_Trylock_Point
+                       @Label: Write_Trylock_Succ_Point
+                       @End
+               */
                return 1;
-
+       }
+       /**
+               @Begin
+               @Commit_point_define: true
+               @Potential_commit_point_label: Potential_Write_Trylock_Point
+               @Label: Write_Trylock_Fail_Point
+               @End
+       */
        atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_relaxed);
        return 0;
 }
@@ -217,15 +262,13 @@ static inline int write_trylock(rwlock_t *rw)
        @Begin
        @Interface: Read_Unlock
        @Commit_point_set: Read_Unlock_Point
-       @Check:
-               __reader_lock_cnt > 0 && !__writer_lock_acquired
-       @Action: 
-               @Code:
-               reader_lock_cnt--;
+       @Check: reader_lock_cnt > 0 && !writer_lock_acquired
+       @Action: reader_lock_cnt--;
        @End
 */
 static inline void read_unlock(rwlock_t *rw)
 {
+       /**********  Admissibility  **********/
        atomic_fetch_add_explicit(&rw->lock, 1, memory_order_release);
        /**
                @Begin
@@ -238,17 +281,14 @@ static inline void read_unlock(rwlock_t *rw)
 /**
        @Begin
        @Interface: Write_Unlock
-       @Commit_point_set: Write_Unlock_Point
-       @Check:
-               reader_lock_cnt == 0 && writer_lock_acquired
-       @Action: 
-               @Code:
-               __writer_lock_acquired = false;
+       @Commit_point_set: Write_Unlock_Point | Write_Unlock_Clear
+       @Check: reader_lock_cnt == 0 && writer_lock_acquired
+       @Action: writer_lock_acquired = false;
        @End
 */
-
 static inline void write_unlock(rwlock_t *rw)
 {
+       /**********  Admissibility  **********/
        atomic_fetch_add_explicit(&rw->lock, RW_LOCK_BIAS, memory_order_release);
        /**
                @Begin
@@ -256,6 +296,13 @@ static inline void write_unlock(rwlock_t *rw)
                @Label: Write_Unlock_Point
                @End
        */
+
+       /**
+               //@Begin
+               @Commit_point_clear: true
+               @Label: Write_Unlock_Clear
+               @End
+       */
 }
 
 rwlock_t mylock;
@@ -263,27 +310,42 @@ int shareddata;
 
 static void a(void *obj)
 {
-       int i;
-       for(i = 0; i < 2; i++) {
-               if ((i % 2) == 0) {
-                       read_lock(&mylock);
-                       load_32(&shareddata);
-                       read_unlock(&mylock);
-               } else {
-                       write_lock(&mylock);
-                       store_32(&shareddata,(unsigned int)i);
-                       write_unlock(&mylock);
-               }
+       read_lock(&mylock);
+       //load_32(&shareddata);
+       //printf("%d\n", shareddata);
+       read_unlock(&mylock);
+       
+       write_lock(&mylock);
+       //store_32(&shareddata,(unsigned int)i);
+       shareddata = 47;
+       write_unlock(&mylock);
+}
+
+static void b(void *obj)
+{
+       if (read_trylock(&mylock) == 1) {
+               //printf("%d\n", shareddata);
+               read_unlock(&mylock);
+       }
+       
+       if (write_trylock(&mylock) == 1) {
+               //shareddata = 47;
+               write_unlock(&mylock);
        }
 }
 
 int user_main(int argc, char **argv)
 {
+       /**
+               @Begin
+               @Entry_point
+               @End
+       */
        thrd_t t1, t2;
        atomic_init(&mylock.lock, RW_LOCK_BIAS);
 
        thrd_create(&t1, (thrd_start_t)&a, NULL);
-       thrd_create(&t2, (thrd_start_t)&a, NULL);
+       thrd_create(&t2, (thrd_start_t)&b, NULL);
 
        thrd_join(t1);
        thrd_join(t2);