From jhamby@anobject.com  Mon Aug 16 00:21:29 2004
Return-Path: <jhamby@anobject.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 99F0C16A4CF
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Aug 2004 00:21:29 +0000 (GMT)
Received: from bronco.gopix.net (gopix.net [38.118.153.46])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 4E6E343D45
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Aug 2004 00:21:29 +0000 (GMT)
	(envelope-from jhamby@anobject.com)
Received: from localhost.my.domain (ca-stmnca-cuda2-blade8b-87.stmnca.adelphia.net [68.65.226.87])
	by bronco.gopix.net (8.12.11/8.12.11) with ESMTP id i7G0LRYB008778
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK)
	for <FreeBSD-gnats-submit@freebsd.org>; Sun, 15 Aug 2004 17:21:28 -0700
Received: (from jhamby@localhost)
	by localhost.my.domain (8.13.1/8.13.1/Submit) id i7G0LRYC003133;
	Sun, 15 Aug 2004 17:21:27 -0700 (PDT)
	(envelope-from jhamby)
Message-Id: <200408160021.i7G0LRYC003133@localhost.my.domain>
Date: Sun, 15 Aug 2004 17:21:27 -0700 (PDT)
From: Jake Hamby <jhamby@anobject.com>
Reply-To: Jake Hamby <jhamby@anobject.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: error in new __thread local storage support
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         70502
>Category:       kern
>Synopsis:       error in new __thread local storage support
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 16 00:30:24 GMT 2004
>Closed-Date:    Wed Aug 18 08:20:10 GMT 2004
>Last-Modified:  Wed Aug 18 08:20:10 GMT 2004
>Originator:     Jake Hamby
>Release:        FreeBSD 5.2-CURRENT i386
>Organization:
Software Factory x
>Environment:
System: FreeBSD fuji 5.2-CURRENT FreeBSD 5.2-CURRENT #2: Sat Aug 14 19:00:56 PDT 2004 root@fuji:/usr/home/work/sys/FUJI i386
>Description:

The new __thread based TLS code doesn't seem to work beyond a particular size.

>How-To-Repeat:

See the attached test program.  On my machine, it works for NUM_KEYS=6, but
with NUM_KEYS=10 I see data corruption in the TLS area, and with NUM_KEYS=64,
it crashes, so the TLS region is definitely overwriting something important.

$ gcc -O2 -o tls_nptl_test tls_nptl_test.c -lpthread
$ ./tls_nptl_test

Fatal error '_pq_remove: Not in priority queue' at line 144 in file /usr/src/lib/libpthread/thread/thr_priority_queue.c (errno = 0)
Segmentation fault (core dumped)

>Fix:

I don't know the code well enough to suggest a fix.

--- tls_nptl_test.c begins here ---

/*
 * Test of pthreads / TLS storage.
 */

#define _REENTRANT
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#include <dlfcn.h>

#define NUM_THREADS 64
#define NUM_KEYS 64
static __thread int TLS_keys[NUM_KEYS];
static pthread_t threads[NUM_THREADS];

static void*
start_routine(void *arg)
{
	int thread_num = (int)arg;
	int i, err;
	for(i=0; i<500; i++)
	{
		if (i==17)
		{
		/*	printf("Thread %d: Number 17:  break for debugger\n",
				thread_num); */
		}
		int j;
		for(j=0; j<NUM_KEYS; j++)
		{
			/* verify old key value (except first time through loop) */
			int val = TLS_keys[j];
			if (val != i && (i != 0))
			{
				printf("Thread %d: expected %d for key %d, found %d\n",
					thread_num, i, j, val);
				return (void*)1;
			}
			/* set new key value */
			TLS_keys[j] = i+1;
		}
		/* sleep from 0.1 to 1 sec. */
		struct timespec slptime = {0, 100000000 + random()%900000000};
		/*printf("Thread %d: foo sleep %d\n", thread_num, slptime.tv_nsec);*/
		nanosleep(&slptime, 0);
	}
	return 0;
}

int
main(int argc, char** argv)
{
	int i;
	const char* dlerr = dlerror();
	if (dlerr)
	{
		printf("dlerror: %s\n", dlerr);
		return 1;
	}
	for(i=0; i<NUM_THREADS; i++)
	{
		int err = pthread_create(&threads[i], NULL, start_routine,
					 (void*)i);
		if (err)
		{
			printf("pthread_create error %d for thread %d\n", err, i);
			return 1;
		}
	}
	for(i=0; i<NUM_THREADS; i++)
	{
		void* retval;
		int err = pthread_join(threads[i], &retval);
		if (err)
		{
			printf("pthread_join error %d for thread %d\n", err, i);
			return 1;
		}
	}
	return 0;
}
--- tls_nptl_test.c ends here ---


>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->closed 
State-Changed-By: dfr 
State-Changed-When: Wed Aug 18 08:19:25 GMT 2004 
State-Changed-Why:  
Submitter was using a pre-TLS version of libpthread. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=70502 
>Unformatted:
