|
From: <sv...@va...> - 2012-01-25 20:41:05
|
Author: bart Date: 2012-01-25 20:36:27 +0000 (Wed, 25 Jan 2012) New Revision: 12356 Log: drd: Remove drd/drd_list.h again because of its GPLv2 license. For more info about Valgrind source code licensing, see also: [1] Top level README line 51. [2] http://valgrind.org/docs/manual/manual-intro.html#manual-intro.overview, last paragraph. Removed: trunk/drd/drd_list.h Modified: trunk/drd/drd_segment.c trunk/drd/drd_segment.h trunk/drd/drd_thread.c trunk/drd/drd_thread.h Deleted: trunk/drd/drd_list.h =================================================================== --- trunk/drd/drd_list.h 2012-01-25 11:05:12 UTC (rev 12355) +++ trunk/drd/drd_list.h 2012-01-25 20:36:27 UTC (rev 12356) @@ -1,202 +0,0 @@ -/* - This file is part of drd, a thread error detector. - - Copyright (C) 1990-2011 Linus Torvalds and other kernel authors. - Copyright (C) 2012 Bart Van Assche <bva...@ac...>. - - This program is free software; you can redistribute it and/or - modify it under the terms of version 2 of the GNU General Public - License as published by the Free Software Foundation. - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307, USA. - - The GNU General Public License is contained in the file COPYING. -*/ - -#ifndef _DRD_LIST_H_ -#define _DRD_LIST_H_ - -/* - * Doubly linked lists. See also the Linux kernel headers <linux/types.h>. - */ - -/** - * container_of - cast a member of a structure out to the containing structure - * @ptr: the pointer to the member. - * @type: the type of the container struct this is embedded in. - * @member: the name of the member within the struct. - * - */ -#define container_of(ptr, type, member) ({ \ - const typeof( ((type *)0)->member ) *__mptr = (ptr); \ - (type *)( (char *)__mptr - offsetof(type,member) );}) - -struct list_head { - struct list_head *next; - struct list_head *prev; -}; - -#define LIST_HEAD_INIT(name) { &(name), &(name) } - -static inline void init_list_head(struct list_head *list) -{ - list->next = list; - list->prev = list; -} - -static inline void __list_add(struct list_head *new, - struct list_head *prev, - struct list_head *next) -{ - next->prev = new; - new->next = next; - new->prev = prev; - prev->next = new; -} - -/** - * list_add - add a new entry - * @new: new entry to be added - * @head: list head to add it after - * - * Insert a new entry after the specified head. - */ -static inline void list_add(struct list_head *new, struct list_head *head) -{ - __list_add(new, head, head->next); -} - -/** - * list_add_tail - add a new entry - * @new: new entry to be added - * @head: list head to add it before - * - * Insert a new entry before the specified head. - * This is useful for implementing queues. - */ -static inline void list_add_tail(struct list_head *new, struct list_head *head) -{ - __list_add(new, head->prev, head); -} - -/* - * Delete a list entry by making the prev/next entries - * point to each other. - * - * This is only for internal list manipulation where we know - * the prev/next entries already! - */ -static inline void __list_del(struct list_head * prev, struct list_head * next) -{ - next->prev = prev; - prev->next = next; -} - -/** - * list_del - deletes entry from list. - * @entry: the element to delete from the list. - * Note: list_empty() on entry does not return true after this, the entry is - * in an undefined state. - */ -static inline void list_del(struct list_head *entry) -{ - __list_del(entry->prev, entry->next); - entry->next = NULL; - entry->prev = NULL; -} - -/** - * list_is_last - tests whether @list is the last entry in list @head - * @list: the entry to test - * @head: the head of the list - */ -static inline int list_is_last(const struct list_head *list, - const struct list_head *head) -{ - return list->next == head; -} - -/** - * list_empty - tests whether a list is empty - * @head: the list to test. - */ -static inline int list_empty(const struct list_head *head) -{ - return head->next == head; -} - -/** - * list_entry - get the struct for this entry - * @ptr: the &struct list_head pointer. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - */ -#define list_entry(ptr, type, member) \ - container_of(ptr, type, member) - -/** - * list_first_entry - get the first element from a list - * @ptr: the list head to take the element from. - * @type: the type of the struct this is embedded in. - * @member: the name of the list_struct within the struct. - * - * Note, that list is expected to be not empty. - */ -#define list_first_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -#define list_next_entry(ptr, type, member) \ - list_entry((ptr)->next, type, member) - -#define list_last_entry(ptr, type, member) \ - list_entry((ptr)->prev, type, member) - -/** - * list_for_each_entry - iterate over list of given type - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry(pos, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.next, typeof(*pos), member)) - -/** - * list_for_each_entry_reverse - iterate backwards over list of given type. - * @pos: the type * to use as a loop cursor. - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_reverse(pos, head, member) \ - for (pos = list_entry((head)->prev, typeof(*pos), member); \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -#define list_for_each_entry_reverse_continue(pos, head, member) \ - for ( ; \ - &pos->member != (head); \ - pos = list_entry(pos->member.prev, typeof(*pos), member)) - -/** - * list_for_each_entry_safe - iterate over list of given type safe against removal of list entry - * @pos: the type * to use as a loop cursor. - * @n: another type * to use as temporary storage - * @head: the head for your list. - * @member: the name of the list_struct within the struct. - */ -#define list_for_each_entry_safe(pos, n, head, member) \ - for (pos = list_entry((head)->next, typeof(*pos), member), \ - n = list_entry(pos->member.next, typeof(*pos), member); \ - &pos->member != (head); \ - pos = n, n = list_entry(n->member.next, typeof(*n), member)) - -#endif /* _DRD_LIST_H_ */ Modified: trunk/drd/drd_segment.c =================================================================== --- trunk/drd/drd_segment.c 2012-01-25 11:05:12 UTC (rev 12355) +++ trunk/drd/drd_segment.c 2012-01-25 20:36:27 UTC (rev 12356) @@ -36,7 +36,7 @@ /* Global variables. */ -struct list_head DRD_(g_sg_list) = LIST_HEAD_INIT(DRD_(g_sg_list)); +Segment* DRD_(g_sg_list); /* Local variables. */ @@ -73,10 +73,10 @@ creator_sg = (creator != DRD_INVALID_THREADID ? DRD_(thread_get_segment)(creator) : 0); - sg->g_list.next = NULL; - sg->g_list.prev = NULL; - sg->thr_list.next = NULL; - sg->thr_list.prev = NULL; + sg->g_next = NULL; + sg->g_prev = NULL; + sg->thr_next = NULL; + sg->thr_prev = NULL; sg->tid = created; sg->refcnt = 1; @@ -126,7 +126,11 @@ sg = VG_(malloc)("drd.segment.sn.1", sizeof(*sg)); tl_assert(sg); sg_init(sg, creator, created); - list_add(&sg->g_list, &DRD_(g_sg_list)); + if (DRD_(g_sg_list)) { + DRD_(g_sg_list)->g_prev = sg; + sg->g_next = DRD_(g_sg_list); + } + DRD_(g_sg_list) = sg; return sg; } @@ -145,7 +149,12 @@ s_segments_alive_count--; tl_assert(sg); - list_del(&sg->g_list); + if (sg->g_next) + sg->g_next->g_prev = sg->g_prev; + if (sg->g_prev) + sg->g_prev->g_next = sg->g_next; + else + DRD_(g_sg_list) = sg->g_next; DRD_(sg_cleanup)(sg); VG_(free)(sg); } Modified: trunk/drd/drd_segment.h =================================================================== --- trunk/drd/drd_segment.h 2012-01-25 11:05:12 UTC (rev 12355) +++ trunk/drd/drd_segment.h 2012-01-25 20:36:27 UTC (rev 12356) @@ -33,7 +33,6 @@ */ -#include "drd_list.h" #include "drd_vc.h" #include "pub_drd_bitmap.h" #include "pub_tool_execontext.h" // ExeContext @@ -42,9 +41,11 @@ typedef struct segment { - struct list_head g_list; + struct segment* g_next; + struct segment* g_prev; /** Pointers to next and previous segments executed by the same thread. */ - struct list_head thr_list; + struct segment* thr_next; + struct segment* thr_prev; DrdThreadId tid; /** Reference count: number of pointers that point to this segment. */ int refcnt; @@ -59,7 +60,7 @@ struct bitmap bm; } Segment; -extern struct list_head DRD_(g_sg_list); +extern Segment* DRD_(g_sg_list); Segment* DRD_(sg_new)(const DrdThreadId creator, const DrdThreadId created); static int DRD_(sg_get_refcnt)(const Segment* const sg); Modified: trunk/drd/drd_thread.c =================================================================== --- trunk/drd/drd_thread.c 2012-01-25 11:05:12 UTC (rev 12355) +++ trunk/drd/drd_thread.c 2012-01-25 20:36:27 UTC (rev 12356) @@ -142,10 +142,6 @@ void DRD_(thread_init)(void) { - int i; - - for (i = 0; i < DRD_N_THREADS; i++) - init_list_head(&DRD_(g_threadinfo)[i].sg_list); } /** @@ -201,7 +197,8 @@ DRD_(g_threadinfo)[i].pthread_create_nesting_level = 0; DRD_(g_threadinfo)[i].synchr_nesting = 0; DRD_(g_threadinfo)[i].deletion_seq = s_deletion_tail - 1; - tl_assert(list_empty(&DRD_(g_threadinfo)[i].sg_list)); + tl_assert(DRD_(g_threadinfo)[i].sg_first == NULL); + tl_assert(DRD_(g_threadinfo)[i].sg_last == NULL); tl_assert(DRD_(IsValidDrdThreadId)(i)); @@ -297,7 +294,8 @@ tl_assert(0 <= (int)created && created < DRD_N_THREADS && created != DRD_INVALID_THREADID); - tl_assert(list_empty(&DRD_(g_threadinfo)[created].sg_list)); + tl_assert(DRD_(g_threadinfo)[created].sg_first == NULL); + tl_assert(DRD_(g_threadinfo)[created].sg_last == NULL); /* Create an initial segment for the newly created thread. */ thread_append_segment(created, DRD_(sg_new)(creator, created)); @@ -496,10 +494,10 @@ tl_assert(DRD_(IsValidDrdThreadId)(tid)); tl_assert(DRD_(g_threadinfo)[tid].synchr_nesting >= 0); - list_for_each_entry_safe(sg, sg_prev, &DRD_(g_threadinfo)[tid].sg_list, - thr_list) - { - list_del(&sg->thr_list); + for (sg = DRD_(g_threadinfo)[tid].sg_last; sg; sg = sg_prev) { + sg_prev = sg->thr_prev; + sg->thr_next = NULL; + sg->thr_prev = NULL; DRD_(sg_put)(sg); } DRD_(g_threadinfo)[tid].valid = False; @@ -509,9 +507,10 @@ DRD_(g_threadinfo)[tid].detached_posix_thread = False; else tl_assert(!DRD_(g_threadinfo)[tid].detached_posix_thread); - tl_assert(list_empty(&DRD_(g_threadinfo)[tid].sg_list)); + DRD_(g_threadinfo)[tid].sg_first = NULL; + DRD_(g_threadinfo)[tid].sg_last = NULL; - tl_assert(! DRD_(IsValidDrdThreadId)(tid)); + tl_assert(!DRD_(IsValidDrdThreadId)(tid)); } /** @@ -746,7 +745,14 @@ tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid])); #endif - list_add_tail(&sg->thr_list, &DRD_(g_threadinfo)[tid].sg_list); + // add at tail + sg->thr_prev = DRD_(g_threadinfo)[tid].sg_last; + sg->thr_next = NULL; + if (DRD_(g_threadinfo)[tid].sg_last) + DRD_(g_threadinfo)[tid].sg_last->thr_next = sg; + DRD_(g_threadinfo)[tid].sg_last = sg; + if (DRD_(g_threadinfo)[tid].sg_first == NULL) + DRD_(g_threadinfo)[tid].sg_first = sg; #ifdef ENABLE_DRD_CONSISTENCY_CHECKS tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid])); @@ -767,7 +773,14 @@ tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[tid])); #endif - list_del(&sg->thr_list); + if (sg->thr_prev) + sg->thr_prev->thr_next = sg->thr_next; + if (sg->thr_next) + sg->thr_next->thr_prev = sg->thr_prev; + if (sg == DRD_(g_threadinfo)[tid].sg_first) + DRD_(g_threadinfo)[tid].sg_first = sg->thr_next; + if (sg == DRD_(g_threadinfo)[tid].sg_last) + DRD_(g_threadinfo)[tid].sg_last = sg->thr_prev; DRD_(sg_put)(sg); #ifdef ENABLE_DRD_CONSISTENCY_CHECKS @@ -781,13 +794,13 @@ */ VectorClock* DRD_(thread_get_vc)(const DrdThreadId tid) { - struct list_head* sg_list; + Segment* latest_sg; tl_assert(0 <= (int)tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID); - sg_list = &DRD_(g_threadinfo)[tid].sg_list; - tl_assert(!list_empty(sg_list)); - return &list_last_entry(sg_list, Segment, thr_list)->vc; + latest_sg = DRD_(g_threadinfo)[tid].sg_last; + tl_assert(latest_sg); + return &latest_sg->vc; } /** @@ -795,16 +808,16 @@ */ void DRD_(thread_get_latest_segment)(Segment** sg, const DrdThreadId tid) { - struct list_head* sg_list; + Segment* latest_sg; tl_assert(sg); tl_assert(0 <= (int)tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID); - sg_list = &DRD_(g_threadinfo)[tid].sg_list; - tl_assert(!list_empty(sg_list)); + latest_sg = DRD_(g_threadinfo)[tid].sg_last; + tl_assert(latest_sg); DRD_(sg_put)(*sg); - *sg = DRD_(sg_get)(list_last_entry(sg_list, Segment, thr_list)); + *sg = DRD_(sg_get)(latest_sg); } /** @@ -817,15 +830,13 @@ { unsigned i; Bool first; - struct list_head* sg_list; Segment* latest_sg; first = True; for (i = 0; i < DRD_N_THREADS; i++) { - sg_list = &DRD_(g_threadinfo)[i].sg_list; - if (!list_empty(sg_list)) { - latest_sg = list_last_entry(sg_list, Segment, thr_list); + latest_sg = DRD_(g_threadinfo)[i].sg_last; + if (latest_sg) { if (first) DRD_(vc_assign)(vc, &latest_sg->vc); else @@ -844,15 +855,13 @@ { unsigned i; Bool first; - struct list_head* sg_list; Segment* latest_sg; first = True; for (i = 0; i < DRD_N_THREADS; i++) { - sg_list = &DRD_(g_threadinfo)[i].sg_list; - if (!list_empty(sg_list)) { - latest_sg = list_last_entry(sg_list, Segment, thr_list); + latest_sg = DRD_(g_threadinfo)[i].sg_last; + if (latest_sg) { if (first) DRD_(vc_assign)(vc, &latest_sg->vc); else @@ -893,17 +902,15 @@ DRD_(vc_cleanup)(&thread_vc_max); } - for (i = 0; i < DRD_N_THREADS; i++) - { + for (i = 0; i < DRD_N_THREADS; i++) { Segment* sg; Segment* sg_next; - struct list_head* sg_list; - sg_list = &DRD_(g_threadinfo)[i].sg_list; - list_for_each_entry_safe(sg, sg_next, sg_list, thr_list) { - if (list_is_last(&sg->thr_list, sg_list) - || !DRD_(vc_lte)(&sg->vc, &thread_vc_min)) - break; + for (sg = DRD_(g_threadinfo)[i].sg_first; + sg && (sg_next = sg->thr_next) + && DRD_(vc_lte)(&sg->vc, &thread_vc_min); + sg = sg_next) + { thread_discard_segment(i, sg); } } @@ -944,35 +951,26 @@ Segment* const sg2) { unsigned i; - struct list_head* sg_list; - sg_list = &DRD_(g_threadinfo)[tid].sg_list; - tl_assert(!list_is_last(&sg1->thr_list, sg_list)); - tl_assert(!list_is_last(&sg2->thr_list, sg_list)); - tl_assert(list_next_entry(&sg1->thr_list, Segment, thr_list) == sg2); + tl_assert(sg1->thr_next); + tl_assert(sg2->thr_next); + tl_assert(sg1->thr_next == sg2); tl_assert(DRD_(vc_lte)(&sg1->vc, &sg2->vc)); for (i = 0; i < DRD_N_THREADS; i++) { Segment* sg; - sg_list = &DRD_(g_threadinfo)[i].sg_list; - list_for_each_entry(sg, sg_list, thr_list) - { - if (list_is_last(&sg->thr_list, sg_list) - || DRD_(sg_get_refcnt)(sg) > 1) - { + for (sg = DRD_(g_threadinfo)[i].sg_first; sg; sg = sg->thr_next) { + if (!sg->thr_next || DRD_(sg_get_refcnt)(sg) > 1) { if (DRD_(vc_lte)(&sg2->vc, &sg->vc)) break; if (DRD_(vc_lte)(&sg1->vc, &sg->vc)) return False; } } - list_for_each_entry_reverse(sg, sg_list, thr_list) - { - if (list_is_last(&sg->thr_list, sg_list) - || DRD_(sg_get_refcnt)(sg) > 1) - { + for (sg = DRD_(g_threadinfo)[i].sg_last; sg; sg = sg->thr_prev) { + if (!sg->thr_next || DRD_(sg_get_refcnt)(sg) > 1) { if (DRD_(vc_lte)(&sg->vc, &sg1->vc)) break; if (DRD_(vc_lte)(&sg->vc, &sg2->vc)) @@ -1016,15 +1014,11 @@ tl_assert(DRD_(sane_ThreadInfo)(&DRD_(g_threadinfo)[i])); #endif - struct list_head* sg_list = &DRD_(g_threadinfo)[i].sg_list; - list_for_each_entry(sg, sg_list, thr_list) - { - if (DRD_(sg_get_refcnt)(sg) == 1 - && !list_is_last(&sg->thr_list, sg_list)) { - Segment* sg_next = list_next_entry(&sg->thr_list, Segment, - thr_list); + for (sg = DRD_(g_threadinfo)[i].sg_first; sg; sg = sg->thr_next) { + if (DRD_(sg_get_refcnt)(sg) == 1 && sg->thr_next) { + Segment* const sg_next = sg->thr_next; if (DRD_(sg_get_refcnt)(sg_next) == 1 - && !list_is_last(&sg_next->thr_list, sg_list) + && sg_next->thr_next && thread_consistent_segment_ordering(i, sg, sg_next)) { /* Merge sg and sg_next into sg. */ @@ -1046,7 +1040,6 @@ */ void DRD_(thread_new_segment)(const DrdThreadId tid) { - struct list_head* sg_list; Segment* last_sg; Segment* new_sg; @@ -1054,9 +1047,7 @@ && tid != DRD_INVALID_THREADID); tl_assert(thread_conflict_set_up_to_date(DRD_(g_drd_running_tid))); - sg_list = &DRD_(g_threadinfo)[tid].sg_list; - last_sg = list_empty(sg_list) ? NULL - : list_last_entry(sg_list, Segment, thr_list); + last_sg = DRD_(g_threadinfo)[tid].sg_last; new_sg = DRD_(sg_new)(tid, tid); thread_append_segment(tid, new_sg); if (tid == DRD_(g_drd_running_tid) && last_sg) @@ -1083,8 +1074,10 @@ && joiner != DRD_INVALID_THREADID); tl_assert(0 <= (int)joinee && joinee < DRD_N_THREADS && joinee != DRD_INVALID_THREADID); - tl_assert(!list_empty(&DRD_(g_threadinfo)[joiner].sg_list)); - tl_assert(!list_empty(&DRD_(g_threadinfo)[joinee].sg_list)); + tl_assert(DRD_(g_threadinfo)[joiner].sg_first); + tl_assert(DRD_(g_threadinfo)[joiner].sg_last); + tl_assert(DRD_(g_threadinfo)[joinee].sg_first); + tl_assert(DRD_(g_threadinfo)[joinee].sg_last); if (DRD_(sg_get_trace)()) { @@ -1131,7 +1124,8 @@ tl_assert(0 <= (int)tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID); - tl_assert(!list_empty(&DRD_(g_threadinfo)[tid].sg_list)); + tl_assert(DRD_(g_threadinfo)[tid].sg_first); + tl_assert(DRD_(g_threadinfo)[tid].sg_last); tl_assert(sg); tl_assert(vc); @@ -1194,7 +1188,7 @@ { Segment* p; - list_for_each_entry(p, &DRD_(g_sg_list), g_list) + for (p = DRD_(g_sg_list); p; p = p->g_next) DRD_(bm_clear)(DRD_(sg_bm)(p), a1, a2); DRD_(bm_clear)(DRD_(g_conflict_set), a1, a2); @@ -1228,14 +1222,12 @@ void DRD_(thread_print_all)(void) { unsigned i; - struct list_head* sg_list; Segment* p; for (i = 0; i < DRD_N_THREADS; i++) { - sg_list = &DRD_(g_threadinfo)[i].sg_list; - if (!list_empty(sg_list)) - { + p = DRD_(g_threadinfo)[i].sg_first; + if (p) { VG_(printf)("**************\n" "* thread %3d (%d/%d/%d/%d/0x%lx/%d) *\n" "**************\n", @@ -1246,7 +1238,7 @@ DRD_(g_threadinfo)[i].posix_thread_exists, DRD_(g_threadinfo)[i].pt_threadid, DRD_(g_threadinfo)[i].detached_posix_thread); - list_for_each_entry(p, sg_list, thr_list) + for ( ; p; p = p->thr_next) DRD_(sg_print)(p); } } @@ -1283,15 +1275,11 @@ && tid != DRD_INVALID_THREADID); tl_assert(p); - for (i = 0; i < DRD_N_THREADS; i++) - { - if (i != tid) - { + for (i = 0; i < DRD_N_THREADS; i++) { + if (i != tid) { Segment* q; - struct list_head *sg_list; - sg_list = &DRD_(g_threadinfo)[i].sg_list; - list_for_each_entry_reverse(q, sg_list, thr_list) { + for (q = DRD_(g_threadinfo)[i].sg_last; q; q = q->thr_prev) { /* * Since q iterates over the segments of thread i in order of * decreasing vector clocks, if q->vc <= p->vc, then @@ -1300,11 +1288,9 @@ */ if (DRD_(vc_lte)(&q->vc, &p->vc)) break; - if (! DRD_(vc_lte)(&p->vc, &q->vc)) - { + if (!DRD_(vc_lte)(&p->vc, &q->vc)) { if (DRD_(bm_has_conflict_with)(DRD_(sg_bm)(q), addr, addr + size, - access_type)) - { + access_type)) { Segment* q_next; tl_assert(q->stacktrace); @@ -1320,8 +1306,7 @@ else VG_(message)(Vg_UserMsg, "Other segment end (thread %d)\n", i); - q_next = list_is_last(&q->thr_list, sg_list) - ? NULL : list_next_entry(&q->thr_list, Segment, thr_list); + q_next = q->thr_next; show_call_stack(i, q_next ? q_next->stacktrace : 0); if (VG_(clo_xml)) VG_(printf_xml)(" </other_segment_end>\n"); @@ -1343,7 +1328,7 @@ tl_assert(0 <= (int)tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID); - list_for_each_entry(p, &DRD_(g_threadinfo)[tid].sg_list, thr_list) { + for (p = DRD_(g_threadinfo)[tid].sg_first; p; p = p->thr_next) { if (DRD_(bm_has)(DRD_(sg_bm)(p), addr, addr + size, access_type)) thread_report_conflicting_segments_segment(tid, addr, size, access_type, p); @@ -1418,12 +1403,11 @@ VG_(free)(str); } - p = list_last_entry(&DRD_(g_threadinfo)[tid].sg_list, Segment, thr_list); + p = DRD_(g_threadinfo)[tid].sg_last; { unsigned j; - if (s_trace_conflict_set) - { + if (s_trace_conflict_set) { char* vc; vc = DRD_(vc_aprint)(&p->vc); @@ -1432,18 +1416,14 @@ VG_(free)(vc); } - for (j = 0; j < DRD_N_THREADS; j++) - { - if (j != tid && DRD_(IsValidDrdThreadId)(j)) - { + for (j = 0; j < DRD_N_THREADS; j++) { + if (j != tid && DRD_(IsValidDrdThreadId)(j)) { Segment* q; - list_for_each_entry_reverse(q, &DRD_(g_threadinfo)[j].sg_list, - thr_list) { - if (! DRD_(vc_lte)(&q->vc, &p->vc) - && ! DRD_(vc_lte)(&p->vc, &q->vc)) - { - if (s_trace_conflict_set) - { + + for (q = DRD_(g_threadinfo)[j].sg_last; q; q = q->thr_prev) { + if (!DRD_(vc_lte)(&q->vc, &p->vc) + && !DRD_(vc_lte)(&p->vc, &q->vc)) { + if (s_trace_conflict_set) { char* str; str = DRD_(vc_aprint)(&q->vc); @@ -1453,11 +1433,8 @@ VG_(free)(str); } DRD_(bm_merge2)(*conflict_set, DRD_(sg_bm)(q)); - } - else - { - if (s_trace_conflict_set) - { + } else { + if (s_trace_conflict_set) { char* str; str = DRD_(vc_aprint)(&q->vc); @@ -1477,8 +1454,7 @@ s_conflict_set_bitmap2_creation_count += DRD_(bm_get_bitmap2_creation_count)(); - if (s_trace_conflict_set_bm) - { + if (s_trace_conflict_set_bm) { VG_(message)(Vg_DebugMsg, "[%d] new conflict set:\n", tid); DRD_(bm_print)(*conflict_set); VG_(message)(Vg_DebugMsg, "[%d] end of new conflict set.\n", tid); @@ -1525,15 +1501,14 @@ if (j == tid || ! DRD_(IsValidDrdThreadId)(j)) continue; - list_for_each_entry_reverse(q, &DRD_(g_threadinfo)[j].sg_list, thr_list) { - Bool included_in_old_conflict_set, included_in_new_conflict_set; + for (q = DRD_(g_threadinfo)[j].sg_last; + q && !DRD_(vc_lte)(&q->vc, new_vc); + q = q->thr_prev) { + const Bool included_in_old_conflict_set + = !DRD_(vc_lte)(old_vc, &q->vc); + const Bool included_in_new_conflict_set + = !DRD_(vc_lte)(new_vc, &q->vc); - if (DRD_(vc_lte)(&q->vc, new_vc)) - break; - - included_in_old_conflict_set = !DRD_(vc_lte)(old_vc, &q->vc); - included_in_new_conflict_set = !DRD_(vc_lte)(new_vc, &q->vc); - if (UNLIKELY(s_trace_conflict_set)) { char* str; @@ -1549,17 +1524,13 @@ DRD_(bm_mark)(DRD_(g_conflict_set), DRD_(sg_bm)(q)); } - list_for_each_entry_reverse_continue(q, &DRD_(g_threadinfo)[j].sg_list, - thr_list) { - Bool included_in_old_conflict_set, included_in_new_conflict_set; + for ( ; q && !DRD_(vc_lte)(&q->vc, old_vc); q = q->thr_prev) { + const Bool included_in_old_conflict_set + = !DRD_(vc_lte)(old_vc, &q->vc); + const Bool included_in_new_conflict_set + = !DRD_(vc_lte)(&q->vc, new_vc) + && !DRD_(vc_lte)(new_vc, &q->vc); - if (DRD_(vc_lte)(&q->vc, old_vc)) - break; - - included_in_old_conflict_set = !DRD_(vc_lte)(old_vc, &q->vc); - included_in_new_conflict_set - = !DRD_(vc_lte)(&q->vc, new_vc) && !DRD_(vc_lte)(new_vc, &q->vc); - if (UNLIKELY(s_trace_conflict_set)) { char* str; @@ -1578,16 +1549,13 @@ DRD_(bm_clear_marked)(DRD_(g_conflict_set)); - p = list_last_entry(&DRD_(g_threadinfo)[tid].sg_list, Segment, thr_list); - for (j = 0; j < DRD_N_THREADS; j++) - { - if (j != tid && DRD_(IsValidDrdThreadId)(j)) - { + p = DRD_(g_threadinfo)[tid].sg_last; + for (j = 0; j < DRD_N_THREADS; j++) { + if (j != tid && DRD_(IsValidDrdThreadId)(j)) { Segment* q; - list_for_each_entry_reverse(q, &DRD_(g_threadinfo)[j].sg_list, - thr_list) { - if (DRD_(vc_lte)(&q->vc, &p->vc)) - break; + for (q = DRD_(g_threadinfo)[j].sg_last; + q && !DRD_(vc_lte)(&q->vc, &p->vc); + q = q->thr_prev) { if (!DRD_(vc_lte)(&p->vc, &q->vc)) DRD_(bm_merge2_marked)(DRD_(g_conflict_set), DRD_(sg_bm)(q)); } Modified: trunk/drd/drd_thread.h =================================================================== --- trunk/drd/drd_thread.h 2012-01-25 11:05:12 UTC (rev 12355) +++ trunk/drd/drd_thread.h 2012-01-25 20:36:27 UTC (rev 12356) @@ -29,7 +29,6 @@ /* Include directives. */ #include "drd_basics.h" -#include "drd_list.h" #include "drd_segment.h" #include "pub_drd_bitmap.h" #include "pub_tool_libcassert.h" /* tl_assert() */ @@ -67,7 +66,8 @@ /** Per-thread information managed by DRD. */ typedef struct { - struct list_head sg_list;/**< Segment list. */ + struct segment* sg_first;/**< Segment list. */ + struct segment* sg_last; ThreadId vg_threadid; /**< Valgrind thread ID. */ PThreadId pt_threadid; /**< POSIX thread ID. */ Addr stack_min_min; /**< Lowest value stack pointer ever had. */ @@ -340,17 +340,12 @@ static __inline__ Segment* DRD_(thread_get_segment)(const DrdThreadId tid) { - struct list_head* sg_list; - #ifdef ENABLE_DRD_CONSISTENCY_CHECKS tl_assert(0 <= (int)tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID); + tl_assert(DRD_(g_threadinfo)[tid].sg_last); #endif - sg_list = &DRD_(g_threadinfo)[tid].sg_list; -#ifdef ENABLE_DRD_CONSISTENCY_CHECKS - tl_assert(!list_empty(sg_list)); -#endif - return list_last_entry(sg_list, Segment, thr_list); + return DRD_(g_threadinfo)[tid].sg_last; } /** Return a pointer to the latest segment for the running thread. */ |