blob: efe4e6d5c481aa701bfda06aadbfce38d2e63ea9 [file] [log] [blame]
barte7d58722008-02-28 19:08:04 +00001/*
bart86562bd2009-02-16 19:43:56 +00002 This file is part of drd, a thread error detector.
barte7d58722008-02-28 19:08:04 +00003
bart86562bd2009-02-16 19:43:56 +00004 Copyright (C) 2006-2009 Bart Van Assche <bart.vanassche@gmail.com>.
barte7d58722008-02-28 19:08:04 +00005
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307, USA.
20
21 The GNU General Public License is contained in the file COPYING.
22*/
23
24
25#ifndef __DRD_CLIENTOBJ_H
26#define __DRD_CLIENTOBJ_H
27
28
bart195e41f2009-02-15 11:34:57 +000029#include "drd_basics.h" /* DrdThreadId */
bart9d5b7962008-05-14 12:25:00 +000030#include "drd_clientreq.h" /* MutexT */
barte7d58722008-02-28 19:08:04 +000031#include "pub_tool_basics.h"
bart9d5b7962008-05-14 12:25:00 +000032#include "pub_tool_execontext.h" /* ExeContext */
bart28230a32008-02-29 17:27:03 +000033#include "pub_tool_oset.h"
bart3e017fa2008-12-17 19:20:13 +000034#include "pub_tool_xarray.h"
barte7d58722008-02-28 19:08:04 +000035
36
bart195e41f2009-02-15 11:34:57 +000037/* Forward declarations. */
barte7d58722008-02-28 19:08:04 +000038
39union drd_clientobj;
40
41
bart195e41f2009-02-15 11:34:57 +000042/* Type definitions. */
barte7d58722008-02-28 19:08:04 +000043
bart28230a32008-02-29 17:27:03 +000044typedef enum {
45 ClientMutex = 1,
46 ClientCondvar = 2,
47 ClientSemaphore = 3,
48 ClientBarrier = 4,
bart777f7fe2008-03-02 17:43:18 +000049 ClientRwlock = 5,
bart28230a32008-02-29 17:27:03 +000050} ObjType;
barte7d58722008-02-28 19:08:04 +000051
52struct any
53{
bart391d9dc2008-07-03 10:57:30 +000054 Addr a1;
55 ObjType type;
56 void (*cleanup)(union drd_clientobj*);
57 ExeContext* first_observed_at;
barte7d58722008-02-28 19:08:04 +000058};
59
60struct mutex_info
61{
bart195e41f2009-02-15 11:34:57 +000062 Addr a1;
63 ObjType type;
64 void (*cleanup)(union drd_clientobj*);
65 ExeContext* first_observed_at;
66 MutexT mutex_type; // pthread_mutex_t or pthread_spinlock_t.
67 int recursion_count; // 0 if free, >= 1 if locked.
68 DrdThreadId owner; // owner if locked, last owner if free.
69 struct segment* last_locked_segment;
70 ULong acquiry_time_ms;
71 ExeContext* acquired_at;
barte7d58722008-02-28 19:08:04 +000072};
73
bart28230a32008-02-29 17:27:03 +000074struct cond_info
75{
bart391d9dc2008-07-03 10:57:30 +000076 Addr a1;
77 ObjType type;
78 void (*cleanup)(union drd_clientobj*);
79 ExeContext* first_observed_at;
80 int waiter_count;
81 Addr mutex; // Client mutex specified in pthread_cond_wait() call, and
82 // null if no client threads are currently waiting on this cond.var.
bart28230a32008-02-29 17:27:03 +000083};
84
85struct semaphore_info
86{
87 Addr a1;
bart28230a32008-02-29 17:27:03 +000088 ObjType type;
89 void (*cleanup)(union drd_clientobj*);
bart391d9dc2008-07-03 10:57:30 +000090 ExeContext* first_observed_at;
bartc8914e92008-12-24 09:45:41 +000091 UInt waits_to_skip; // Number of sem_wait() calls to skip
92 // (due to the value assigned by sem_init()).
bartafb42b72008-12-17 07:32:09 +000093 UInt value; // Semaphore value.
bart28230a32008-02-29 17:27:03 +000094 UWord waiters; // Number of threads inside sem_wait().
95 DrdThreadId last_sem_post_tid; // Thread ID associated with last sem_post().
bart3e017fa2008-12-17 19:20:13 +000096 XArray* last_sem_post_seg; // array of Segment*, used as a stack.
bart28230a32008-02-29 17:27:03 +000097};
98
99struct barrier_info
100{
bart9d5b7962008-05-14 12:25:00 +0000101 Addr a1;
102 ObjType type;
103 void (*cleanup)(union drd_clientobj*);
bart391d9dc2008-07-03 10:57:30 +0000104 ExeContext* first_observed_at;
bart306527d2008-03-12 17:23:07 +0000105 BarrierT barrier_type; // pthread_barrier or gomp_barrier.
bart777f7fe2008-03-02 17:43:18 +0000106 Word count; // Participant count in a barrier wait.
107 Word pre_iteration; // pthread_barrier_wait() call count modulo two.
108 Word post_iteration; // pthread_barrier_wait() call count modulo two.
109 Word pre_waiters_left; // number of waiters left for a complete barrier.
110 Word post_waiters_left; // number of waiters left for a complete barrier.
111 OSet* oset; // Thread-specific barrier information.
112};
113
114struct rwlock_info
115{
bart9d5b7962008-05-14 12:25:00 +0000116 Addr a1;
117 ObjType type;
118 void (*cleanup)(union drd_clientobj*);
bart391d9dc2008-07-03 10:57:30 +0000119 ExeContext* first_observed_at;
bart9d5b7962008-05-14 12:25:00 +0000120 OSet* thread_info;
121 ULong acquiry_time_ms;
122 ExeContext* acquired_at;
bart28230a32008-02-29 17:27:03 +0000123};
124
barte7d58722008-02-28 19:08:04 +0000125typedef union drd_clientobj
126{
bart28230a32008-02-29 17:27:03 +0000127 struct any any;
128 struct mutex_info mutex;
129 struct cond_info cond;
130 struct semaphore_info semaphore;
131 struct barrier_info barrier;
bart777f7fe2008-03-02 17:43:18 +0000132 struct rwlock_info rwlock;
barte7d58722008-02-28 19:08:04 +0000133} DrdClientobj;
134
135
bart195e41f2009-02-15 11:34:57 +0000136/* Function declarations. */
barte7d58722008-02-28 19:08:04 +0000137
bart195e41f2009-02-15 11:34:57 +0000138void DRD_(clientobj_set_trace)(const Bool trace);
139void DRD_(clientobj_init)(void);
140void DRD_(clientobj_cleanup)(void);
141DrdClientobj* DRD_(clientobj_get_any)(const Addr addr);
142DrdClientobj* DRD_(clientobj_get)(const Addr addr, const ObjType t);
143Bool DRD_(clientobj_present)(const Addr a1, const Addr a2);
144DrdClientobj* DRD_(clientobj_add)(const Addr a1, const ObjType t);
145Bool DRD_(clientobj_remove)(const Addr addr, const ObjType t);
146void DRD_(clientobj_stop_using_mem)(const Addr a1, const Addr a2);
147void DRD_(clientobj_resetiter)(void);
148DrdClientobj* DRD_(clientobj_next)(const ObjType t);
149const char* DRD_(clientobj_type_name)(const ObjType t);
bart391d9dc2008-07-03 10:57:30 +0000150
barte7d58722008-02-28 19:08:04 +0000151
152#endif /* __DRD_CLIENTOBJ_H */