~posulliv/drizzle/optimizer-style-cleanup

« back to all changes in this revision

Viewing changes to plugin/pbxt/src/pthread_xt.cc

  • Committer: Padraig O'Sullivan
  • Date: 2010-04-17 01:38:47 UTC
  • mfrom: (1237.9.238 bad-staging)
  • Revision ID: osullivan.padraig@gmail.com-20100417013847-ibjioqsfbmf5yg4g
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (c) 2005 PrimeBase Technologies GmbH
 
2
 *
 
3
 * PrimeBase XT
 
4
 *
 
5
 * This program is free software; you can redistribute it and/or modify
 
6
 * it under the terms of the GNU General Public License as published by
 
7
 * the Free Software Foundation; either version 2 of the License, or
 
8
 * (at your option) any later version.
 
9
 *
 
10
 * This program is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
13
 * GNU General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU General Public License
 
16
 * along with this program; if not, write to the Free Software
 
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
18
 *
 
19
 * 2006-03-22   Paul McCullagh
 
20
 *
 
21
 * H&G2JCtL
 
22
 *
 
23
 * This file contains windows specific code
 
24
 */
 
25
 
 
26
#include "xt_config.h"
 
27
 
 
28
#ifdef XT_WIN
 
29
#include <my_pthread.h>
 
30
#else
 
31
#ifdef DRIZZLED
 
32
#include <unistd.h>
 
33
#endif
 
34
#include <sys/resource.h>
 
35
#endif
 
36
#include <errno.h>
 
37
#include <limits.h>
 
38
#include <string.h>
 
39
 
 
40
#include "pthread_xt.h"
 
41
#include "thread_xt.h"
 
42
 
 
43
#ifdef XT_WIN
 
44
 
 
45
xtPublic void xt_p_init_threading(void)
 
46
{
 
47
}
 
48
 
 
49
xtPublic int xt_p_set_normal_priority(pthread_t thr)
 
50
{
 
51
        if (!SetThreadPriority (thr, THREAD_PRIORITY_NORMAL))
 
52
                return GetLastError();
 
53
        return 0;
 
54
}
 
55
 
 
56
xtPublic int xt_p_set_low_priority(pthread_t thr)
 
57
{
 
58
        if (!SetThreadPriority (thr, THREAD_PRIORITY_LOWEST))
 
59
                return GetLastError();
 
60
        return 0;
 
61
}
 
62
 
 
63
xtPublic int xt_p_set_high_priority(pthread_t thr)
 
64
{
 
65
        if (!SetThreadPriority (thr, THREAD_PRIORITY_HIGHEST))
 
66
                return GetLastError();
 
67
        return 0;
 
68
}
 
69
 
 
70
#define XT_RWLOCK_MAGIC 0x78AC390E
 
71
 
 
72
#ifdef XT_THREAD_LOCK_INFO
 
73
xtPublic int xt_p_mutex_init(xt_mutex_type *mutex, const pthread_mutexattr_t *attr, const char *n)
 
74
#else
 
75
xtPublic int xt_p_mutex_init(xt_mutex_type *mutex, const pthread_mutexattr_t *attr)
 
76
#endif
 
77
{
 
78
        InitializeCriticalSection(&mutex->mt_cs);
 
79
#ifdef XT_THREAD_LOCK_INFO
 
80
        xt_thread_lock_info_init(&mutex->mt_lock_info, mutex);
 
81
        mutex->mt_name = n;
 
82
#endif
 
83
        return 0;
 
84
}
 
85
 
 
86
xtPublic int xt_p_mutex_destroy(xt_mutex_type *mutex)
 
87
{
 
88
        DeleteCriticalSection(&mutex->mt_cs);
 
89
#ifdef XT_THREAD_LOCK_INFO
 
90
        xt_thread_lock_info_free(&mutex->mt_lock_info);
 
91
#endif
 
92
        return 0;
 
93
}
 
94
 
 
95
xtPublic int xt_p_mutex_lock(xt_mutex_type *mx)
 
96
{
 
97
        EnterCriticalSection(&mx->mt_cs);
 
98
#ifdef XT_THREAD_LOCK_INFO
 
99
        xt_thread_lock_info_add_owner(&mx->mt_lock_info);
 
100
#endif
 
101
        return 0;
 
102
}
 
103
 
 
104
xtPublic int xt_p_mutex_unlock(xt_mutex_type *mx)
 
105
{
 
106
        LeaveCriticalSection(&mx->mt_cs);
 
107
#ifdef XT_THREAD_LOCK_INFO
 
108
        xt_thread_lock_info_release_owner(&mx->mt_lock_info);
 
109
#endif
 
110
        return 0;
 
111
}
 
112
 
 
113
xtPublic int xt_p_mutex_trylock(xt_mutex_type *mutex)
 
114
{
 
115
#if(_WIN32_WINNT >= 0x0400)
 
116
        /* NOTE: MySQL bug! was using?!
 
117
         * pthread_mutex_trylock(A) (WaitForSingleObject((A), 0) == WAIT_TIMEOUT)
 
118
         */
 
119
        if (TryEnterCriticalSection(&mutex->mt_cs)) {
 
120
#ifdef XT_THREAD_LOCK_INFO
 
121
                xt_thread_lock_info_add_owner(&mutex->mt_lock_info);
 
122
#endif
 
123
                return 0;
 
124
        }
 
125
        return WAIT_TIMEOUT;
 
126
#else
 
127
        EnterCriticalSection(&mutex->mt_cs);
 
128
#ifdef XT_THREAD_LOCK_INFO
 
129
        xt_thread_lock_info_add_owner(&mutex->mt_lock_info);
 
130
#endif
 
131
        return 0;
 
132
#endif
 
133
}
 
134
 
 
135
#ifdef XT_THREAD_LOCK_INFO
 
136
xtPublic int xt_p_rwlock_init(xt_rwlock_type *rwl, const pthread_condattr_t *attr, const char *n)
 
137
#else
 
138
xtPublic int xt_p_rwlock_init(xt_rwlock_type *rwl, const pthread_condattr_t *attr)
 
139
#endif
 
140
{
 
141
        int result;
 
142
 
 
143
        if (rwl == NULL)
 
144
                return ERROR_BAD_ARGUMENTS;
 
145
 
 
146
        rwl->rw_sh_count = 0;
 
147
        rwl->rw_ex_count = 0;
 
148
        rwl->rw_sh_complete_count = 0;
 
149
 
 
150
        result = xt_p_mutex_init_with_autoname(&rwl->rw_ex_lock, NULL);
 
151
        if (result != 0)
 
152
                goto failed;
 
153
 
 
154
        result = xt_p_mutex_init_with_autoname(&rwl->rw_sh_lock, NULL);
 
155
        if (result != 0)
 
156
                goto failed_2;
 
157
 
 
158
        result = pthread_cond_init(&rwl->rw_sh_cond, NULL);
 
159
        if (result != 0)
 
160
                goto failed_3;
 
161
 
 
162
        rwl->rw_magic = XT_RWLOCK_MAGIC;
 
163
#ifdef XT_THREAD_LOCK_INFO
 
164
        rwl->rw_name = n;
 
165
        xt_thread_lock_info_init(&rwl->rw_lock_info, rwl);
 
166
#endif
 
167
        return 0;
 
168
 
 
169
        failed_3:
 
170
        (void) xt_p_mutex_destroy(&rwl->rw_sh_lock);
 
171
 
 
172
        failed_2:
 
173
        (void) xt_p_mutex_destroy(&rwl->rw_ex_lock);
 
174
 
 
175
        failed:
 
176
        return result;
 
177
}
 
178
 
 
179
xtPublic int xt_p_rwlock_destroy(xt_rwlock_type *rwl)
 
180
{
 
181
        int result = 0, result1 = 0, result2 = 0;
 
182
 
 
183
        if (rwl == NULL)
 
184
                return ERROR_BAD_ARGUMENTS;
 
185
 
 
186
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
 
187
                return ERROR_BAD_ARGUMENTS;
 
188
 
 
189
        if ((result = xt_p_mutex_lock(&rwl->rw_ex_lock)) != 0)
 
190
                return result;
 
191
 
 
192
        if ((result = xt_p_mutex_lock(&rwl->rw_sh_lock)) != 0) {
 
193
                (void) xt_p_mutex_unlock(&rwl->rw_ex_lock);
 
194
                return result;
 
195
        }
 
196
 
 
197
        /*
 
198
         * Check whether any threads own/wait for the lock (wait for ex.access);
 
199
         * report "BUSY" if so.
 
200
         */
 
201
        if (rwl->rw_ex_count > 0 || rwl->rw_sh_count > rwl->rw_sh_complete_count) {
 
202
                result = xt_p_mutex_unlock(&rwl->rw_sh_lock);
 
203
                result1 = xt_p_mutex_unlock(&rwl->rw_ex_lock);
 
204
                result2 = ERROR_BUSY;
 
205
        }
 
206
        else {
 
207
                rwl->rw_magic = 0;
 
208
 
 
209
                if ((result = xt_p_mutex_unlock(&rwl->rw_sh_lock)) != 0)
 
210
                {
 
211
                        xt_p_mutex_unlock(&rwl->rw_ex_lock);
 
212
                        return result;
 
213
                }
 
214
 
 
215
                if ((result = xt_p_mutex_unlock(&rwl->rw_ex_lock)) != 0)
 
216
                        return result;
 
217
 
 
218
                result = pthread_cond_destroy(&rwl->rw_sh_cond);
 
219
                result1 = xt_p_mutex_destroy(&rwl->rw_sh_lock);
 
220
                result2 = xt_p_mutex_destroy(&rwl->rw_ex_lock);
 
221
        }
 
222
 
 
223
#ifdef XT_THREAD_LOCK_INFO
 
224
        xt_thread_lock_info_free(&rwl->rw_lock_info);
 
225
#endif
 
226
 
 
227
        return (result != 0) ? result : ((result1 != 0) ? result1 : result2);
 
228
}
 
229
 
 
230
 
 
231
xtPublic int xt_p_rwlock_rdlock(xt_rwlock_type *rwl)
 
232
{
 
233
        int result;
 
234
 
 
235
        if (rwl == NULL)
 
236
                return ERROR_BAD_ARGUMENTS;
 
237
 
 
238
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
 
239
                return ERROR_BAD_ARGUMENTS;
 
240
 
 
241
        if ((result = xt_p_mutex_lock(&rwl->rw_ex_lock)) != 0)
 
242
                return result;
 
243
 
 
244
        if (++rwl->rw_sh_count == INT_MAX) {
 
245
                if ((result = xt_p_mutex_lock(&rwl->rw_sh_lock)) != 0)
 
246
                {
 
247
                        (void) xt_p_mutex_unlock(&rwl->rw_ex_lock);
 
248
                        return result;
 
249
                }
 
250
 
 
251
                rwl->rw_sh_count -= rwl->rw_sh_complete_count;
 
252
                rwl->rw_sh_complete_count = 0;
 
253
 
 
254
                if ((result = xt_p_mutex_unlock(&rwl->rw_sh_lock)) != 0)
 
255
                {
 
256
                        (void) xt_p_mutex_unlock(&rwl->rw_ex_lock);
 
257
                        return result;
 
258
                }
 
259
        }
 
260
 
 
261
#ifdef XT_THREAD_LOCK_INFO
 
262
        xt_thread_lock_info_add_owner(&rwl->rw_lock_info);
 
263
#endif
 
264
 
 
265
        return (xt_p_mutex_unlock (&(rwl->rw_ex_lock)));
 
266
}
 
267
 
 
268
xtPublic int xt_p_rwlock_wrlock(xt_rwlock_type *rwl)
 
269
{
 
270
        int result;
 
271
 
 
272
        if (rwl == NULL)
 
273
                return ERROR_BAD_ARGUMENTS;
 
274
 
 
275
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
 
276
                return ERROR_BAD_ARGUMENTS;
 
277
 
 
278
        if ((result = xt_p_mutex_lock (&rwl->rw_ex_lock)) != 0)
 
279
                return result;
 
280
 
 
281
        if ((result = xt_p_mutex_lock (&rwl->rw_sh_lock)) != 0) {
 
282
                (void) xt_p_mutex_unlock (&rwl->rw_ex_lock);
 
283
                return result;
 
284
        }
 
285
 
 
286
        if (rwl->rw_ex_count == 0) {
 
287
                if (rwl->rw_sh_complete_count > 0) {
 
288
                        rwl->rw_sh_count -= rwl->rw_sh_complete_count;
 
289
                        rwl->rw_sh_complete_count = 0;
 
290
                }
 
291
 
 
292
                if (rwl->rw_sh_count > 0) {
 
293
                        rwl->rw_sh_complete_count = -rwl->rw_sh_count;
 
294
 
 
295
                        do {
 
296
                                result = pthread_cond_wait (&rwl->rw_sh_cond, &rwl->rw_sh_lock.mt_cs);
 
297
                        }
 
298
                        while (result == 0 && rwl->rw_sh_complete_count < 0);
 
299
 
 
300
                        if (result == 0)
 
301
                                rwl->rw_sh_count = 0;
 
302
                }
 
303
        }
 
304
 
 
305
        if (result == 0)
 
306
                rwl->rw_ex_count++;
 
307
 
 
308
#ifdef XT_THREAD_LOCK_INFO
 
309
        xt_thread_lock_info_add_owner(&rwl->rw_lock_info);
 
310
#endif
 
311
 
 
312
        return result;
 
313
}
 
314
 
 
315
xtPublic xtBool xt_p_rwlock_try_wrlock(xt_rwlock_type *rwl)
 
316
{
 
317
        int result;
 
318
 
 
319
        if (rwl == NULL)
 
320
                return FALSE;
 
321
 
 
322
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
 
323
                return FALSE;
 
324
 
 
325
        if ((result = xt_p_mutex_trylock(&rwl->rw_ex_lock)) != 0)
 
326
                return FALSE;
 
327
 
 
328
        if ((result = xt_p_mutex_lock(&rwl->rw_sh_lock)) != 0) {
 
329
                (void) xt_p_mutex_unlock(&rwl->rw_ex_lock);
 
330
                return FALSE;
 
331
        }
 
332
 
 
333
        if (rwl->rw_ex_count == 0) {
 
334
                if (rwl->rw_sh_complete_count > 0) {
 
335
                        rwl->rw_sh_count -= rwl->rw_sh_complete_count;
 
336
                        rwl->rw_sh_complete_count = 0;
 
337
                }
 
338
 
 
339
                if (rwl->rw_sh_count > 0) {
 
340
                        rwl->rw_sh_complete_count = -rwl->rw_sh_count;
 
341
 
 
342
                        do {
 
343
                                result = pthread_cond_wait (&rwl->rw_sh_cond, &rwl->rw_sh_lock.mt_cs);
 
344
                        }
 
345
                        while (result == 0 && rwl->rw_sh_complete_count < 0);
 
346
 
 
347
                        if (result == 0)
 
348
                                rwl->rw_sh_count = 0;
 
349
                }
 
350
        }
 
351
 
 
352
        if (result == 0)
 
353
                rwl->rw_ex_count++;
 
354
 
 
355
#ifdef XT_THREAD_LOCK_INFO
 
356
        xt_thread_lock_info_add_owner(&rwl->rw_lock_info);
 
357
#endif
 
358
 
 
359
        return TRUE;
 
360
}
 
361
 
 
362
xtPublic int xt_p_rwlock_unlock(xt_rwlock_type *rwl)
 
363
{
 
364
        int result, result1;
 
365
 
 
366
        if (rwl == NULL)
 
367
                return (ERROR_BAD_ARGUMENTS);
 
368
 
 
369
        if (rwl->rw_magic != XT_RWLOCK_MAGIC)
 
370
                return ERROR_BAD_ARGUMENTS;
 
371
 
 
372
        if (rwl->rw_ex_count == 0) {
 
373
                if ((result = xt_p_mutex_lock(&rwl->rw_sh_lock)) != 0)
 
374
                        return result;
 
375
 
 
376
                if (++rwl->rw_sh_complete_count == 0)
 
377
                        result = pthread_cond_signal(&rwl->rw_sh_cond);
 
378
 
 
379
                result1 = xt_p_mutex_unlock(&rwl->rw_sh_lock);
 
380
        }
 
381
        else {
 
382
                rwl->rw_ex_count--;
 
383
 
 
384
                result = xt_p_mutex_unlock(&rwl->rw_sh_lock);
 
385
                result1 = xt_p_mutex_unlock(&rwl->rw_ex_lock);
 
386
        }
 
387
 
 
388
#ifdef XT_THREAD_LOCK_INFO
 
389
        xt_thread_lock_info_release_owner(&rwl->rw_lock_info);
 
390
#endif
 
391
 
 
392
        return ((result != 0) ? result : result1);
 
393
}
 
394
 
 
395
xtPublic int xt_p_cond_wait(xt_cond_type *cond, xt_mutex_type *mutex)
 
396
{
 
397
        return xt_p_cond_timedwait(cond, mutex, NULL);
 
398
}
 
399
 
 
400
xtPublic int xt_p_cond_timedwait(xt_cond_type *cond, xt_mutex_type *mt, struct timespec *abstime)
 
401
{
 
402
        pthread_mutex_t *mutex = &mt->mt_cs;
 
403
        int                             result;
 
404
        long                    timeout; 
 
405
        union ft64              now;
 
406
 
 
407
        if (abstime != NULL) {
 
408
                GetSystemTimeAsFileTime(&now.ft);
 
409
 
 
410
                timeout = (long)((abstime->tv.i64 - now.i64) / 10000);
 
411
                if (timeout < 0)
 
412
                        timeout = 0L;
 
413
                if (timeout > abstime->max_timeout_msec)
 
414
                        timeout = abstime->max_timeout_msec;
 
415
        }
 
416
        else
 
417
                timeout= INFINITE;
 
418
 
 
419
        WaitForSingleObject(cond->broadcast_block_event, INFINITE);
 
420
 
 
421
        EnterCriticalSection(&cond->lock_waiting);
 
422
        cond->waiting++;
 
423
        LeaveCriticalSection(&cond->lock_waiting);
 
424
 
 
425
        LeaveCriticalSection(mutex);
 
426
 
 
427
        result= WaitForMultipleObjects(2, cond->events, FALSE, timeout);
 
428
 
 
429
        EnterCriticalSection(&cond->lock_waiting);
 
430
        cond->waiting--;
 
431
        
 
432
        if (cond->waiting == 0) {
 
433
                /* The last waiter must reset the broadcast
 
434
                 * state (whther there was a broadcast or not)!
 
435
                 */
 
436
                ResetEvent(cond->events[xt_cond_type::BROADCAST]);
 
437
                SetEvent(cond->broadcast_block_event);
 
438
        }
 
439
        LeaveCriticalSection(&cond->lock_waiting);
 
440
        
 
441
        EnterCriticalSection(mutex);
 
442
 
 
443
        return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
 
444
}
 
445
 
 
446
xtPublic int xt_p_join(pthread_t thread, void **value)
 
447
{
 
448
        DWORD exitcode;
 
449
 
 
450
        while(1) {
 
451
                switch (WaitForSingleObject(thread, 10000)) {
 
452
                        case WAIT_OBJECT_0:
 
453
                                return 0;
 
454
                        case WAIT_TIMEOUT:
 
455
                                /* Don't do this! According to the Win docs:
 
456
                                 * _endthread automatically closes the thread handle
 
457
                                 * (whereas _endthreadex does not). Therefore, when using
 
458
                                 * _beginthread and _endthread, do not explicitly close the
 
459
                                 * thread handle by calling the Win32 CloseHandle API.
 
460
                                CloseHandle(thread);
 
461
                                 */
 
462
                                /* This is done so that if the thread was not [yet] in the running
 
463
                                 * state when this function was called we won't deadlock here.
 
464
                                 */
 
465
                                if (GetExitCodeThread(thread, &exitcode) && (exitcode == STILL_ACTIVE))
 
466
                                        break;
 
467
                                return 0;
 
468
                        case WAIT_FAILED:
 
469
                                return GetLastError();
 
470
                }
 
471
        }
 
472
 
 
473
        return 0;
 
474
}
 
475
 
 
476
#else // XT_WIN
 
477
 
 
478
#ifdef __darwin__
 
479
#define POLICY                  SCHED_RR
 
480
#else
 
481
#define POLICY                  pth_policy
 
482
#endif
 
483
 
 
484
static int pth_policy;
 
485
static int pth_normal_priority;
 
486
static int pth_min_priority;
 
487
static int pth_max_priority;
 
488
 
 
489
/* Return zero if the priority was set OK,
 
490
 * else errno.
 
491
 */
 
492
static int pth_set_priority(pthread_t thread, int priority)
 
493
{
 
494
        struct sched_param      sp;
 
495
 
 
496
        memset(&sp, 0, sizeof(struct sched_param));
 
497
        sp.sched_priority = priority;
 
498
        return pthread_setschedparam(thread, POLICY, &sp);
 
499
}
 
500
 
 
501
static void pth_get_priority_limits(void)
 
502
{
 
503
        XTThreadPtr                     self = NULL;
 
504
        struct sched_param      sp;
 
505
        int                                     err;
 
506
        int                                     start;
 
507
 
 
508
        /* Save original priority: */
 
509
        err = pthread_getschedparam(pthread_self(), &pth_policy, &sp);
 
510
        if (err) {
 
511
                xt_throw_errno(XT_CONTEXT, err);
 
512
                return;
 
513
        }
 
514
        pth_normal_priority = sp.sched_priority;
 
515
 
 
516
        start = sp.sched_priority;
 
517
 
 
518
#ifdef XT_FREEBSD 
 
519
        pth_min_priority = sched_get_priority_min(sched_getscheduler(0));
 
520
        pth_max_priority = sched_get_priority_max(sched_getscheduler(0));
 
521
#else
 
522
        /* Search for the minimum priority: */
 
523
        pth_min_priority = start;
 
524
        for (;;) {
 
525
                /* 2007-03-01: Corrected, pth_set_priority returns the error code
 
526
                 * (thanks to Hakan for pointing out this bug!)
 
527
                 */
 
528
                if (pth_set_priority(pthread_self(), pth_min_priority-1) != 0)
 
529
                        break;
 
530
                pth_min_priority--;
 
531
        }
 
532
 
 
533
        /* Search for the maximum priority: */
 
534
        pth_max_priority = start;
 
535
        for (;;) {
 
536
                if (pth_set_priority(pthread_self(), pth_max_priority+1) != 0)
 
537
                        break;
 
538
                pth_max_priority++;
 
539
        }
 
540
 
 
541
        /* Restore original priority: */
 
542
        pthread_setschedparam(pthread_self(), pth_policy, &sp);
 
543
#endif
 
544
}
 
545
 
 
546
xtPublic void xt_p_init_threading(void)
 
547
{
 
548
        pth_get_priority_limits();
 
549
}
 
550
 
 
551
xtPublic int xt_p_set_low_priority(pthread_t thr)
 
552
{
 
553
        if (pth_min_priority == pth_max_priority) {
 
554
                /* Under Linux the priority of normal (non-runtime)
 
555
                 * threads are set using the standard methods
 
556
                 * for setting process priority.
 
557
                 */
 
558
 
 
559
                /* We could set who == 0 because it should have the same affect
 
560
                 * as using the PID.
 
561
                 */
 
562
 
 
563
                /* -20 = highest, 20 = lowest */
 
564
                if (setpriority(PRIO_PROCESS, getpid(), 20) == -1)
 
565
                        return errno;
 
566
                return 0;
 
567
        }
 
568
        return pth_set_priority(thr, pth_min_priority);
 
569
}
 
570
 
 
571
xtPublic int xt_p_set_normal_priority(pthread_t thr)
 
572
{
 
573
        if (pth_min_priority == pth_max_priority) {
 
574
                if (setpriority(PRIO_PROCESS, getpid(), 0) == -1)
 
575
                        return errno;
 
576
                return 0;
 
577
        }
 
578
        return pth_set_priority(thr, pth_normal_priority);
 
579
}
 
580
 
 
581
xtPublic int xt_p_set_high_priority(pthread_t thr)
 
582
{
 
583
        if (pth_min_priority == pth_max_priority) {
 
584
                if (setpriority(PRIO_PROCESS, getpid(), -20) == -1) {
 
585
                        if (errno == EACCES) {
 
586
                               if (setpriority(PRIO_PROCESS, getpid(), 0) == -1) {
 
587
                                        if (errno != EACCES)
 
588
                                                return errno;
 
589
                                }
 
590
                        }
 
591
                }
 
592
                return 0;
 
593
        }
 
594
        return pth_set_priority(thr, pth_max_priority);
 
595
}
 
596
 
 
597
#ifdef DEBUG_LOCKING
 
598
 
 
599
xtPublic int xt_p_mutex_lock(xt_mutex_type *mutex, u_int line, const char *file)
 
600
{
 
601
        XTThreadPtr self = xt_get_self();
 
602
        int                     r;
 
603
 
 
604
        ASSERT_NS(mutex->mu_init == 12345);
 
605
        r = pthread_mutex_lock(&mutex->mu_plock);
 
606
        if (r == 0) {
 
607
                if (mutex->mu_trace)
 
608
                        printf("==LOCK mutex %d %s:%d\n", (int) mutex->mu_trace, file, (int) line);
 
609
                ASSERT_NS(!mutex->mu_locker);
 
610
                mutex->mu_locker = self;
 
611
                mutex->mu_line = line;
 
612
                mutex->mu_file = file;
 
613
        }
 
614
#ifdef XT_THREAD_LOCK_INFO
 
615
        xt_thread_lock_info_add_owner(&mutex->mu_lock_info);
 
616
#endif
 
617
        return r;
 
618
}
 
619
 
 
620
xtPublic int xt_p_mutex_unlock(xt_mutex_type *mutex)
 
621
{
 
622
        XTThreadPtr self = xt_get_self();
 
623
 
 
624
        ASSERT_NS(mutex->mu_init == 12345);
 
625
        ASSERT_NS(mutex->mu_locker == self);
 
626
        mutex->mu_locker = NULL;
 
627
        if (mutex->mu_trace)
 
628
                printf("UNLOCK mutex %d\n", (int) mutex->mu_trace);
 
629
#ifdef XT_THREAD_LOCK_INFO
 
630
        xt_thread_lock_info_release_owner(&mutex->mu_lock_info);
 
631
#endif
 
632
        return pthread_mutex_unlock(&mutex->mu_plock);
 
633
}
 
634
 
 
635
xtPublic int xt_p_mutex_destroy(xt_mutex_type *mutex)
 
636
{
 
637
        ASSERT_NS(mutex->mu_init == 12345 || !mutex->mu_init || mutex->mu_init == 11111);
 
638
        mutex->mu_init = 11111;
 
639
#ifdef XT_THREAD_LOCK_INFO
 
640
        xt_thread_lock_info_free(&mutex->mu_lock_info);
 
641
#endif
 
642
        return pthread_mutex_destroy(&mutex->mu_plock);
 
643
}
 
644
 
 
645
xtPublic int xt_p_mutex_trylock(xt_mutex_type *mutex)
 
646
{
 
647
        XTThreadPtr self = xt_get_self();
 
648
        int                     r;
 
649
 
 
650
        ASSERT_NS(mutex->mu_init == 12345);
 
651
        r = pthread_mutex_trylock(&mutex->mu_plock);
 
652
        if (r == 0) {
 
653
                ASSERT_NS(!mutex->mu_locker);
 
654
                mutex->mu_locker = self;
 
655
#ifdef XT_THREAD_LOCK_INFO
 
656
                xt_thread_lock_info_add_owner(&mutex->mu_lock_info);
 
657
#endif
 
658
        }
 
659
        return r;
 
660
}
 
661
 
 
662
#ifdef XT_THREAD_LOCK_INFO
 
663
xtPublic int xt_p_mutex_init(xt_mutex_type *mutex, const pthread_mutexattr_t *attr, const char *n)
 
664
#else
 
665
xtPublic int xt_p_mutex_init(xt_mutex_type *mutex, const pthread_mutexattr_t *attr)
 
666
#endif
 
667
{
 
668
        mutex->mu_init = 12345;
 
669
        mutex->mu_trace = FALSE;
 
670
        mutex->mu_locker = NULL;
 
671
#ifdef XT_THREAD_LOCK_INFO
 
672
        mutex->mu_name = n;
 
673
        xt_thread_lock_info_init(&mutex->mu_lock_info, mutex);
 
674
#endif
 
675
        return pthread_mutex_init(&mutex->mu_plock, attr);
 
676
}
 
677
 
 
678
xtPublic int xt_p_cond_wait(xt_cond_type *cond, xt_mutex_type *mutex)
 
679
{
 
680
        XTThreadPtr self = xt_get_self();
 
681
        int                     r;
 
682
 
 
683
        ASSERT_NS(mutex->mu_init == 12345);
 
684
        ASSERT_NS(mutex->mu_locker == self);
 
685
        mutex->mu_locker = NULL;
 
686
        r = pthread_cond_wait(cond, &mutex->mu_plock);
 
687
        ASSERT_NS(!mutex->mu_locker);
 
688
        mutex->mu_locker = self;
 
689
        return r;
 
690
}
 
691
 
 
692
xtPublic int xt_p_cond_timedwait(xt_cond_type *cond, xt_mutex_type *mutex, const struct timespec *abstime)
 
693
{
 
694
        XTThreadPtr self = xt_get_self();
 
695
        int                     r;
 
696
 
 
697
        ASSERT_NS(mutex->mu_init == 12345);
 
698
        ASSERT_NS(mutex->mu_locker == self);
 
699
        mutex->mu_locker = NULL;
 
700
        r = pthread_cond_timedwait(cond, &mutex->mu_plock, abstime);
 
701
        ASSERT_NS(!mutex->mu_locker);
 
702
        mutex->mu_locker = self;
 
703
        return r;
 
704
}
 
705
 
 
706
xtPublic int xt_p_rwlock_rdlock(xt_rwlock_type *rwlock)
 
707
{
 
708
        int r;
 
709
 
 
710
        ASSERT_NS(rwlock->rw_init == 67890);
 
711
        r = pthread_rwlock_rdlock(&rwlock->rw_plock);
 
712
#ifdef XT_THREAD_LOCK_INFO
 
713
        xt_thread_lock_info_add_owner(&rwlock->rw_lock_info);
 
714
#endif
 
715
        return r;
 
716
}
 
717
 
 
718
xtPublic int xt_p_rwlock_wrlock(xt_rwlock_type *rwlock)
 
719
{
 
720
        XTThreadPtr self = xt_get_self();
 
721
        int                     r;
 
722
 
 
723
        ASSERT_NS(rwlock->rw_init == 67890);
 
724
        r = pthread_rwlock_wrlock(&rwlock->rw_plock);
 
725
        if (r == 0) {
 
726
                ASSERT_NS(!rwlock->rw_locker);
 
727
                rwlock->rw_locker = self;
 
728
        }
 
729
#ifdef XT_THREAD_LOCK_INFO
 
730
        xt_thread_lock_info_add_owner(&rwlock->rw_lock_info);
 
731
#endif
 
732
        return r;
 
733
}
 
734
 
 
735
xtPublic xtBool xt_p_rwlock_try_wrlock(xt_rwlock_type *rwlock)
 
736
{
 
737
        XTThreadPtr self = xt_get_self();
 
738
        int                     r;
 
739
 
 
740
        ASSERT_NS(rwlock->rw_init == 67890);
 
741
        r = pthread_rwlock_trywrlock(&rwlock->rw_plock);
 
742
        if (r == 0) {
 
743
                ASSERT_NS(!rwlock->rw_locker);
 
744
                rwlock->rw_locker = self;
 
745
#ifdef XT_THREAD_LOCK_INFO
 
746
                xt_thread_lock_info_add_owner(&rwlock->rw_lock_info);
 
747
#endif
 
748
        }
 
749
        return r == 0;
 
750
}
 
751
 
 
752
xtPublic int xt_p_rwlock_unlock(xt_rwlock_type *rwlock)
 
753
{
 
754
        XTThreadPtr self = xt_get_self();
 
755
 
 
756
        ASSERT_NS(rwlock->rw_init == 67890);
 
757
        if (rwlock->rw_locker) {
 
758
                ASSERT_NS(rwlock->rw_locker == self);
 
759
                rwlock->rw_locker = NULL;
 
760
        }
 
761
#ifdef XT_THREAD_LOCK_INFO
 
762
        xt_thread_lock_info_release_owner(&rwlock->rw_lock_info);
 
763
#endif
 
764
        return pthread_rwlock_unlock(&rwlock->rw_plock);
 
765
}
 
766
 
 
767
xtPublic int xt_p_rwlock_destroy(xt_rwlock_type *rwlock)
 
768
{
 
769
        ASSERT_NS(rwlock->rw_init == 67890);
 
770
        rwlock->rw_init = 0;
 
771
#ifdef XT_THREAD_LOCK_INFO
 
772
        xt_thread_lock_info_free(&rwlock->rw_lock_info);
 
773
#endif
 
774
        return pthread_rwlock_destroy(&rwlock->rw_plock);
 
775
}
 
776
 
 
777
#ifdef XT_THREAD_LOCK_INFO
 
778
xtPublic int xt_p_rwlock_init(xt_rwlock_type *rwlock, const pthread_rwlockattr_t *attr, const char *n)
 
779
#else
 
780
xtPublic int xt_p_rwlock_init(xt_rwlock_type *rwlock, const pthread_rwlockattr_t *attr)
 
781
#endif
 
782
{
 
783
        rwlock->rw_init = 67890;
 
784
        rwlock->rw_readers = 0;
 
785
        rwlock->rw_locker = NULL;
 
786
#ifdef XT_THREAD_LOCK_INFO
 
787
        rwlock->rw_name = n;
 
788
        xt_thread_lock_info_init(&rwlock->rw_lock_info, rwlock);
 
789
#endif
 
790
        return pthread_rwlock_init(&rwlock->rw_plock, attr);
 
791
}
 
792
 
 
793
#endif // DEBUG_LOCKING
 
794
 
 
795
#endif // XT_WIN
 
796