/* setup and create a groups threads */ int create_group(struct group_parameters *group) { int status; pthread_attr_t thread_attr; cpu_set_t mask; /* initialize group structure */ status = initialize_group(group); if (status) { error("initializing group %d\n", group->id); return FAILURE; } CPU_ZERO(&mask); CPU_SET(group->cpu, &mask); debug("group %d bound to cpu %ld\n", group->id, group->cpu); /* start the low priority thread */ debug("creating low priority thread\n"); if (setup_thread_attr(&thread_attr, LOW_PRIO(), &mask, policy)) return FAILURE; status = pthread_create(&group->low_tid, &thread_attr, low_priority, group); if (status != 0) { error("creating low_priority thread: %s\n", strerror(status)); return FAILURE; } /* create the medium priority thread */ debug("creating medium priority thread\n"); if (setup_thread_attr(&thread_attr, MED_PRIO(), &mask, policy)) return FAILURE; status = pthread_create(&group->med_tid, &thread_attr, med_priority, group); if (status != 0) { error("creating med_priority thread: %s\n", strerror(status)); return FAILURE; } /* create the high priority thread */ debug("creating high priority thread\n"); if (setup_thread_attr(&thread_attr, HIGH_PRIO(), &mask, policy)) return FAILURE; status = pthread_create(&group->high_tid, &thread_attr, high_priority, group); if (status != 0) { error("creating high_priority thread: %s\n", strerror(status)); set_shutdown_flag(); return FAILURE; } return SUCCESS; }
extern int libcheck_check (struct checker * c) { struct tur_checker_context *ct = c->context; struct timespec tsp; struct stat sb; pthread_attr_t attr; int tur_status, r; if (!ct) return PATH_UNCHECKED; if (fstat(c->fd, &sb) == 0) ct->devt = sb.st_rdev; if (c->sync) return tur_check(c); /* * Async mode */ r = pthread_mutex_lock(&ct->lock); if (r != 0) { condlog(2, "%d:%d: tur mutex lock failed with %d", TUR_DEVT(ct), r); MSG(c, MSG_TUR_FAILED); return PATH_WILD; } if (ct->running) { /* Check if TUR checker is still running */ if (ct->thread) { if (tur_check_async_timeout(c)) { condlog(3, "%d:%d: tur checker timeout", TUR_DEVT(ct)); pthread_cancel(ct->thread); ct->running = 0; MSG(c, MSG_TUR_TIMEOUT); tur_status = PATH_DOWN; ct->state = PATH_UNCHECKED; } else { condlog(3, "%d:%d: tur checker not finished", TUR_DEVT(ct)); ct->running++; tur_status = PATH_PENDING; } } else { /* TUR checker done */ ct->running = 0; tur_status = ct->state; } pthread_mutex_unlock(&ct->lock); } else { if (ct->thread) { /* pthread cancel failed. continue in sync mode */ pthread_mutex_unlock(&ct->lock); condlog(3, "%d:%d: tur thread not responding, " "using sync mode", TUR_DEVT(ct)); return tur_check(c); } /* Start new TUR checker */ ct->state = PATH_UNCHECKED; tur_set_async_timeout(c); setup_thread_attr(&attr, 32 * 1024, 1); r = pthread_create(&ct->thread, &attr, tur_thread, c); if (r) { pthread_mutex_unlock(&ct->lock); ct->thread = 0; condlog(3, "%d:%d: failed to start tur thread, using" " sync mode", TUR_DEVT(ct)); return tur_check(c); } pthread_attr_destroy(&attr); tur_timeout(&tsp); r = pthread_cond_timedwait(&ct->active, &ct->lock, &tsp); tur_status = ct->state; pthread_mutex_unlock(&ct->lock); if (ct->thread && (tur_status == PATH_PENDING || tur_status == PATH_UNCHECKED)) { condlog(3, "%d:%d: tur checker still running", TUR_DEVT(ct)); ct->running = 1; tur_status = PATH_PENDING; } } return tur_status; }