[PATCH 1/5] [RFC] Introduce multi-thread to search_virtual

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch will introduce multithread for search_virtual.

The main process, aka readmem, will fill a zone of page buffers, then notify
search_value threads to start. A pthread barrier is used for such main process
and threads synchronization. For the search_value threads, they are always
working on a same zone, the search results are cached within a output_buffer
of each thread. If one thread finishes earlier, it have to wait untill other
threads finish. The last finished thread is responsible for output search
results in order. After all work done, search_value threads will work on the
next zone.

Signed-off-by: Tao Liu <ltao@xxxxxxxxxx>
---
 defs.h   |   6 +
 memory.c | 447 ++++++++++++++++++++++++++++++++++++++++++++-----------
 task.c   |  14 ++
 3 files changed, 382 insertions(+), 85 deletions(-)

diff --git a/defs.h b/defs.h
index 12ad6aa..c58272c 100644
--- a/defs.h
+++ b/defs.h
@@ -5705,6 +5705,11 @@ int dump_inode_page(ulong);
 ulong valid_section_nr(ulong);
 void display_memory_from_file_offset(ulonglong, long, void *);
 void swap_info_init(void);
+typedef struct cache_output {
+	char **output_buf;
+	int *output_buf_size;
+	int *output_buf_offset;
+} cache_output_t;
 
 /*
  *  filesys.c 
@@ -5950,6 +5955,7 @@ void sort_tgid_array(void);
 int sort_by_tgid(const void *, const void *);
 int in_irq_ctx(ulonglong, int, ulong);
 void check_stack_overflow(void);
+void print_task_header_para(struct task_context *, int, cache_output_t *);
 
 /*
  *  extensions.c
diff --git a/memory.c b/memory.c
index 592a5ef..c396b07 100644
--- a/memory.c
+++ b/memory.c
@@ -22,6 +22,8 @@
 #include <netinet/in.h>
 #include <byteswap.h>
 #include "maple_tree.h"
+#include <pthread.h>
+#include <semaphore.h>
 
 struct meminfo {           /* general purpose memory information structure */
         ulong cache;       /* used by the various memory searching/dumping */
@@ -136,6 +138,9 @@ struct searchinfo {
 		} s_chars;
 	} s_parms;
 	char buf[BUFSIZE];
+	ulong thread_num;
+	ulong page_buf_zone_num;
+	ulong factor;
 };
 
 struct handle_each_vm_area_args {
@@ -241,9 +246,9 @@ static int page_to_phys(ulong, physaddr_t *);
 static void display_memory(ulonglong, long, ulong, int, void *); 
 static char *show_opt_string(struct searchinfo *);
 static void display_with_pre_and_post(void *, ulonglong, struct searchinfo *);
-static ulong search_ulong(ulong *, ulong, int, struct searchinfo *);
-static ulong search_uint(ulong *, ulong, int, struct searchinfo *);
-static ulong search_ushort(ulong *, ulong, int, struct searchinfo *);
+static ulong search_ulong(ulong *, ulong, int, struct searchinfo *, struct searchinfo *, void *);
+static ulong search_uint(ulong *, ulong, int, struct searchinfo *, struct searchinfo *, void *);
+static ulong search_ushort(ulong *, ulong, int, struct searchinfo *, struct searchinfo *, void *);
 static ulong search_chars(ulong *, ulong, int, struct searchinfo *);
 static ulonglong search_ulong_p(ulong *, ulonglong, int, struct searchinfo *);
 static ulonglong search_uint_p(ulong *, ulonglong, int, struct searchinfo *);
@@ -14928,25 +14933,57 @@ display_with_pre_and_post(void *bufptr, ulonglong addr, struct searchinfo *si)
 }
 
 static ulong
-search_ulong(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
+search_ulong(ulong *bufptr, ulong addr, int longcnt,
+	     struct searchinfo *si, struct searchinfo *si_orig, void *priv)
 {
 	int i;
+	cache_output_t *co = (cache_output_t *)priv;
+	char *buf;
+
 	ulong mask = si->s_parms.s_ulong.mask;
 	for (i = 0; i < longcnt; i++, bufptr++, addr += sizeof(long)) {
 		for (si->val = 0; si->val < si->vcnt; si->val++) {
 			if (SEARCHMASK(*bufptr) == 
 			    SEARCHMASK(si->s_parms.s_ulong.value[si->val])) {
 				if (si->do_task_header) {
-					print_task_header(fp, si->task_context, 
-						si->tasks_found);
-					si->do_task_header = FALSE;
-					si->tasks_found++;
+					if (co)
+						print_task_header_para(si->task_context,
+							si->tasks_found, co);
+					else
+						print_task_header(fp, si->task_context,
+							si->tasks_found);
+					si_orig->do_task_header = si->do_task_header = FALSE;
+					si_orig->tasks_found = ++si->tasks_found;
 				}
 				if (si->context)
 					display_with_pre_and_post(bufptr, addr, si);
-				else 
-					fprintf(fp, "%lx: %lx %s\n", addr, *bufptr,
-						show_opt_string(si));
+				else {
+					if (co) {
+						*co->output_buf_offset += snprintf(
+						    *co->output_buf +
+							*co->output_buf_offset,
+						    *co->output_buf_size -
+							*co->output_buf_offset,
+						    "%lx: %lx %s\n",
+						    addr, *bufptr,
+						    show_opt_string(si));
+						if (*co->output_buf_offset >=
+						    *co->output_buf_size >> 1) {
+							*co->output_buf_size <<= 1;
+							buf = *co->output_buf;
+							if (!(*co->output_buf =
+							    malloc(*co->output_buf_size))) {
+							    error(FATAL, "cannot malloc"
+								" more output buffer");
+							}
+							memcpy(*co->output_buf, buf,
+							    *co->output_buf_offset);
+							free(buf);
+						}
+					} else
+						fprintf(fp, "%lx: %lx %s\n", addr, *bufptr,
+							show_opt_string(si));
+				}
 			}
                 }
 	}
@@ -14975,28 +15012,59 @@ search_ulong_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si
 }
 
 static ulong
-search_uint(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
+search_uint(ulong *bufptr, ulong addr, int longcnt,
+	    struct searchinfo *si, struct searchinfo *si_orig, void *priv)
 {
 	int i;
 	int cnt = longcnt * (sizeof(long)/sizeof(int));
 	uint *ptr = (uint *)bufptr;
 	uint mask = si->s_parms.s_uint.mask;
+	cache_output_t *co = (cache_output_t *)priv;
+	char *buf;
 
 	for (i = 0; i < cnt; i++, ptr++, addr += sizeof(int)) {
 		for (si->val = 0; si->val < si->vcnt; si->val++) {
 			if (SEARCHMASK(*ptr) == 
 			    SEARCHMASK(si->s_parms.s_uint.value[si->val])) {
 				if (si->do_task_header) {
-					print_task_header(fp, si->task_context, 
-						si->tasks_found);
-					si->do_task_header = FALSE;
-					si->tasks_found++;
+					if (co)
+						print_task_header_para(si->task_context,
+							si->tasks_found, co);
+					else
+						print_task_header(fp, si->task_context,
+							si->tasks_found);
+					si_orig->do_task_header = si->do_task_header = FALSE;
+					si_orig->tasks_found = ++si->tasks_found;
 				}
 				if (si->context)
 					display_with_pre_and_post(ptr, addr, si);
-				else
-					fprintf(fp, "%lx: %x %s\n", addr, *ptr, 
-						show_opt_string(si));
+				else {
+					if (co) {
+						*co->output_buf_offset += snprintf(
+						    *co->output_buf +
+							*co->output_buf_offset,
+						    *co->output_buf_size -
+							*co->output_buf_offset,
+						    "%lx: %lx %s\n",
+						    addr, *bufptr,
+						    show_opt_string(si));
+						if (*co->output_buf_offset >=
+						    *co->output_buf_size >> 1) {
+							*co->output_buf_size <<= 1;
+							buf = *co->output_buf;
+							if (!(*co->output_buf =
+							    malloc(*co->output_buf_size))) {
+							    error(FATAL, "cannot malloc"
+								" more output buffer");
+							}
+							memcpy(*co->output_buf, buf,
+							    *co->output_buf_offset);
+							free(buf);
+						}
+					} else
+						fprintf(fp, "%lx: %x %s\n", addr, *ptr,
+							show_opt_string(si));
+				}
 			}
                 }
 	}
@@ -15028,28 +15096,62 @@ search_uint_p(ulong *bufptr, ulonglong addr, int longcnt, struct searchinfo *si)
 }
 
 static ulong
-search_ushort(ulong *bufptr, ulong addr, int longcnt, struct searchinfo *si)
+search_ushort(ulong *bufptr, ulong addr, int longcnt,
+	      struct searchinfo *si, struct searchinfo *si_orig, void *priv)
 {
 	int i;
 	int cnt = longcnt * (sizeof(long)/sizeof(short));
 	ushort *ptr = (ushort *)bufptr;
 	ushort mask = si->s_parms.s_ushort.mask;
+	cache_output_t *co = (cache_output_t *)priv;
+	char *buf;
 
 	for (i = 0; i < cnt; i++, ptr++, addr += sizeof(short)) {
 		for (si->val = 0; si->val < si->vcnt; si->val++) {
 			if (SEARCHMASK(*ptr) == 
 			    SEARCHMASK(si->s_parms.s_ushort.value[si->val])) {
 				if (si->do_task_header) {
-					print_task_header(fp, si->task_context, 
-						si->tasks_found);
-					si->do_task_header = FALSE;
-					si->tasks_found++;
+					if (co)
+						print_task_header_para(
+							si->task_context,
+							si->tasks_found, co);
+					else
+						print_task_header(fp,
+							si->task_context,
+							si->tasks_found);
+					si_orig->do_task_header =
+						si->do_task_header = FALSE;
+					si_orig->tasks_found = ++si->tasks_found;
 				}
 				if (si->context)
 					display_with_pre_and_post(ptr, addr, si);
-				else
-					fprintf(fp, "%lx: %x %s\n", addr, *ptr, 
-						show_opt_string(si));
+				else {
+					if (co) {
+						*co->output_buf_offset += snprintf(
+						    *co->output_buf +
+							*co->output_buf_offset,
+						    *co->output_buf_size -
+							*co->output_buf_offset,
+						    "%lx: %lx %s\n",
+						    addr, *bufptr,
+						    show_opt_string(si));
+						if (*co->output_buf_offset >=
+						    *co->output_buf_size >> 1) {
+							*co->output_buf_size <<= 1;
+							buf = *co->output_buf;
+							if (!(*co->output_buf =
+							    malloc(*co->output_buf_size))) {
+							    error(FATAL, "cannot malloc"
+								" more output buffer");
+							}
+							memcpy(*co->output_buf, buf,
+							    *co->output_buf_offset);
+							free(buf);
+						}
+					} else
+						fprintf(fp, "%lx: %x %s\n", addr, *ptr,
+							show_opt_string(si));
+				}
 			}
                 }
 	}
@@ -15101,6 +15203,34 @@ ulonglong cross_match_next_addr_p; /* the expected starting value of the next ph
 	
 #define CHARS_CTX 56
 
+typedef struct page_buf {
+       char *pagebuf;
+       ulonglong ppp;
+       ulonglong pnext;
+       int lastpage;
+} page_buf_t;
+page_buf_t *page_buf;
+
+typedef struct thread_data {
+	int *start;
+	int *end;
+	int *exit;
+	struct searchinfo *si;
+	char *output_buf;
+	int output_buf_size;
+	int output_buf_offset;
+	struct thread_data *td;
+
+	// For thread sync
+	int *page_buf_zone_index;
+	sem_t *empty_page_buf_zone_count;
+	pthread_barrier_t *barrier;
+	int *finished_thread_count;
+	pthread_mutex_t *finished_thread_count_mutex;
+
+	int thread_index;
+} thread_data_t;
+
 static void
 report_match(struct searchinfo *si, ulong addr, char *ptr1, int len1, char *ptr2, int len2)
 {
@@ -15285,50 +15415,184 @@ search_chars_p(ulong *bufptr, ulonglong addr_p, int longcnt, struct searchinfo *
 	return addr_p;
 }
 
+static void *
+do_search_virtual(void *args)
+{
+	ulong *ubp;
+	ulong pp, next;
+	ulong end;
+	int wordcnt, lastpage;
+	struct searchinfo si;
+	int i, page_buf_zone_index, page_buf_num_per_zone;
+	cache_output_t cache_output;
+
+	thread_data_t *td = (thread_data_t *)args;
+	end = td->si->vaddr_end;
+	memcpy(&si, td->si, sizeof(struct searchinfo));
+	cache_output.output_buf = &td->output_buf;
+	cache_output.output_buf_size = &td->output_buf_size;
+	cache_output.output_buf_offset = &td->output_buf_offset;
+	page_buf_num_per_zone = si.thread_num * si.factor;
+
+	while (1) {
+		pthread_barrier_wait(td->barrier);
+		page_buf_zone_index = *td->page_buf_zone_index;
+		for (i = td->start[page_buf_zone_index];
+		     i < td->end[page_buf_zone_index];
+		     i++) {
+			pp = (page_buf + page_buf_num_per_zone *
+					page_buf_zone_index)[i].ppp;
+			next = (page_buf + page_buf_num_per_zone *
+					page_buf_zone_index)[i].pnext;
+			lastpage = (page_buf + page_buf_num_per_zone *
+					page_buf_zone_index)[i].lastpage;
+
+			ubp = (ulong *)&(page_buf + page_buf_num_per_zone *
+						page_buf_zone_index)[i]
+						.pagebuf[next - pp];
+			if (lastpage) {
+				if (end == (ulong)(-1))
+					wordcnt = PAGESIZE()/sizeof(long);
+				else
+					wordcnt = (end - next)/sizeof(long);
+			} else
+				wordcnt = (PAGESIZE() - (next - pp))/sizeof(long);
+
+			switch (td->si->mode)
+			{
+			case SEARCH_ULONG:
+				next = search_ulong(ubp, next, wordcnt,
+						    &si, td->si, &cache_output);
+				break;
+			case SEARCH_UINT:
+				next = search_uint(ubp, next, wordcnt,
+						   &si, td->si, &cache_output);
+				break;
+			case SEARCH_USHORT:
+				next = search_ushort(ubp, next, wordcnt,
+						     &si, td->si, &cache_output);
+				break;
+			case SEARCH_CHARS:
+				next = search_chars(ubp, next, wordcnt, si);
+				break;
+			default:
+				/* unimplemented search type */
+				next += wordcnt * (sizeof(long));
+				break;
+			}
+		}
+		pthread_mutex_lock(td->finished_thread_count_mutex);
+		if (++(*td->finished_thread_count) == si.thread_num) {
+			pthread_mutex_unlock(td->finished_thread_count_mutex);
+			for (i = 0; i < si.thread_num; i++) {
+				fprintf(fp, "%s", (td->td + i)->output_buf);
+				*((td->td + i)->output_buf) = '\0';
+				(td->td + i)->output_buf_offset = 0;
+			}
+			*td->page_buf_zone_index = (page_buf_zone_index + 1) %
+							si.page_buf_zone_num;
+			(*td->finished_thread_count) = 0;
+
+			sem_post(td->empty_page_buf_zone_count);
+		} else {
+			pthread_mutex_unlock(td->finished_thread_count_mutex);
+		}
+		if (td->exit[page_buf_zone_index]) {
+			break;
+		}
+	}
+	return NULL;
+}
+
 static void
 search_virtual(struct searchinfo *si)
 {
 	ulong start, end;
-	ulong pp, next, *ubp;
-	int wordcnt, lastpage;
+	ulong next, pp;
 	ulong page;
-	physaddr_t paddr; 
-	char *pagebuf;
+	physaddr_t paddr;
+	int i, st, ed;
 	ulong pct, pages_read, pages_checked;
 	time_t begin, finish;
-
-	start = si->vaddr_start;
-	end = si->vaddr_end;
+	int page_buf_zone_index = 0;
+	int page_buf_index;
+	int thread_num = si->thread_num;
+	int page_buf_num_per_zone = thread_num * si->factor;
 	pages_read = pages_checked = 0;
 	begin = finish = 0;
 
-	pagebuf = GETBUF(PAGESIZE());
+	// For thread sync
+	sem_t empty_page_buf_zone_count;
+	pthread_barrier_t barrier;
+	pthread_t *threads;
+	thread_data_t *td;
+	int finished_thread_count = 0;
+	pthread_mutex_t finished_thread_count_mutex = PTHREAD_MUTEX_INITIALIZER;
+	int thread_page_buf_zone_index = 0;
+	sem_init(&empty_page_buf_zone_count, 0, si->page_buf_zone_num);
+	pthread_barrier_init(&barrier, NULL, thread_num + 1);
+
+	// Alloc buffers
+	page_buf = (page_buf_t *)GETBUF(sizeof(page_buf_t) *
+		si->page_buf_zone_num * page_buf_num_per_zone);
+	threads = (pthread_t *)GETBUF(sizeof(pthread_t) * thread_num);
+	td = (thread_data_t *)GETBUF(sizeof(thread_data_t) * thread_num);
+	memset(threads, 0, sizeof(sizeof(pthread_t) * thread_num));
+	memset(td, 0, sizeof(thread_data_t) * thread_num);
+	memset(page_buf, 0, sizeof(struct page_buf) * si->page_buf_zone_num *
+				page_buf_num_per_zone);
+	for (i = 0; i < si->page_buf_zone_num * page_buf_num_per_zone; i++) {
+		((struct page_buf *)page_buf + i)->pagebuf = GETBUF(PAGESIZE());
+	}
 
+	start = si->vaddr_start;
+	end = si->vaddr_end;
 	if (start & (sizeof(long)-1)) {
 		start &= ~(sizeof(long)-1);
 		error(INFO, "rounding down start address to: %lx\n", start);
 	}
-
 	if (CRASHDEBUG(1)) {
 		begin = time(NULL);
-		fprintf(fp, "search_virtual: start: %lx end: %lx\n", 
+		fprintf(fp, "search_virtual: start: %lx end: %lx\n",
 			start, end);
 	}
 
-	next = start;
+	for (i = 0; i < thread_num; i++) {
+		td[i].si = si;
+		if ((td[i].output_buf = malloc(1024)) == NULL)
+			error(FATAL, "cannot malloc output buffer");
+		*td[i].output_buf = '\0';
+		td[i].output_buf_size = 1024;
+		td[i].empty_page_buf_zone_count = &empty_page_buf_zone_count;
+		td[i].barrier = &barrier;
+		td[i].finished_thread_count = &finished_thread_count;
+		td[i].page_buf_zone_index = &thread_page_buf_zone_index;
+		td[i].finished_thread_count_mutex = &finished_thread_count_mutex;
+		td[i].td = td;
+		td[i].start = (int *)GETBUF(sizeof(int) * si->page_buf_zone_num * 3);
+		td[i].end = td[i].start + si->page_buf_zone_num * 1;
+		td[i].exit = td[i].start + si->page_buf_zone_num * 2;
+		memset(td[i].start, 0, sizeof(int) * si->page_buf_zone_num * 3);
+
+		td[i].thread_index = i;
 
+		pthread_create(&threads[i], NULL, do_search_virtual, &td[i]);
+	}
+
+	page_buf_index = 0;
+	next = start;
+	sem_wait(&empty_page_buf_zone_count);
 	for (pp = VIRTPAGEBASE(start); next < end; next = pp) {
 		pages_checked++;
-		lastpage = (VIRTPAGEBASE(next) == VIRTPAGEBASE(end));
-		if (LKCD_DUMPFILE())
-			set_lkcd_nohash();
-
-		/*
-		 *  Keep it virtual for Xen hypervisor.
-		 */
+		(page_buf + page_buf_zone_index * page_buf_num_per_zone)
+			[page_buf_index].lastpage =
+				(VIRTPAGEBASE(next) == VIRTPAGEBASE(end));
 		if (XEN_HYPER_MODE()) {
-                	if (!readmem(pp, KVADDR, pagebuf, PAGESIZE(),
-                    	    "search page", RETURN_ON_ERROR|QUIET)) {
+			if (!readmem(pp, KVADDR, (page_buf +
+				     page_buf_zone_index * page_buf_num_per_zone)
+					[page_buf_index].pagebuf,
+				     PAGESIZE(), "search page",
+				     RETURN_ON_ERROR|QUIET)) {
 				if (CRASHDEBUG(1))
 					fprintf(fp, 
 					    "search suspended at: %lx\n", pp);
@@ -15337,7 +15601,7 @@ search_virtual(struct searchinfo *si)
 			goto virtual;
 		}
 
-                switch (si->memtype)
+		switch (si->memtype)
                 {
                 case UVADDR:
                         if (!uvtop(CURRENT_CONTEXT(), pp, &paddr, 0) ||
@@ -15358,60 +15622,73 @@ search_virtual(struct searchinfo *si)
                         break;
                 }
 
-                if (!readmem(paddr, PHYSADDR, pagebuf, PAGESIZE(),
-                    "search page", RETURN_ON_ERROR|QUIET)) {
+                if (!readmem(paddr, PHYSADDR, (page_buf +
+			     page_buf_zone_index * page_buf_num_per_zone)
+				[page_buf_index].pagebuf,
+			     PAGESIZE(), "search page",
+			     RETURN_ON_ERROR|QUIET)) {
 			pp += PAGESIZE();
 			continue;
 		}
-virtual:
 		pages_read++;
-
-		ubp = (ulong *)&pagebuf[next - pp];
-		if (lastpage) {
-			if (end == (ulong)(-1))
-				wordcnt = PAGESIZE()/sizeof(long);
-			else
-				wordcnt = (end - next)/sizeof(long);
-		} else
-			wordcnt = (PAGESIZE() - (next - pp))/sizeof(long);
-
-		switch (si->mode)
-		{
-		case SEARCH_ULONG:
-			next = search_ulong(ubp, next, wordcnt, si);
-			break;
-		case SEARCH_UINT:
-			next = search_uint(ubp, next, wordcnt, si);
-			break;
-		case SEARCH_USHORT:
-			next = search_ushort(ubp, next, wordcnt, si);
-			break;
-		case SEARCH_CHARS:
-			next = search_chars(ubp, next, wordcnt, si);
-			break;
-		default:
-			/* unimplemented search type */
-			next += wordcnt * (sizeof(long));
-			break;
+virtual:
+		(page_buf + page_buf_zone_index * page_buf_num_per_zone)
+			[page_buf_index].ppp = pp;
+		(page_buf + page_buf_zone_index * page_buf_num_per_zone)
+			[page_buf_index++].pnext = next;
+		if (page_buf_index >= page_buf_num_per_zone) {
+			for (st = 0, i = 0; i < thread_num; st = ed, i++) {
+				ed = st + page_buf_index / thread_num + 1;
+				ed = ed > page_buf_index ? page_buf_index : ed;
+				td[i].start[page_buf_zone_index] = st;
+				td[i].end[page_buf_zone_index] = ed;
+			}
+			pthread_barrier_wait(&barrier);
+			page_buf_index = 0;
+			page_buf_zone_index = (page_buf_zone_index + 1) %
+						si->page_buf_zone_num;
+			sem_wait(&empty_page_buf_zone_count);
 		}
 
 		if (CRASHDEBUG(1))
 			if ((pp % (1024*1024)) == 0)
 				console("%lx\n", pp);
-
 		pp += PAGESIZE();
 	}
-
+	if (next >= end) {
 done:
+		for (st = 0, i = 0; i < thread_num; st = ed, i++) {
+			ed = st + page_buf_index / thread_num + 1;
+			ed = ed > page_buf_index ? page_buf_index : ed;
+			td[i].start[page_buf_zone_index] = st;
+			td[i].end[page_buf_zone_index] = ed;
+			td[i].exit[page_buf_zone_index] = true;
+		}
+		pthread_barrier_wait(&barrier);
+		sem_wait(&empty_page_buf_zone_count);
+	}
+	for (i = 0; i < thread_num; i++) {
+		pthread_join(threads[i], NULL);
+	}
+	for (i = 0; i < thread_num; i++) {
+		free(td[i].output_buf);
+		FREEBUF(td[i].start);
+	}
+	for (i = 0; i < si->page_buf_zone_num * page_buf_num_per_zone; i++) {
+		FREEBUF(((struct page_buf *)page_buf + i)->pagebuf);
+	}
+	FREEBUF(page_buf);
+	sem_destroy(&empty_page_buf_zone_count);
+	pthread_barrier_destroy(&barrier);
+	pthread_mutex_destroy(&finished_thread_count_mutex);
+
 	if (CRASHDEBUG(1)) {
 		finish = time(NULL);
 		pct = (pages_read * 100)/pages_checked;
-		fprintf(fp, 
-		    "search_virtual: read %ld (%ld%%) of %ld pages checked in %ld seconds\n", 
+		fprintf(fp,
+		    "search_virtual: read %ld (%ld%%) of %ld pages checked in %ld seconds\n",
 			pages_read, pct, pages_checked, finish - begin);
 	}
-
-	FREEBUF(pagebuf);
 }
 
 
diff --git a/task.c b/task.c
index 88941c7..ff5b897 100644
--- a/task.c
+++ b/task.c
@@ -7724,6 +7724,20 @@ print_task_header(FILE *out, struct task_context *tc, int newline)
 		task_cpu(tc->processor, buf, !VERBOSE), tc->comm);
 }
 
+void
+print_task_header_para(struct task_context *tc, int newline, cache_output_t *co)
+{
+	char buf[BUFSIZE];
+	char buf1[BUFSIZE];
+
+	*co->output_buf_offset += snprintf(*co->output_buf,
+		*co->output_buf_size - *co->output_buf_offset,
+		"%sPID: %-7ld  TASK: %s  CPU: %-3s  COMMAND: \"%s\"\n",
+		newline ? "\n" : "", tc->pid,
+		mkstring(buf1, VADDR_PRLEN, LJUST|LONG_HEX, MKSTR(tc->task)),
+		task_cpu(tc->processor, buf, !VERBOSE), tc->comm);
+}
+
 /*
  *  "help -t" output
  */
-- 
2.33.1

--
Crash-utility mailing list
Crash-utility@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/crash-utility
Contribution Guidelines: https://github.com/crash-utility/crash/wiki




[Index of Archives]     [Fedora Development]     [Fedora Desktop]     [Fedora SELinux]     [Yosemite News]     [KDE Users]     [Fedora Tools]

 

Powered by Linux