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.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@12356
This commit is contained in:
Bart Van Assche 2012-01-25 20:36:27 +00:00
parent 75a946033a
commit af76b5a089
5 changed files with 130 additions and 359 deletions

View File

@ -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 <bvanassche@acm.org>.
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_ */

View File

@ -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 @@ static void sg_init(Segment* const sg,
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 @@ Segment* DRD_(sg_new)(const DrdThreadId creator, const DrdThreadId created)
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 @@ static void DRD_(sg_delete)(Segment* const sg)
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);
}

View File

@ -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 @@ typedef struct segment
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);

View File

@ -142,10 +142,6 @@ void DRD_(thread_set_join_list_vol)(const int jlv)
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 @@ static DrdThreadId DRD_(VgThreadIdToNewDrdThreadId)(const ThreadId tid)
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 @@ DrdThreadId DRD_(thread_pre_create)(const DrdThreadId creator,
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 @@ void DRD_(thread_delete)(const DrdThreadId tid, const Bool detached)
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 @@ void DRD_(thread_delete)(const DrdThreadId tid, const Bool detached)
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 @@ void thread_append_segment(const DrdThreadId tid, Segment* const sg)
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 @@ void thread_discard_segment(const DrdThreadId tid, Segment* const sg)
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 @@ void thread_discard_segment(const DrdThreadId tid, Segment* const sg)
*/
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 @@ VectorClock* DRD_(thread_get_vc)(const DrdThreadId tid)
*/
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 @@ static void DRD_(thread_compute_minimum_vc)(VectorClock* vc)
{
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 @@ static void DRD_(thread_compute_maximum_vc)(VectorClock* vc)
{
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 @@ static void thread_discard_ordered_segments(void)
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 @@ static Bool thread_consistent_segment_ordering(const DrdThreadId tid,
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 @@ static void thread_merge_segments(void)
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 @@ static void thread_merge_segments(void)
*/
void DRD_(thread_new_segment)(const DrdThreadId tid)
{
struct list_head* sg_list;
Segment* last_sg;
Segment* new_sg;
@ -1054,9 +1047,7 @@ void DRD_(thread_new_segment)(const DrdThreadId tid)
&& 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 @@ void DRD_(thread_combine_vc_join)(DrdThreadId joiner, DrdThreadId joinee)
&& 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 @@ static void thread_combine_vc_sync(DrdThreadId tid, const Segment* sg)
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 @@ void DRD_(thread_stop_using_mem)(const Addr a1, const Addr a2)
{
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_set_record_stores)(const DrdThreadId tid, const Bool enabled)
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 @@ void DRD_(thread_print_all)(void)
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 @@ thread_report_conflicting_segments_segment(const DrdThreadId tid,
&& 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 @@ thread_report_conflicting_segments_segment(const DrdThreadId tid,
*/
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 @@ thread_report_conflicting_segments_segment(const DrdThreadId tid,
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 @@ void DRD_(thread_report_conflicting_segments)(const DrdThreadId tid,
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 @@ static void thread_compute_conflict_set(struct bitmap** conflict_set,
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 @@ static void thread_compute_conflict_set(struct bitmap** conflict_set,
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 @@ static void thread_compute_conflict_set(struct bitmap** conflict_set,
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 @@ static void thread_compute_conflict_set(struct bitmap** conflict_set,
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,14 +1501,13 @@ void DRD_(thread_update_conflict_set)(const DrdThreadId tid,
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;
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);
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 (UNLIKELY(s_trace_conflict_set)) {
char* str;
@ -1549,16 +1524,12 @@ void DRD_(thread_update_conflict_set)(const DrdThreadId tid,
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;
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);
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 (UNLIKELY(s_trace_conflict_set)) {
char* str;
@ -1578,16 +1549,13 @@ void DRD_(thread_update_conflict_set)(const DrdThreadId tid,
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));
}

View File

@ -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 @@ typedef UWord PThreadId;
/** 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 @@ Bool DRD_(thread_address_on_any_stack)(const Addr a)
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. */