Diff
Not logged in

Differences From Artifact [a83393e28d]:

To Artifact [8107bc2ad4]:


18
19
20
21
22
23
24
25

26
27
28
29
30

31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52


53
54
55
56
57
58
59
18
19
20
21
22
23
24

25
26
27
28
29

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50


51
52
53
54
55
56
57
58
59







-
+




-
+




















-
-
+
+







typedef struct ThreadSpecificData {
    char nabuf[16];
} ThreadSpecificData;

static Tcl_ThreadDataKey dataKey;

/*
 * masterLock is used to serialize creation of mutexes, condition variables,
 * mainLock is used to serialize creation of mutexes, condition variables,
 * and thread local storage. This is the only place that can count on the
 * ability to statically initialize the mutex.
 */

static pthread_mutex_t masterLock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t mainLock = PTHREAD_MUTEX_INITIALIZER;

/*
 * initLock is used to serialize initialization and finalization of Tcl. It
 * cannot use any dyamically allocated storage.
 */

static pthread_mutex_t initLock = PTHREAD_MUTEX_INITIALIZER;

/*
 * allocLock is used by Tcl's version of malloc for synchronization. For
 * obvious reasons, cannot use any dyamically allocated storage.
 */

static pthread_mutex_t allocLock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t *allocLockPtr = &allocLock;

/*
 * These are for the critical sections inside this file.
 */

#define MASTER_LOCK	pthread_mutex_lock(&masterLock)
#define MASTER_UNLOCK	pthread_mutex_unlock(&masterLock)
#define MAIN_LOCK	pthread_mutex_lock(&mainLock)
#define MAIN_UNLOCK	pthread_mutex_unlock(&mainLock)

#endif /* TCL_THREADS */

/*
 *----------------------------------------------------------------------
 *
 * TclpThreadCreate --
270
271
272
273
274
275
276
277

278
279
280
281
282
283
284
270
271
272
273
274
275
276

277
278
279
280
281
282
283
284







-
+







void
TclFinalizeLock(void)
{
#ifdef TCL_THREADS
    /*
     * You do not need to destroy mutexes that were created with the
     * PTHREAD_MUTEX_INITIALIZER macro. These mutexes do not need any
     * destruction: masterLock, allocLock, and initLock.
     * destruction: mainLock, allocLock, and initLock.
     */

    pthread_mutex_unlock(&initLock);
#endif
}

/*
305
306
307
308
309
310
311
312

313
314
315
316
317
318
319
320
321
322
323
324
325

326
327
328
329
330
331

332
333
334

335
336
337
338
339
340
341
342

343
344
345
346
347
348
349
350
351

352
353
354
355
356
357

358
359
360

361
362
363
364
365
366
367
305
306
307
308
309
310
311

312
313
314
315
316
317
318
319
320
321
322
323
324

325
326
327
328
329
330

331
332
333

334
335
336
337
338
339
340
341

342
343
344
345
346
347
348
349
350

351
352
353
354
355
356

357
358
359

360
361
362
363
364
365
366
367







-
+












-
+





-
+


-
+







-
+








-
+





-
+


-
+







    pthread_mutex_unlock(&initLock);
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * TclpMasterLock
 * TclpMainLock
 *
 *	This procedure is used to grab a lock that serializes creation and
 *	finalization of serialization objects. This interface is only needed
 *	in finalization; it is hidden during creation of the objects.
 *
 *	This lock must be different than the initLock because the initLock is
 *	held during creation of synchronization objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Acquire the master mutex.
 *	Acquire the main mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMasterLock(void)
TclpMainLock(void)
{
#ifdef TCL_THREADS
    pthread_mutex_lock(&masterLock);
    pthread_mutex_lock(&mainLock);
#endif
}


/*
 *----------------------------------------------------------------------
 *
 * TclpMasterUnlock
 * TclpMainUnlock
 *
 *	This procedure is used to release a lock that serializes creation and
 *	finalization of synchronization objects.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Release the master mutex.
 *	Release the main mutex.
 *
 *----------------------------------------------------------------------
 */

void
TclpMasterUnlock(void)
TclpMainUnlock(void)
{
#ifdef TCL_THREADS
    pthread_mutex_unlock(&masterLock);
    pthread_mutex_unlock(&mainLock);
#endif
}

/*
 *----------------------------------------------------------------------
 *
 * Tcl_GetAllocMutex
417
418
419
420
421
422
423
424

425
426
427

428
429
430
431
432
433
434
435

436
437
438
439
440
441
442
417
418
419
420
421
422
423

424
425
426

427
428
429
430
431
432
433
434

435
436
437
438
439
440
441
442







-
+


-
+







-
+







void
Tcl_MutexLock(
    Tcl_Mutex *mutexPtr)	/* Really (pthread_mutex_t **) */
{
    pthread_mutex_t *pmutexPtr;

    if (*mutexPtr == NULL) {
	MASTER_LOCK;
	MAIN_LOCK;
	if (*mutexPtr == NULL) {
	    /*
	     * Double inside master lock check to avoid a race condition.
	     * Double inside main lock check to avoid a race condition.
	     */

	    pmutexPtr = ckalloc(sizeof(pthread_mutex_t));
	    pthread_mutex_init(pmutexPtr, NULL);
	    *mutexPtr = (Tcl_Mutex)pmutexPtr;
	    TclRememberMutex(mutexPtr);
	}
	MASTER_UNLOCK;
	MAIN_UNLOCK;
    }
    pmutexPtr = *((pthread_mutex_t **)mutexPtr);
    pthread_mutex_lock(pmutexPtr);
}

/*
 *----------------------------------------------------------------------
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
540
541
542
543
544
545

546
547
548
549
550
551
552
525
526
527
528
529
530
531

532
533
534
535
536
537
538
539
540
541
542
543
544

545
546
547
548
549
550
551
552







-
+












-
+







    const Tcl_Time *timePtr) /* Timeout on waiting period */
{
    pthread_cond_t *pcondPtr;
    pthread_mutex_t *pmutexPtr;
    struct timespec ptime;

    if (*condPtr == NULL) {
	MASTER_LOCK;
	MAIN_LOCK;

	/*
	 * Double check inside mutex to avoid race, then initialize condition
	 * variable if necessary.
	 */

	if (*condPtr == NULL) {
	    pcondPtr = ckalloc(sizeof(pthread_cond_t));
	    pthread_cond_init(pcondPtr, NULL);
	    *condPtr = (Tcl_Condition) pcondPtr;
	    TclRememberCondition(condPtr);
	}
	MASTER_UNLOCK;
	MAIN_UNLOCK;
    }
    pmutexPtr = *((pthread_mutex_t **)mutexPtr);
    pcondPtr = *((pthread_cond_t **)condPtr);
    if (timePtr == NULL) {
	pthread_cond_wait(pcondPtr, pmutexPtr);
    } else {
	Tcl_Time now;
796
797
798
799
800
801
802
803

804
805
806
807
808
809
810
796
797
798
799
800
801
802

803
804
805
806
807
808
809
810







-
+







TclpThreadSetMasterTSD(
    void *tsdKeyPtr,
    void *ptr)
{
    pthread_key_t *ptkeyPtr = tsdKeyPtr;

    if (pthread_setspecific(*ptkeyPtr, ptr)) {
	Tcl_Panic("unable to set master TSD value");
	Tcl_Panic("unable to set main TSD value");
    }
}

void *
TclpThreadGetMasterTSD(
    void *tsdKeyPtr)
{