extern int __VERIFIER_nondet_int(void); extern unsigned long __VERIFIER_nondet_ulong(void); extern unsigned char __VERIFIER_nondet_uchar(void); extern void abort(void); void assume_abort_if_not(int cond) { if(!cond) {abort();} } extern void abort(void); #include void reach_error() { assert(0); } /* Generated by CSeq 0.5 (-t4 -r2 -fcbmc) 2013-06-08 02:22:20 */ #include #include void __VERIFIER_assert(int cond) { if (!(cond)) { ERROR: {reach_error();abort();} } return; } #define __CS_type unsigned char #define __CS_pthread_t unsigned char #define __CS_pthread_mutex_t unsigned char #define __CS_pthread_cond_t unsigned char //cseq: max no. of rounds and threads (parameters for the translation) #define __CS_ROUNDS 2 #define __CS_THREADS 4 //cseq: main extra variables used for the simulation //// __CS_type __k; __CS_type __CS_round = 0; //cseq: index of the current round being simulated __CS_type __CS_ret = 0; //cseq: thread exit conditions const __CS_type __CS_ret_PREEMPTED = 0x01; //cseq: context-switch happened before thread end const __CS_type __CS_ret_ERROR = 0x02; //cseq: thread returned due to an error condition const __CS_type __CS_ret_FINISHED = 0x04; //cseq: thread finished without errors happening __CS_type __CS_error = 0; //cseq: set whenever an error is found and checked after thread-wrapping /* __CS_type __CS_error_detail = 0; //cseq: error condition details (tells why __CS_error was set) const __CS_type __ERR_MAXTHREADS_REACHED = 0x01; const __CS_type __ERR_ERROR_LABEL_REACHED = 0x02; const __CS_type __ERR_ASSERT_FAILURE = 0x04; const __CS_type __ERR_UNLOCK_ATTEMPT = 0x08; const __CS_type __ERR_JOIN_FAILED_WRONG_THREAD_ID = 0x10; const __CS_type __ERR_JOIN_FAILED_THREAD_NOT_CREATED = 0x20; const __CS_type __ERR_COND_WAIT_MUTEX_NOT_OWNED = 0x30; const __CS_type __ERR_MUTEX_DESTROY = 0x40; const __CS_type __ERR_MUTEX_NOT_OWNED = 0x80; */ //cseq: handling of the status of the threads __CS_type __CS_thread_index; //cseq: currently running thread ranging in [1..max+1], 1 being main() __CS_type __CS_thread_allocated[__CS_THREADS+1]; //cseq: threads used in the simulation __CS_type __CS_thread_born_round[__CS_THREADS+1]; //cseq: round when a thread is born void *(*__CS_thread[__CS_THREADS+1])(void *); //cseq: pointers to thread functions __CS_type __CS_thread_status[__CS_ROUNDS][__CS_THREADS+1]; //cseq: thread status at a round const __CS_type __THREAD_UNUSED = 0x00; //cseq: not used const __CS_type __THREAD_RUNNING = 0x01; //cseq: successfully created const __CS_type __THREAD_FINISHED = 0x02; //cseq: finished with errors or without errors /* const __CS_type __THREAD_FINISHED_ERROR = 0x02; //cseq: finished with errors const __CS_type __THREAD_FINISHED_NO_ERROR = 0x04; //cseq: finished without errors */ __CS_type *__CS_thread_lockedon[__CS_ROUNDS][__CS_THREADS+1]; //cseq: threads waiting for conditional variables /* //cseq: size of dynamically allocated memory blocks, indexed by var ID int __CS_size[__CS_ROUNDS][9]; int __CS_cp___CS_size[__CS_ROUNDS][9]; */ /* unsigned int __CS_SwitchPoints[__CS_ROUNDS]; unsigned int __CS_StmtCount; unsigned int __CS_SwitchDone; */ //cseq: function declarations int __VERIFIER_nondet_int(); void __CS_cs(void) { __CS_type k = __VERIFIER_nondet_uchar(); assume_abort_if_not(__CS_round+k < __CS_ROUNDS); // k==0 --> no switch __CS_round += k; // this is removed when not needed // __CS_ret = (__VERIFIER_nondet_int() && __CS_round == __CS_ROUNDS-1)?1:__CS_ret; // preemption __CS_ret = (__VERIFIER_nondet_int() && __CS_round == __CS_ROUNDS-1)?__CS_ret_PREEMPTED:__CS_ret; } /* void __CS_cs(void) { if (__CS_SwitchDone == __CS_ROUNDS-1) return; if (__CS_SwitchPoints[__CS_SwitchDone] == __CS_StmtCount++) { __CS_type k; assume_abort_if_not(__CS_round+k < __CS_ROUNDS); // k==__CS_round --> no switch __CS_round += k; //assume_abort_if_not(__CS_thread_lockedon[__CS_round][__CS_thread_index] == 0); __CS_SwitchDone++; //__CS_StmtCount = 0; } } */ int __CS_pthread_mutex_init(__CS_pthread_mutex_t *mutex, void *attr) { return 0; } int __CS_pthread_mutex_destroy(__CS_pthread_mutex_t *lock) { if (*lock != __CS_thread_index && *lock != 0) { __CS_error = 1; __CS_ret = __CS_ret_ERROR; //__CS_error_detail = __ERR_MUTEX_DESTROY; } else *lock = 0; return 0; } int __CS_pthread_mutex_lock(__CS_pthread_mutex_t *lock) { if (*lock == 0) *lock = (__CS_thread_index+1); else { __CS_ret = __CS_ret_PREEMPTED; return 1; } return 0; } int __CS_pthread_mutex_unlock(__CS_pthread_mutex_t *lock) { if (*lock != (__CS_thread_index+1)) { __CS_error = 1; __CS_ret = __CS_ret_ERROR; //__CS_error_detail = __ERR_UNLOCK_ATTEMPT; return 1; } else *lock = 0; return 0; } int __CS_pthread_cond_init(__CS_pthread_cond_t *cond, void *attr) { return 0; } int __CS_pthread_cond_signal(__CS_pthread_cond_t *cond) { int j; for (j=0; j<=__CS_THREADS; j++) if (__CS_thread_lockedon[__CS_round][j] == cond) __CS_thread_lockedon[__CS_round][j] = 0; return 0; } int __CS_pthread_cond_broadcast(__CS_pthread_cond_t *cond) { int j; for (j=0; j<=__CS_THREADS; j++) if (__CS_thread_lockedon[__CS_round][j] == cond) __CS_thread_lockedon[__CS_round][j] = 0; return 0; } int __CS_pthread_cond_wait(__CS_pthread_cond_t *cond, __CS_pthread_mutex_t *lock) { // __CS_pthread_mutex_unlock(mutex); if (*lock != (__CS_thread_index+1)) { __CS_error = 1; __CS_ret = __CS_ret_ERROR; //__CS_error_detail = __ERR_COND_WAIT_MUTEX_NOT_OWNED; return 1; } else *lock = 0; __CS_thread_lockedon[__CS_round][__CS_thread_index] = cond; __CS_ret = __CS_ret_PREEMPTED; // force context-switch // __CS_pthread_mutex_lock(mutex); if (*lock == 0) *lock = __CS_thread_index+1; else { __CS_ret = __CS_ret_PREEMPTED; return 1; } return 0; } void __CS_assert(int expr) { if (!expr) { __CS_error = 1; //__CS_error_detail = __ERR_ASSERT_FAILURE; __CS_ret = __CS_ret_ERROR; } } void __CS_assume(int expr) { if (!expr) __CS_ret = __CS_ret_PREEMPTED; } int __CS_pthread_join(__CS_pthread_t thread, void **value_ptr) { // checking index range if (thread != 123 && thread > __CS_THREADS+1) { __CS_error = 1; //__CS_error_detail = __ERR_JOIN_FAILED_WRONG_THREAD_ID; __CS_ret = __CS_ret_ERROR; return 0; } if ( thread == 123 || __CS_thread_status[__CS_round][thread] == __THREAD_RUNNING ) { __CS_ret = __CS_ret_PREEMPTED; return 0; } if (__CS_thread_status[__CS_round][thread] == __THREAD_UNUSED) { __CS_error = 1; //__CS_error_detail = __ERR_JOIN_FAILED_THREAD_NOT_CREATED; __CS_ret = __CS_ret_ERROR; return 0; } /* assume_abort_if_not( __CS_thread_status[__CS_round][thread] == __THREAD_FINISHED_ERROR || __CS_thread_status[__CS_round][thread] == __THREAD_FINISHED_NO_ERROR ); */ assume_abort_if_not( __CS_thread_status[__CS_round][thread] == __THREAD_FINISHED ); return 0; } int __CS_pthread_create(__CS_pthread_t *id1, void *attr, void *(*t1)(void*), void *arg) { /* if (__VERIFIER_nondet_int()) { *id = -1; return -1; } */ /* if (__CS_thread_index == __CS_THREADS+1) { __CS_error = 1; __CS_ret = __CS_ret_ERROR; __CS_error_detail = __ERR_MAXTHREADS_REACHED; return 1; } */ if (__CS_thread_index == __CS_THREADS) { *id1 = 123; return -1; } __CS_thread_index++; __CS_thread_allocated[__CS_thread_index] = 1; __CS_thread_born_round[__CS_thread_index] = __CS_round; __CS_thread[__CS_thread_index] = t1; __CS_thread_status[__CS_round][__CS_thread_index] = __THREAD_RUNNING; *id1 = __CS_thread_index; return __CS_thread_index; } /* void *__CS_malloc(int varID, int size) { __CS_size[__CS_round][varID] = size; return malloc((size_t)size); } void __CS_free(int varID, void *ptr) { __CS_size[__CS_round][varID] = 0; } int __CS_memcmp(void *a, void *b, int size) { int j; for (j=0; j