1130803Smarcel/*
2130803Smarcel * Copyright (c) 2002, Intel Corporation. All rights reserved.
3130803Smarcel * Created by:  bing.wei.liu REMOVE-THIS AT intel DOT com
4130803Smarcel * This file is licensed under the GPL license.  For the full content
5130803Smarcel * of this license, see the COPYING file at the top level of this
6130803Smarcel * source tree.
7130803Smarcel
8130803Smarcel * Test that pthread_key_create()
9130803Smarcel *
10130803Smarcel *  shall create a thread-specific data key visible to all threaads in the process.  Key values
11130803Smarcel *  provided by pthread_key_create() are opaque objects used to locate thread-specific data.
12130803Smarcel *  Although the same key value may be used by different threads, the values bound to the key
13130803Smarcel *  by pthread_setspecific() are maintained on a per-thread basis and persist for the life of
14130803Smarcel *  the calling thread.
15130803Smarcel *
16130803Smarcel * Steps:
17130803Smarcel * 1. Define and create a key
18130803Smarcel * 2. Verify that you can create many threads with the same key value
19130803Smarcel *
20130803Smarcel */
21130803Smarcel
22130803Smarcel#include <pthread.h>
23130803Smarcel#include <stdio.h>
24130803Smarcel#include <stdlib.h>
25130803Smarcel#include <unistd.h>
26130803Smarcel#include "posixtest.h"
27130803Smarcel
28130803Smarcel#define NUM_OF_THREADS 10
29130803Smarcel#define KEY_VALUE 1000
30130803Smarcelpthread_key_t keys[NUM_OF_THREADS];
31130803Smarcelint i;
32130803Smarcel
33130803Smarcel/* Thread function that sets the key to KEY_VALUE */
34130803Smarcelvoid *a_thread_func()
35130803Smarcel{
36130803Smarcel	/* Set the key to KEY_VALUE */
37130803Smarcel	if(pthread_setspecific(keys[i], (void *)(KEY_VALUE)) != 0)
38130803Smarcel	{
39130803Smarcel		printf("Error: pthread_setspecific() failed\n");
40130803Smarcel		pthread_exit((void*)PTS_FAIL);
41130803Smarcel	}
42130803Smarcel
43130803Smarcel	pthread_exit(0);
44130803Smarcel	return NULL;
45130803Smarcel}
46130803Smarcel
47130803Smarcelint main()
48130803Smarcel{
49130803Smarcel	pthread_t new_th;
50130803Smarcel	void *value_ptr;
51130803Smarcel
52130803Smarcel	/* Create a key */
53130803Smarcel	for(i = 0;i<NUM_OF_THREADS;i++)
54130803Smarcel	{
55130803Smarcel		if(pthread_key_create(&keys[i], NULL) != 0)
56130803Smarcel		{
57130803Smarcel			printf("Error: pthread_key_create() failed\n");
58130803Smarcel			return PTS_UNRESOLVED;
59130803Smarcel		}
60130803Smarcel	}
61130803Smarcel
62130803Smarcel	/* Create NUM_OF_THREADS threads and in the thread_func, it will
63130803Smarcel	 * use pthread_setspecific with the same KEY_VALUE */
64130803Smarcel	for(i = 0;i<NUM_OF_THREADS;i++)
65130803Smarcel	{
66130803Smarcel		/* Create a thread */
67130803Smarcel		if(pthread_create(&new_th, NULL, a_thread_func, NULL) != 0)
68130803Smarcel		{
69130803Smarcel			perror("Error creating thread\n");
70130803Smarcel			return PTS_UNRESOLVED;
71130803Smarcel		}
72130803Smarcel
73130803Smarcel		/* Wait for thread to end */
74130803Smarcel		if(pthread_join(new_th, &value_ptr) != 0)
75130803Smarcel		{
76130803Smarcel			perror("Error in pthread_join\n");
77130803Smarcel			return PTS_UNRESOLVED;
78130803Smarcel		}
79130803Smarcel
80130803Smarcel		if(value_ptr == (void*) PTS_FAIL)
81130803Smarcel		{
82130803Smarcel			printf("Test FAILED: Could not use a certain key value to set for many keys\n");
83130803Smarcel			return PTS_FAIL;
84130803Smarcel		}
85130803Smarcel	}
86130803Smarcel
87130803Smarcel	printf("Test PASSED\n");
88130803Smarcel	return PTS_PASS;
89130803Smarcel}
90130803Smarcel