blob: f5ef6696291389c50e48c044b1f3bba47b68ff10 [file] [log] [blame]
barte7d58722008-02-28 19:08:04 +00001/*
2 This file is part of drd, a data race detector.
3
4 Copyright (C) 2006-2008 Bart Van Assche
5 bart.vanassche@gmail.com
6
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public License as
9 published by the Free Software Foundation; either version 2 of the
10 License, or (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307, USA.
21
22 The GNU General Public License is contained in the file COPYING.
23*/
24
25
26#include "drd_clientobj.h"
27#include "drd_suppression.h"
28#include "pub_tool_basics.h"
29#include "pub_tool_libcassert.h"
30#include "pub_tool_libcbase.h"
31#include "pub_tool_libcprint.h" // VG_(message)()
32#include "pub_tool_mallocfree.h"
33#include "pub_tool_oset.h"
34
35
36// Local variables.
37
38static OSet* s_clientobj;
39
40
41// Function definitions.
42
43/** Initialize the client object set. */
44void drd_clientobj_init(void)
45{
46 tl_assert(s_clientobj == 0);
47 s_clientobj = VG_(OSetGen_Create)(0, 0, VG_(malloc), VG_(free));
48 tl_assert(s_clientobj);
49}
50
51/** Free the memory allocated for the client object set.
52 * @pre Client object set is empty.
53 */
54void drd_clientobj_cleanup(void)
55{
56 tl_assert(s_clientobj);
57 tl_assert(VG_(OSetGen_Size)(s_clientobj) == 0);
58 VG_(OSetGen_Destroy)(s_clientobj);
59 s_clientobj = 0;
60}
61
62/** Return the data associated with the client object at client address addr
63 * and that has object type t. Return 0 if there is no client object in the
64 * set with the specified start address.
65 */
66DrdClientobj* drd_clientobj_get(const Addr addr, const ObjType t)
67{
68 DrdClientobj* p;
69 p = VG_(OSetGen_Lookup)(s_clientobj, &addr);
70 if (p && p->any.type == t)
71 return p;
72 return 0;
73}
74
75/** Return true if and only if the address range of any client object overlaps
76 * with the specified address range.
77 */
78Bool drd_clientobj_present(const Addr a1, const Addr a2)
79{
80 DrdClientobj *p;
81
82 tl_assert(a1 < a2);
83 VG_(OSetGen_ResetIter)(s_clientobj);
84 for ( ; (p = VG_(OSetGen_Next)(s_clientobj)) != 0; )
85 {
86 if ((a1 <= p->any.a1 && p->any.a1 < a2)
87 || (a1 < p->any.a2 && p->any.a2 <= a2))
88 {
89 return True;
90 }
91 }
92 return False;
93}
94
95/** Add state information for the client object at client address addr and
96 * of type t. Suppress data race reports on the address range [addr,addr+size[.
97 * @pre No other client object is present in the address range [addr,addr+size[.
98 */
99DrdClientobj*
100drd_clientobj_add(const Addr a1, const Addr a2, const ObjType t)
101{
102 DrdClientobj* p;
103
104 tl_assert(a1 < a2 && a1 + 4096 > a2);
105 tl_assert(! drd_clientobj_present(a1, a2));
106 tl_assert(VG_(OSetGen_Lookup)(s_clientobj, &a1) == 0);
107 p = VG_(OSetGen_AllocNode)(s_clientobj, sizeof(*p));
108 VG_(memset)(p, 0, sizeof(*p));
109 p->any.a1 = a1;
110 p->any.a2 = a2;
111 p->any.type = t;
112 VG_(OSetGen_Insert)(s_clientobj, p);
113 tl_assert(VG_(OSetGen_Lookup)(s_clientobj, &a1) == p);
114 drd_start_suppression(p->any.a1, p->any.a2, "client object");
115 return p;
116}
117
118Bool drd_clientobj_remove(const Addr addr)
119{
120 DrdClientobj* p;
121
122 p = VG_(OSetGen_Remove)(s_clientobj, &addr);
123 if (p)
124 {
125#if 0
126 VG_(message)(Vg_DebugMsg, "removing client obj [%p,%p[\n",
127 p->any.a1, p->any.a2);
128#endif
129 tl_assert(VG_(OSetGen_Lookup)(s_clientobj, &addr) == 0);
130 drd_finish_suppression(p->any.a1, p->any.a2);
131 tl_assert(p->any.cleanup);
132 (*p->any.cleanup)(p);
133 VG_(OSetGen_FreeNode)(s_clientobj, p);
134 return True;
135 }
136 return False;
137}
138
139void drd_clientobj_stop_using_mem(const Addr a1, const Addr a2)
140{
141 DrdClientobj* p;
142 tl_assert(s_clientobj);
143 VG_(OSetGen_ResetIter)(s_clientobj);
144 for ( ; (p = VG_(OSetGen_Next)(s_clientobj)) != 0; )
145 {
146 if ((a1 <= p->any.a1 && p->any.a1 < a2)
147 || (a1 < p->any.a2 && p->any.a2 <= a2))
148 {
149 drd_clientobj_remove(p->any.a1);
150 }
151 }
152}
153
154void drd_clientobj_resetiter(void)
155{
156 VG_(OSetGen_ResetIter)(s_clientobj);
157}
158
159DrdClientobj* drd_clientobj_next(const ObjType t)
160{
161 DrdClientobj* p;
162 while ((p = VG_(OSetGen_Next)(s_clientobj)) != 0 && p->any.type != t)
163 ;
164 return p;
165}
166