@@ -489,6 +489,18 @@ struct e2fsck_struct {
};
#ifdef HAVE_PTHREAD
+#ifdef DEBUG_THREADS
+/*
+ * Enabling DEBUG_THREADS would cause the parallel
+ * fsck threads run sequentially.
+ */
+struct e2fsck_thread_debug {
+ pthread_mutex_t etd_mutex;
+ pthread_cond_t etd_cond;
+ int etd_finished_threads;
+};
+#endif
+
struct e2fsck_thread_info {
/* ID returned by pthread_create() */
pthread_t eti_thread_id;
@@ -498,7 +510,11 @@ struct e2fsck_thread_info {
int eti_started;
/* Context used for this thread */
e2fsck_t eti_thread_ctx;
+#ifdef DEBUG_THREADS
+ struct e2fsck_thread_debug *eti_debug;
+#endif
};
+
#endif
/* Data structures to evaluate whether an extent tree needs rebuilding. */
@@ -2575,6 +2575,18 @@ static void *e2fsck_pass1_thread(void *arg)
{
struct e2fsck_thread_info *info = arg;
e2fsck_t thread_ctx = info->eti_thread_ctx;
+#ifdef DEBUG_THREADS
+ struct e2fsck_thread_debug *thread_debug = info->eti_debug;
+#endif
+
+#ifdef DEBUG_THREADS
+ pthread_mutex_lock(&thread_debug->etd_mutex);
+ while (info->eti_thread_index > thread_debug->etd_finished_threads) {
+ pthread_cond_wait(&thread_debug->etd_cond,
+ &thread_debug->etd_mutex);
+ }
+ pthread_mutex_unlock(&thread_debug->etd_mutex);
+#endif
#ifdef HAVE_SETJMP_H
/*
@@ -2599,6 +2611,14 @@ out:
thread_ctx->thread_info.et_group_start,
thread_ctx->thread_info.et_group_end,
thread_ctx->thread_info.et_inode_number);
+
+#ifdef DEBUG_THREADS
+ pthread_mutex_lock(&thread_debug->etd_mutex);
+ thread_debug->etd_finished_threads++;
+ pthread_cond_broadcast(&thread_debug->etd_cond);
+ pthread_mutex_unlock(&thread_debug->etd_mutex);
+#endif
+
return NULL;
}
@@ -2612,6 +2632,12 @@ static int e2fsck_pass1_threads_start(struct e2fsck_thread_info **pinfo,
struct e2fsck_thread_info *tmp_pinfo;
int i;
e2fsck_t thread_ctx;
+#ifdef DEBUG_THREADS
+ struct e2fsck_thread_debug thread_debug =
+ {PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, 0};
+
+ thread_debug.etd_finished_threads = 0;
+#endif
retval = pthread_attr_init(&attr);
if (retval) {
@@ -2632,6 +2658,9 @@ static int e2fsck_pass1_threads_start(struct e2fsck_thread_info **pinfo,
for (i = 0; i < num_threads; i++) {
tmp_pinfo = &infos[i];
tmp_pinfo->eti_thread_index = i;
+#ifdef DEBUG_THREADS
+ tmp_pinfo->eti_debug = &thread_debug;
+#endif
retval = e2fsck_pass1_thread_prepare(global_ctx, &thread_ctx,
i, num_threads);
if (retval) {