/* TAGS: c sym threads big */ /* VERIFY_OPTS: --symbolic --svcomp -o nofail:malloc */ extern void __VERIFIER_assume(int); extern void __VERIFIER_error() __attribute__ ((__noreturn__)); extern int __VERIFIER_nondet_int(); #include #define assume(e) __VERIFIER_assume(e) #define assert_nl(e) { if(!(e)) { goto ERROR; } } #define assert(e) { if(!(e)) { ERROR: __VERIFIER_error();(void)0; } } void __VERIFIER_atomic_CAS( volatile int *v, int e, int u, int *r) { if(*v == e) { *v = u, *r = 1; } else { *r = 0; } } #define WORKPERTHREAD 2 #define THREADSMAX 3 volatile int max = 0x80000000; int storage[WORKPERTHREAD*THREADSMAX]; static inline void findMax(int offset){ int i; int e; int my_max = 0x80000000; int c; int cret; for(i = offset; i < offset+WORKPERTHREAD; i++) { e = storage[i]; if(e > my_max) { my_max = e; } assert_nl(e <= my_max); } while(1){ c = max; if(my_max > c){ __VERIFIER_atomic_CAS(&max,c,my_max,&cret); if(cret){ break; } }else{ break; } } assert(my_max <= max); } void* thr1(void* arg) { int offset=__VERIFIER_nondet_int(); assume(offset % WORKPERTHREAD == 0 && offset >= 0 && offset < WORKPERTHREAD*THREADSMAX); //assume(offset < WORKPERTHREAD && offset >= 0 && offset < WORKPERTHREAD*THREADSMAX); findMax(offset); return 0; } int main(){ pthread_t t; while(1) { pthread_create(&t, 0, thr1, 0); } }