params->uninitvalue = 0;
params->maxexecutions = 10;
params->nofork = false;
+ params->threadsnocleanup = false;
}
static void print_usage(const char *program_name, struct model_params *params)
" Default: %u\n"
" -o help for a list of options\n"
"-n No fork\n"
+#ifdef TLS
+ "-d Don't allow threads to cleanup\n"
+#endif
" -- Program arguments follow.\n\n",
program_name,
params->verbose,
static void parse_options(struct model_params *params, int argc, char **argv)
{
- const char *shortopts = "hnt:o:u:x:v::";
+ const char *shortopts = "hdnt:o:u:x:v::";
const struct option longopts[] = {
{"help", no_argument, NULL, 'h'},
{"verbose", optional_argument, NULL, 'v'},
case 'h':
print_usage(argv[0], params);
break;
+ case 'd':
+ params->threadsnocleanup = true;
+ break;
case 'n':
params->nofork = true;
break;
main_thread_startup();
}
-static bool is_nonsc_write(const ModelAction *act) {
- if (act->get_type() == ATOMIC_WRITE) {
- std::memory_order order = act->get_mo();
- switch(order) {
- case std::memory_order_relaxed:
- case std::memory_order_release:
- return true;
- default:
- return false;
- }
- }
- return false;
-}
-
/** @brief Run ModelChecker for the user program */
void ModelChecker::run()
{
void startMainThread();
void startChecker();
Thread * getInitThread() {return init_thread;}
+ Scheduler * getScheduler() {return scheduler;}
MEMALLOC
private:
/** Flag indicates whether to restart the model checker. */
unsigned int uninitvalue;
int maxexecutions;
bool nofork;
+ bool threadsnocleanup;
/** @brief Verbosity (0 = quiet; 1 = noisy; 2 = noisier) */
int verbose;
#include "context.h"
#include "model.h"
+
+#if USE_MPROTECT_SNAPSHOT
+
/** PageAlignedAdressUpdate return a page aligned address for the
* address being added as a side effect the numBytes are also changed.
*/
return (void *)((((uintptr_t)addr) + PAGESIZE - 1) & ~(PAGESIZE - 1));
}
-#if USE_MPROTECT_SNAPSHOT
-
/* Each SnapShotRecord lists the firstbackingpage that must be written to
* revert to that snapshot */
struct SnapShotRecord {
/* global "model" object */
#include "model.h"
#include "execution.h"
+#include "schedule.h"
#ifdef TLS
#include <dlfcn.h>
if (stack)
stack_free(stack);
#ifdef TLS
- if (this != model->getInitThread()) {
+ if (this != model->getInitThread() && !model->getParams()->threadsnocleanup) {
modellock = 1;
+ ASSERT(thread_current()==NULL);
+ Thread * curr_thread = model->getScheduler()->get_current_thread();
+ //Make any current_thread calls work in code to free
+ model->getScheduler()->set_current_thread(this);
real_pthread_mutex_unlock(&mutex2);
real_pthread_join(thread, NULL);
+ model->getScheduler()->set_current_thread(curr_thread);
modellock = 0;
}
#endif