4
#define STRUCT_PTR(TYPE, MEMBER, a) \
5
(TYPE *) ((char *) (a) - offsetof(TYPE, MEMBER))
7
Link a thread into double-linked queue of waiting threads.
10
wqueue_link_into_queue()
11
wqueue pointer to the queue structure
12
thread pointer to the thread to be added to the queue
18
Queue is represented by a circular list of the thread structures
19
The list is double-linked of the type (**prev,*next), accessed by
20
a pointer to the last element.
23
void wqueue_link_into_queue(WQUEUE *wqueue, struct st_my_thread_var *thread)
25
struct st_my_thread_var *last;
26
if (!(last= wqueue->last_thread))
30
thread->prev= &thread->next;
34
thread->prev= last->next->prev;
35
last->next->prev= &thread->next;
36
thread->next= last->next;
39
wqueue->last_thread= thread;
44
Add a thread to single-linked queue of waiting threads
48
wqueue pointer to the queue structure
49
thread pointer to the thread to be added to the queue
55
Queue is represented by a circular list of the thread structures
56
The list is single-linked of the type (*next), accessed by a pointer
60
void wqueue_add_to_queue(WQUEUE *wqueue, struct st_my_thread_var *thread)
62
struct st_my_thread_var *last;
63
if (!(last= wqueue->last_thread))
67
thread->next= last->next;
71
thread->prev= NULL; /* force segfault if used */
73
wqueue->last_thread= thread;
77
Unlink a thread from double-linked queue of waiting threads
80
wqueue_unlink_from_queue()
81
wqueue pointer to the queue structure
82
thread pointer to the thread to be removed from the queue
88
See NOTES for link_into_queue
91
void wqueue_unlink_from_queue(WQUEUE *wqueue, struct st_my_thread_var *thread)
93
if (thread->next == thread)
94
/* The queue contains only one member */
95
wqueue->last_thread= NULL;
98
thread->next->prev= thread->prev;
99
*thread->prev= thread->next;
100
if (wqueue->last_thread == thread)
101
wqueue->last_thread= STRUCT_PTR(struct st_my_thread_var, next,
109
Remove all threads from queue signaling them to proceed
112
wqueue_realease_queue()
113
wqueue pointer to the queue structure
114
thread pointer to the thread to be added to the queue
120
See notes for add_to_queue
121
When removed from the queue each thread is signaled via condition
122
variable thread->suspend.
125
void wqueue_release_queue(WQUEUE *wqueue)
127
struct st_my_thread_var *last= wqueue->last_thread;
128
struct st_my_thread_var *next= last->next;
129
struct st_my_thread_var *thread;
133
pthread_cond_signal(&thread->suspend);
137
while (thread != last);
138
wqueue->last_thread= NULL;
143
@brief Removes all threads waiting for read or first one waiting for write.
145
@param wqueue pointer to the queue structure
146
@param thread pointer to the thread to be added to the queue
148
@note This function is applicable only to single linked lists.
151
void wqueue_release_one_locktype_from_queue(WQUEUE *wqueue)
153
struct st_my_thread_var *last= wqueue->last_thread;
154
struct st_my_thread_var *next= last->next;
155
struct st_my_thread_var *thread;
156
struct st_my_thread_var *new_list= NULL;
157
uint first_type= next->lock_type;
158
if (first_type == MY_PTHREAD_LOCK_WRITE)
160
/* release first waiting for write lock */
161
pthread_cond_signal(&next->suspend);
163
wqueue->last_thread= NULL;
165
last->next= next->next;
173
if (thread->lock_type == MY_PTHREAD_LOCK_WRITE)
175
/* skip waiting for write lock */
178
thread->next= new_list->next;
179
new_list= new_list->next= thread;
182
new_list= thread->next= thread;
186
/* release waiting for read lock */
187
pthread_cond_signal(&thread->suspend);
190
} while (thread != last);
191
wqueue->last_thread= new_list;
199
wqueue_add_and_wait()
200
wqueue queue to add to
201
thread thread which is waiting
202
lock mutex need for the operation
205
void wqueue_add_and_wait(WQUEUE *wqueue,
206
struct st_my_thread_var *thread,
207
pthread_mutex_t *lock)
209
DBUG_ENTER("wqueue_add_and_wait");
211
("thread: 0x%lx cond: 0x%lx mutex: 0x%lx",
212
(ulong) thread, (ulong) &thread->suspend, (ulong) lock));
213
wqueue_add_to_queue(wqueue, thread);
216
DBUG_PRINT("info", ("wait... cond: 0x%lx mutex: 0x%lx",
217
(ulong) &thread->suspend, (ulong) lock));
218
pthread_cond_wait(&thread->suspend, lock);
219
DBUG_PRINT("info", ("wait done cond: 0x%lx mutex: 0x%lx next: 0x%lx",
220
(ulong) &thread->suspend, (ulong) lock,
221
(ulong) thread->next));
223
while (thread->next);