コード例 #1
0
ファイル: pthread_cond_init.2-2.c プロジェクト: 8l/rose
int do_cs_test(void)
{
	int ret;
	int result=0;
	
	pthread_mutex_t mtxN, mtxI;
	pthread_cond_t cndN;
	
	pthread_condattr_t ca;
	
	pthread_t thN, thD;
	
	struct timespec ts, timeout;
	
	clockid_t  cid;

	/* The 3 next data aim to minimize the impact on the
	 *  system time, when the monotonic clock is supported
	 */
	long monotonic_clk;
	struct timespec diff;
	char sens=0;
	
	/* We are going to initialize the cond vars and the mutexes */
	dtN.pmtx = &mtxN;
	dtI.pmtx = &mtxI;
	dtN.pcnd = &cndN;
	dtI.pcnd = &cndI;
	ret = pthread_mutex_init(&mtxI, NULL);
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to initialize a default mutex");  }
	ret = pthread_mutex_init(&mtxN, NULL);
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to initialize a default mutex");  }
	ret = pthread_condattr_init(&ca);
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to initialize cond attribute object");  }

#if 0	/*  Test if the testcase is valid: change the clock from the "NULL" cond var */
	pthread_condattr_setclock(&ca, CLOCK_MONOTONIC);
	ret = pthread_cond_init(&cndN, &ca);
	pthread_condattr_setclock(&ca, CLOCK_REALTIME);
#else
	ret = pthread_cond_init(&cndN, NULL);
#endif
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to initialize the NULL attribute conditional variable.");  }
	
	dtI.ctrl = 0;
	dtN.ctrl = 0;
	dtI.rc   = 0;
	dtN.rc   = 0;
	
	#if VERBOSE > 1
	output("Data initialized successfully for CS test.\n");
	#endif
	
	monotonic_clk = sysconf(_SC_MONOTONIC_CLOCK);
	#if VERBOSE > 1
	output("Sysconf for monotonix clock: %li\n", monotonic_clk);
	#endif
	
	/* Get the default clock ID */
	ret = pthread_condattr_getclock(&ca, &cid);
	if (ret != 0)
	{  UNRESOLVED(ret, "Unable to get clockid from the default cond attribute object");  }
	
	/* Check whether we can set the system clock */
	
	/* Backup the current monotonic time if available */
	if (monotonic_clk != -1L)
	{
		ret = clock_gettime(CLOCK_MONOTONIC, &diff);
		if (ret != 0)
		{
			output("Clock_gettime(CLOCK_MONOTONIC) failed when the system claims to support this option\n");
			monotonic_clk = -1L;
		}
	}
	ret = clock_gettime(cid, &ts);
	if (ret != 0)
	{  UNRESOLVED(errno, "Unable to get clock time");  }
	
	
	ret = clock_settime(cid, &ts);
	if (ret != 0)
	{
		#if VERBOSE > 1
		output("clock_settime failed (%s)\n", strerror(errno));
		output("We cannot test if both cond uses the same clock then...\n");
		#endif
		UNTESTED("Was unable to set the default clock time. Need more privileges?");
	}
	else /* We can do the test */
	{
		#if VERBOSE > 1
		output("clock_settime succeeded\n");
		#endif
		
		if (monotonic_clk != -1L)
		{
			#if VERBOSE > 2
			output("Monotonic clock : %10i.%09li\n", diff.tv_sec, diff.tv_nsec);
			output("Default clock   : %10i.%09li\n", ts.tv_sec, ts.tv_nsec);
			#endif
			/* Save the decay between default clock and clock MONOTONIC */
			if (diff.tv_sec > ts.tv_sec)
			{
				sens = -1; /* monotonic was bigger than system */
				if (diff.tv_nsec < ts.tv_nsec)
				{
					diff.tv_nsec += 1000000000 - ts.tv_nsec;
					diff.tv_sec  -= 1 + ts.tv_sec;
				}
				else
				{
					diff.tv_nsec -= ts.tv_nsec;
					diff.tv_sec -= ts.tv_sec;
				}
			}
			else
			{
				if (diff.tv_sec == ts.tv_sec)
				{
					diff.tv_sec = 0;
					if (diff.tv_nsec > ts.tv_nsec)
					{
						sens = -1;
						diff.tv_nsec -= ts.tv_nsec;
					}
					else
					{
						sens = 1; /* Default clock was bigger than monotonic */
						diff.tv_nsec = ts.tv_nsec - diff.tv_nsec;
					}
				}
				else /* ts.tv_sec > diff.tv_sec */
				{
					sens = 1;
					if (ts.tv_nsec < diff.tv_nsec)
					{
						diff.tv_nsec = 1000000000 + ts.tv_nsec - diff.tv_nsec;
						diff.tv_sec = ts.tv_sec - (1 + diff.tv_sec);
					}
					else
					{
						diff.tv_nsec = ts.tv_nsec - diff.tv_nsec;
						diff.tv_sec = ts.tv_sec - diff.tv_sec;
					}
				}
			}
						
			#if VERBOSE > 2
			output("Computed diff   : %10i.%09li\n", diff.tv_sec, diff.tv_nsec);
			output("With monotonic %s than default\n", sens>0?"smaller":"bigger");
			#endif
		}
		
		/* Prepare the timeout parameters */
		timeout.tv_nsec = 0;
		timeout.tv_sec = ts.tv_sec + 260000; /* About 3 days later */
		dtN.timeout = &timeout;
		dtI.timeout = &timeout;
		
		/* create the threads */
		ret = pthread_create(&thD, NULL, test_timeout, &dtI);
		if (ret != 0)
		{  UNRESOLVED(ret, "Unable to create a thread");  }
		ret = pthread_create(&thN, NULL, test_timeout, &dtN);
		if (ret != 0)
		{  UNRESOLVED(ret, "Unable to create a thread");  }
		
		/* Lock the two mutex and make sure the threads are in wait */
		ret = pthread_mutex_lock(&mtxN);
		if (ret != 0)  {  UNRESOLVED(ret, "Unable to lock a mutex");  }
		while ((dtN.ctrl & FLAG_INWAIT) == 0)
		{
			ret = pthread_mutex_unlock(&mtxN);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
			sched_yield();
			ret = pthread_mutex_lock(&mtxN);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to lock a mutex");  }
		}
		ret = pthread_mutex_lock(&mtxI);
		if (ret != 0)  {  UNRESOLVED(ret, "Unable to lock a mutex");  }
		while ((dtI.ctrl & FLAG_INWAIT) == 0)
		{
			ret = pthread_mutex_unlock(&mtxI);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
			sched_yield();
			ret = pthread_mutex_lock(&mtxI);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to lock a mutex");  }
		}
		
		/* Now both threads are in the timed wait */
		#if VERBOSE > 1
		output("Two threads are created and waiting.\n");
		output("About to change the default clock value.\n");
		#endif
		
		/* We re-read the default clock time, to introduce minimal error on the clock */
		ret = clock_gettime(cid, &ts);
		if (ret != 0)  {  UNRESOLVED(errno, "Unable to get clock time");  }
		
		ts.tv_sec += 604800;  /* Exactly 1 week forth */
		
		/* We set the clock to a date after the timeout parameter */
		ret = clock_settime(cid, &ts);
		if (ret != 0)  {  UNRESOLVED(errno, "Unable to set clock time (again)");  }
		
		/* unlock the two mutex */
		ret = pthread_mutex_unlock(&mtxI);
		if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
		ret = pthread_mutex_unlock(&mtxN);
		if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
		
		/* Let the others threads run */
		sched_yield();
		
		#if VERBOSE > 1
		output("Checking that both threads have timedout...\n");
		#endif
		
		/* Relock the mutexs */
		ret = pthread_mutex_lock(&mtxN);
		if (ret != 0)  {  UNRESOLVED(ret, "Unable to lock a mutex");  }
		ret = pthread_mutex_lock(&mtxI);
		if (ret != 0)  {  UNRESOLVED(ret, "Unable to lock a mutex");  }
		
		/* Check whether the thread has timedout */
		if (dtI.rc == 0)
		{
			#if VERBOSE > 0
			output("The thread was not woken when the clock was changed so as the timeout expired\n");
			output("Going to simulate this POSIX behavior...\n");
			#endif
			ret = pthread_cond_signal(&cndN);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to signal the Null attribute condition");  }
			ret = pthread_cond_signal(&cndI);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to signal the Default attribute condition");  }
			
			/* The threads will now report a spurious wake up ... */
			
			/* We give the threads another chance to timeout */
			/* unlock the two mutex */
			ret = pthread_mutex_unlock(&mtxI);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
			ret = pthread_mutex_unlock(&mtxN);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
			
			/* Let the others threads run */
			sched_yield();
			
			#if VERBOSE > 1
			output("Rechecking that both threads have timedout...\n");
			#endif
			
			/* Relock the mutexs */
			ret = pthread_mutex_lock(&mtxN);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to lock a mutex");  }
			ret = pthread_mutex_lock(&mtxI);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to lock a mutex");  }
		}
			
		
		/* Process the Null condvar */
		if ((dtN.ctrl & FLAG_TIMEDOUT) != 0)
		{
			#if VERBOSE > 1
			output("Null attribute cond var timed out\n");
			#endif
			/* Join the thread */
			ret = pthread_join(thN, NULL);
			if (ret != 0)  {  UNRESOLVED(ret, "Join thread failed");  }
			/* Unlock the mutex */
			ret = pthread_mutex_unlock(&mtxN);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
		}
		else
		{
			#if VERBOSE > 1
			output("Null attribute cond var did not time out\n");
			#endif
			/* Signal the condition */
			dtN.ctrl |= FLAG_CONDWAKE;
			ret = pthread_cond_signal(&cndN);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to signal the Null attribute condition");  }
			/* Unlock the mutex and join the thread */
			ret = pthread_mutex_unlock(&mtxN);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
			/* Join the thread */
			ret = pthread_join(thN, NULL);
			if (ret != 0)  {  UNRESOLVED(ret, "Join thread failed");  }
		}
		
		/* Process the Default condvar */
		if ((dtI.ctrl & FLAG_TIMEDOUT) != 0)
		{
			#if VERBOSE > 1
			output("Default attribute cond var timed out\n");
			#endif
			/* Join the thread */
			ret = pthread_join(thD, NULL);
			if (ret != 0)  {  UNRESOLVED(ret, "Join thread failed");  }
			/* Unlock the mutex */
			ret = pthread_mutex_unlock(&mtxI);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
		}
		else
		{
			#if VERBOSE > 1
			output("Default attribute cond var did not time out\n");
			#endif
			/* Signal the condition */
			dtI.ctrl |= FLAG_CONDWAKE;
			ret = pthread_cond_signal(&cndI);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to signal the Default attribute condition");  }
			/* Unlock the mutex and join the thread */
			ret = pthread_mutex_unlock(&mtxI);
			if (ret != 0)  {  UNRESOLVED(ret, "Unable to unlock a mutex");  }
			/* Join the thread */
			ret = pthread_join(thD, NULL);
			if (ret != 0)  {  UNRESOLVED(ret, "Join thread failed");  }
		}
		
		/* Set the system time back to its value */
		if (monotonic_clk == -1L) /* Monotonic is not supported */
		{
			ret = clock_gettime(cid, &ts);
			if (ret != 0)  {  UNRESOLVED(errno, "Unable to get clock time");  }
			
			ts.tv_sec -= 604800;  /* Exactly 1 week back */ 
			
			/* We set the clock to a date after the timeout parameter */
			ret = clock_settime(cid, &ts);
			if (ret != 0)  {  UNRESOLVED(errno, "Unable to set clock time (3rd time)");  }
			#if VERBOSE > 1
			output("Default clock was set back\n");
			#endif
		}
		else
		{
			/* Read the monotonic time */
			ret = clock_gettime(CLOCK_MONOTONIC, &ts);
			if (ret != 0)  {  UNRESOLVED(errno, "Unable to get monotonic clock time");  }
			
			/* Apply the difference back */
			if (sens > 0) /* monotonic was smaller than system => we must add the diff value */
			{
				ts.tv_sec += diff.tv_sec;
				ts.tv_nsec += diff.tv_nsec;
				if (ts.tv_nsec >= 1000000000)
				{
					ts.tv_nsec -= 1000000000;
					ts.tv_sec += 1;
				}
			}
			else /* monotonic was bigger than system => we must remove the diff value */
			{
				ts.tv_sec -= diff.tv_sec;
				if (ts.tv_nsec < diff.tv_nsec)
				{
					ts.tv_sec -= 1;
					ts.tv_nsec += 1000000000 - diff.tv_nsec;
				}
				else
				{
					ts.tv_nsec -= diff.tv_nsec;
				}
			}
			
			/* We set the clock to a date after the timeout parameter */
			ret = clock_settime(cid, &ts);
			if (ret != 0)  {  UNRESOLVED(errno, "Unable to set clock time (3rd time)");  }
			
			#if VERBOSE > 1
			output("Default clock was set back using monotonic clock as a reference\n");
			#endif
		}
		
		/* Compare the two cond vars */
		#if VERBOSE > 2
		output("Default attribute cond var timedwait return value: %d\n", dtI.rc);
		output("Default attribute cond var exited with a timeout : %s\n", (dtI.ctrl & FLAG_TIMEDOUT)?"yes":"no");
		output("Default attribute cond var had to be signaled    : %s\n", (dtI.ctrl & FLAG_CONDWAKE)?"yes":"no");
		output("Default attribute cond var exited as signaled    : %s\n", (dtI.ctrl & FLAG_AWAKEN)?"yes":"no");
		output("Default attribute cond var spurious wakeups      : %d\n", (dtI.ctrl & MASK_COUNTER) - 1);
		output(" Null   attribute cond var timedwait return value: %d\n", dtN.rc);
		output(" Null   attribute cond var exited with a timeout : %s\n", (dtN.ctrl & FLAG_TIMEDOUT)?"yes":"no");
		output(" Null   attribute cond var had to be signaled    : %s\n", (dtN.ctrl & FLAG_CONDWAKE)?"yes":"no");
		output(" Null   attribute cond var exited as signaled    : %s\n", (dtN.ctrl & FLAG_AWAKEN)?"yes":"no");
		output(" Null   attribute cond var spurious wakeups      : %d\n", (dtN.ctrl & MASK_COUNTER) - 1);
		#endif
		if ((dtN.ctrl == dtI.ctrl) && (dtN.rc == dtI.rc))
		{
			result = 0;
			#if VERBOSE > 1
			output("The two cond vars behaved exactly in the same maneer\n");
			#endif
		}
		else
		{
			if ((dtN.ctrl & FLAG_TIMEDOUT) != (dtI.ctrl & FLAG_TIMEDOUT))
			{
				result += 1; /* The test has failed */
			}
			else
			{
				if (dtN.rc != dtI.rc)
				{
					output("Error codes were different: N:%d D:%d\n",dtN.rc, dtI.rc);
					UNRESOLVED(dtN.rc>dtI.rc?dtN.rc:dtI.rc, "Different error codes?");
				}
				if ((dtN.ctrl & FLAG_AWAKEN) == (dtI.ctrl & FLAG_AWAKEN))
				{
					/* The number of spurious wakeups is different */
					output("Different spurious wakeups: N:%d D:%d\n", 
						(dtN.ctrl & MASK_COUNTER) - 1, 
						(dtI.ctrl & MASK_COUNTER) - 1);
					
					result = 0; /* We don't consider this as a fail case */
				}
			}
		}
	}
	
	/* We can cleanup things now */
	ret = pthread_cond_destroy(&cndN);
	if (ret != 0)
	{  UNRESOLVED(ret, "Cond destroy failed");  }
	ret = pthread_condattr_destroy(&ca);
	if (ret != 0)
	{  UNRESOLVED(ret, "Cond attr destroy failed");  }
	ret = pthread_mutex_destroy(&mtxN);
	if (ret != 0)
	{  UNRESOLVED(ret, "Mutex destroy failed");  }
	ret = pthread_mutex_destroy(&mtxI);
	if (ret != 0)
	{  UNRESOLVED(ret, "Mutex destroy failed");  }
	
	return result;
}
コード例 #2
0
ファイル: 1-2.c プロジェクト: Nan619/ltp-ddt
int main(int argc, char *argv[])
{
	int ret;

	pthread_mutexattr_t ma;
	pthread_condattr_t ca;

	int scenar;
	long pshared, monotonic, cs, mf;

	pid_t p_child[NTHREADS];
	pthread_t t_child[NTHREADS];
	int ch;
	pid_t pid;
	int status;

	pthread_t t_timer;

	testdata_t alternativ;

	output_init();

	/* check the system abilities */
	pshared = sysconf(_SC_THREAD_PROCESS_SHARED);
	cs = sysconf(_SC_CLOCK_SELECTION);
	monotonic = sysconf(_SC_MONOTONIC_CLOCK);
	mf = sysconf(_SC_MAPPED_FILES);

#if VERBOSE > 0
	output("Test starting\n");
	output("System abilities:\n");
	output(" TPS : %li\n", pshared);
	output(" CS  : %li\n", cs);
	output(" MON : %li\n", monotonic);
	output(" MF  : %li\n", mf);
	if ((mf < 0) || (pshared < 0))
		output("Process-shared attributes won't be tested\n");
	if ((cs < 0) || (monotonic < 0))
		output("Alternative clock won't be tested\n");
#endif

	/* We are not interested in testing the clock if we have no other clock available.. */
	if (monotonic < 0)
		cs = -1;

#ifndef USE_ALTCLK
	if (cs > 0)
		output
		    ("Implementation supports the MONOTONIC CLOCK but option is disabled in test.\n");
#endif

/**********
 * Allocate space for the testdata structure
 */
	if (mf < 0) {
		/* Cannot mmap a file, we use an alternative method */
		td = &alternativ;
		pshared = -1;	/* We won't do this testing anyway */
#if VERBOSE > 0
		output("Testdata allocated in the process memory.\n");
#endif
	} else {
		/* We will place the test data in a mmaped file */
		char filename[] = "/tmp/cond_wait_stress-XXXXXX";
		size_t sz, ps;
		void *mmaped;
		int fd;
		char *tmp;

		/* We now create the temp files */
		fd = mkstemp(filename);
		if (fd == -1) {
			UNRESOLVED(errno,
				   "Temporary file could not be created");
		}

		/* and make sure the file will be deleted when closed */
		unlink(filename);

#if VERBOSE > 1
		output("Temp file created (%s).\n", filename);
#endif

		ps = (size_t) sysconf(_SC_PAGESIZE);
		sz = ((sizeof(testdata_t) / ps) + 1) * ps;	/* # pages needed to store the testdata */

		tmp = calloc(1, sz);
		if (tmp == NULL) {
			UNRESOLVED(errno, "Memory allocation failed");
		}

		/* Write the data to the file.  */
		if (write(fd, tmp, sz) != (ssize_t) sz) {
			UNRESOLVED(sz, "Writting to the file failed");
		}

		free(tmp);

		/* Now we can map the file in memory */
		mmaped =
		    mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
		if (mmaped == MAP_FAILED) {
			UNRESOLVED(errno, "mmap failed");
		}

		td = (testdata_t *) mmaped;

		/* Our datatest structure is now in shared memory */
#if VERBOSE > 1
		output("Testdata allocated in shared memory (%ib).\n",
		       sizeof(testdata_t));
#endif
	}

	/* Do the test for each test scenario */
	for (scenar = 0; scenar < NSCENAR; scenar++) {
		/* set / reset everything */
		td->fork = 0;
		ret = pthread_mutexattr_init(&ma);
		if (ret != 0) {
			UNRESOLVED(ret,
				   "[parent] Unable to initialize the mutex attribute object");
		}
		ret = pthread_condattr_init(&ca);
		if (ret != 0) {
			UNRESOLVED(ret,
				   "[parent] Unable to initialize the cond attribute object");
		}
#ifndef WITHOUT_XOPEN
		/* Set the mutex type */
		ret = pthread_mutexattr_settype(&ma, scenarii[scenar].m_type);
		if (ret != 0) {
			UNRESOLVED(ret, "[parent] Unable to set mutex type");
		}
#endif

		/* Set the pshared attributes, if supported */
		if ((pshared > 0) && (scenarii[scenar].mc_pshared != 0)) {
			ret =
			    pthread_mutexattr_setpshared(&ma,
							 PTHREAD_PROCESS_SHARED);
			if (ret != 0) {
				UNRESOLVED(ret,
					   "[parent] Unable to set the mutex process-shared");
			}
			ret =
			    pthread_condattr_setpshared(&ca,
							PTHREAD_PROCESS_SHARED);
			if (ret != 0) {
				UNRESOLVED(ret,
					   "[parent] Unable to set the cond var process-shared");
			}
		}

		/* Set the alternative clock, if supported */
#ifdef USE_ALTCLK
		if ((cs > 0) && (scenarii[scenar].c_clock != 0)) {
			ret = pthread_condattr_setclock(&ca, CLOCK_MONOTONIC);
			if (ret != 0) {
				UNRESOLVED(ret,
					   "[parent] Unable to set the monotonic clock for the cond");
			}
		}
		ret = pthread_condattr_getclock(&ca, &td->cid);
		if (ret != 0) {
			UNRESOLVED(ret, "Unable to get clock from cond attr");
		}
#else
		td->cid = CLOCK_REALTIME;
#endif

		/* Tell whether the test will be across processes */
		if ((pshared > 0) && (scenarii[scenar].fork != 0)) {
			td->fork = 1;
		}

		/* initialize the condvar */
		ret = pthread_cond_init(&td->cnd, &ca);
		if (ret != 0) {
			UNRESOLVED(ret, "Cond init failed");
		}

		/* initialize the mutex */
		ret = pthread_mutex_init(&td->mtx, &ma);
		if (ret != 0) {
			UNRESOLVED(ret, "Mutex init failed");
		}

		/* Destroy the attributes */
		ret = pthread_condattr_destroy(&ca);
		if (ret != 0) {
			UNRESOLVED(ret,
				   "Failed to destroy the cond var attribute object");
		}

		ret = pthread_mutexattr_destroy(&ma);
		if (ret != 0) {
			UNRESOLVED(ret,
				   "Failed to destroy the mutex attribute object");
		}
#if VERBOSE > 2
		output("[parent] Starting test %s\n", scenarii[scenar].descr);
#endif

		td->count = 0;
		/* Create all the children */
		for (ch = 0; ch < NTHREADS; ch++) {
			if (td->fork == 0) {
				ret =
				    pthread_create(&t_child[ch], NULL, child,
						   NULL);
				if (ret != 0) {
					UNRESOLVED(ret,
						   "Failed to create a child thread");
				}
			} else {
				p_child[ch] = fork();
				if (p_child[ch] == -1) {
					ret = errno;
					for (--ch; ch >= 0; ch--)
						kill(p_child[ch], SIGKILL);
					UNRESOLVED(ret,
						   "Failed to create a child process");
				}

				if (p_child[ch] == 0) {	/* We are the child */
					child(NULL);
					exit(0);
				}
			}
		}
#if VERBOSE > 4
		output("[parent] All children are running\n");
#endif

		/* Make sure all children are waiting */
		ret = pthread_mutex_lock(&td->mtx);
		if (ret != 0) {
			UNRESOLVED_KILLALL(ret, "Failed to lock mutex",
					   p_child);
		}
		ch = td->count;
		while (ch < NTHREADS) {
			ret = pthread_mutex_unlock(&td->mtx);
			if (ret != 0) {
				UNRESOLVED_KILLALL(ret,
						   "Failed to unlock mutex",
						   p_child);
			}
			sched_yield();
			ret = pthread_mutex_lock(&td->mtx);
			if (ret != 0) {
				UNRESOLVED_KILLALL(ret, "Failed to lock mutex",
						   p_child);
			}
			ch = td->count;
		}

#if VERBOSE > 4
		output("[parent] All children are waiting\n");
#endif

		/* create the timeout thread */
		ret = pthread_create(&t_timer, NULL, timer, p_child);
		if (ret != 0) {
			UNRESOLVED_KILLALL(ret, "Unable to create timer thread",
					   p_child);
		}

		/* Wakeup the children */
		td->predicate = 1;
		ret = pthread_cond_signal(&td->cnd);
		if (ret != 0) {
			UNRESOLVED_KILLALL(ret,
					   "Failed to signal the condition.",
					   p_child);
		}
#if VERBOSE > 4
		output("[parent] Condition was signaled\n");
#endif

		ret = pthread_mutex_unlock(&td->mtx);
		if (ret != 0) {
			UNRESOLVED_KILLALL(ret, "Failed to unlock mutex",
					   p_child);
		}
#if VERBOSE > 4
		output("[parent] Joining the children\n");
#endif

		/* join the children */
		for (ch = (NTHREADS - 1); ch >= 0; ch--) {
			if (td->fork == 0) {
				ret = pthread_join(t_child[ch], NULL);
				if (ret != 0) {
					UNRESOLVED(ret,
						   "Failed to join a child thread");
				}
			} else {
				pid = waitpid(p_child[ch], &status, 0);
				if (pid != p_child[ch]) {
					ret = errno;
					output
					    ("Waitpid failed (expected: %i, got: %i)\n",
					     p_child[ch], pid);
					for (; ch >= 0; ch--) {
						kill(p_child[ch], SIGKILL);
					}
					UNRESOLVED(ret, "Waitpid failed");
				}
				if (WIFEXITED(status)) {
					/* the child should return only failed or unresolved or passed */
					if (ret != PTS_FAIL)
						ret |= WEXITSTATUS(status);
				}
			}
		}
		if (ret != 0) {
			output_fini();
			exit(ret);
		}
#if VERBOSE > 4
		output("[parent] All children terminated\n");
#endif

		/* cancel the timeout thread */
		ret = pthread_cancel(t_timer);
		if (ret != 0) {
			/* Strange error here... the thread cannot be terminated (app would be killed) */
			UNRESOLVED(ret, "Failed to cancel the timeout handler");
		}

		/* join the timeout thread */
		ret = pthread_join(t_timer, NULL);
		if (ret != 0) {
			UNRESOLVED(ret, "Failed to join the timeout handler");
		}

		/* Destroy the datas */
		ret = pthread_cond_destroy(&td->cnd);
		if (ret != 0) {
			UNRESOLVED(ret, "Failed to destroy the condvar");
		}

		ret = pthread_mutex_destroy(&td->mtx);
		if (ret != 0) {
			UNRESOLVED(ret, "Failed to destroy the mutex");
		}

	}

	/* exit */
	PASSED;
}
コード例 #3
0
ファイル: tst-cond11.c プロジェクト: riscv/riscv-glibc
static int
run_test (clockid_t cl)
{
  pthread_condattr_t condattr;
  pthread_cond_t cond;
  pthread_mutexattr_t mutattr;
  pthread_mutex_t mut;

  printf ("clock = %d\n", (int) cl);

  if (pthread_condattr_init (&condattr) != 0)
    {
      puts ("condattr_init failed");
      return 1;
    }

  if (pthread_condattr_setclock (&condattr, cl) != 0)
    {
      puts ("condattr_setclock failed");
      return 1;
    }

  clockid_t cl2;
  if (pthread_condattr_getclock (&condattr, &cl2) != 0)
    {
      puts ("condattr_getclock failed");
      return 1;
    }
  if (cl != cl2)
    {
      printf ("condattr_getclock returned wrong value: %d, expected %d\n",
	      (int) cl2, (int) cl);
      return 1;
    }

  if (pthread_cond_init (&cond, &condattr) != 0)
    {
      puts ("cond_init failed");
      return 1;
    }

  if (pthread_condattr_destroy (&condattr) != 0)
    {
      puts ("condattr_destroy failed");
      return 1;
    }

  if (pthread_mutexattr_init (&mutattr) != 0)
    {
      puts ("mutexattr_init failed");
      return 1;
    }

  if (pthread_mutexattr_settype (&mutattr, PTHREAD_MUTEX_ERRORCHECK) != 0)
    {
      puts ("mutexattr_settype failed");
      return 1;
    }

  if (pthread_mutex_init (&mut, &mutattr) != 0)
    {
      puts ("mutex_init failed");
      return 1;
    }

  if (pthread_mutexattr_destroy (&mutattr) != 0)
    {
      puts ("mutexattr_destroy failed");
      return 1;
    }

  if (pthread_mutex_lock (&mut) != 0)
    {
      puts ("mutex_lock failed");
      return 1;
    }

  if (pthread_mutex_lock (&mut) != EDEADLK)
    {
      puts ("2nd mutex_lock did not return EDEADLK");
      return 1;
    }

  struct timespec ts;
  if (clock_gettime (cl, &ts) != 0)
    {
      puts ("clock_gettime failed");
      return 1;
    }

  /* Wait one second.  */
  ++ts.tv_sec;

  int e = pthread_cond_timedwait (&cond, &mut, &ts);
  if (e == 0)
    {
      puts ("cond_timedwait succeeded");
      return 1;
    }
  else if (e != ETIMEDOUT)
    {
      puts ("cond_timedwait did not return ETIMEDOUT");
      return 1;
    }

  struct timespec ts2;
  if (clock_gettime (cl, &ts2) != 0)
    {
      puts ("second clock_gettime failed");
      return 1;
    }

  if (ts2.tv_sec < ts.tv_sec
      || (ts2.tv_sec == ts.tv_sec && ts2.tv_nsec < ts.tv_nsec))
    {
      puts ("timeout too short");
      return 1;
    }

  if (pthread_mutex_unlock (&mut) != 0)
    {
      puts ("mutex_unlock failed");
      return 1;
    }

  if (pthread_mutex_destroy (&mut) != 0)
    {
      puts ("mutex_destroy failed");
      return 1;
    }

  if (pthread_cond_destroy (&cond) != 0)
    {
      puts ("cond_destroy failed");
      return 1;
    }

  return 0;
}
コード例 #4
0
ファイル: 2-5.c プロジェクト: Nan619/ltp
int main(void)
{
    int ret, j;
    unsigned int i;
    pthread_mutexattr_t ma;
    pthread_condattr_t ca;
    pthread_t th[NTHREADS];
    int loc_started, loc_stopped;

    long altclk_ok, pshared_ok;

    struct {
        char altclk;	/* Want to use alternative clock */
        char pshared;	/* Want to use process-shared primitives */
        int type;	/* mutex type */
        char *descr;	/* Description of the case */

    } scenar[] = {
        {
            0, 0, PTHREAD_MUTEX_RECURSIVE, "Recursive mutex"
        }, {
            0, 0, PTHREAD_MUTEX_ERRORCHECK, "Errorcheck mutex"
        },
#ifdef USE_ALTCLK
        {
            1, 0, PTHREAD_MUTEX_RECURSIVE,
            "Recursive mutex + altclock cond"
        }, {
            1, 0, PTHREAD_MUTEX_ERRORCHECK,
            "Errorcheck mutex + altclock cond"
        }, {
            1, 1, PTHREAD_MUTEX_RECURSIVE,
            "Recursive pshared mutex + altclock cond"
        }, {
            1, 1, PTHREAD_MUTEX_ERRORCHECK,
            "Errorcheck pshared mutex + altclock cond"
        },
#endif
        {
            0, 1, PTHREAD_MUTEX_RECURSIVE, "Recursive pshared mutex"
        }, {
            0, 1, PTHREAD_MUTEX_ERRORCHECK,
            "Errorcheck pshared mutex"
        },
    };

    output_init();

    /* Initialize the constants */
    altclk_ok = sysconf(_SC_CLOCK_SELECTION);
    if (altclk_ok > 0)
        altclk_ok = sysconf(_SC_MONOTONIC_CLOCK);

#ifndef USE_ALTCLK
    if (altclk_ok > 0)
        output("Implementation supports the MONOTONIC CLOCK "
               "but option is disabled in test.\n");
#endif

    pshared_ok = sysconf(_SC_THREAD_PROCESS_SHARED);

#if VERBOSE > 0
    output("Test starting\n");
    output(" Process-shared primitive %s be tested\n",
           (pshared_ok > 0) ? "will" : "won't");
    output(" Alternative clock for cond %s be tested\n",
           (altclk_ok > 0) ? "will" : "won't");
#endif

    for (i = 0; i < (sizeof(scenar) / sizeof(scenar[0])); i++) {
#if VERBOSE > 1
        output("Starting test for %s\n", scenar[i].descr);
#endif

        /* Initialize the data structure */
        ret = pthread_mutexattr_init(&ma);
        if (ret != 0)
            UNRESOLVED(ret, "Mutex attribute object init failed");

        ret = pthread_mutexattr_settype(&ma, scenar[i].type);
        if (ret != 0)
            UNRESOLVED(ret, "Unable to set mutex type");

        if ((pshared_ok > 0) && (scenar[i].pshared != 0)) {
            ret =
                pthread_mutexattr_setpshared(&ma,
                                             PTHREAD_PROCESS_SHARED);
            if (ret != 0)
                UNRESOLVED(ret,
                           "Unable to set mutex process-shared");
        }

        ret = pthread_condattr_init(&ca);
        if (ret != 0)
            UNRESOLVED(ret, "Cond attribute object init failed");

        if ((pshared_ok > 0) && (scenar[i].pshared != 0)) {
            ret =
                pthread_condattr_setpshared(&ca,
                                            PTHREAD_PROCESS_SHARED);
            if (ret != 0)
                UNRESOLVED(ret,
                           "Unable to set cond process-shared");
        }
#ifdef USE_ALTCLK
        if ((altclk_ok > 0) && (scenar[i].altclk != 0)) {
            ret = pthread_condattr_setclock(&ca, CLOCK_MONOTONIC);
            if (ret != 0)
                UNRESOLVED(ret,
                           "Unable to set alternative (monotonic) clock for cond");
        }
#endif

        ret = pthread_mutex_init(&(data.mtx1), &ma);
        if (ret != 0)
            UNRESOLVED(ret, "Unable to init mutex 1");

        ret = pthread_mutex_init(&(data.mtx2), &ma);
        if (ret != 0)
            UNRESOLVED(ret, "Unable to init mutex 2");

        ret = pthread_cond_init(&(data.cnd), &ca);
        if (ret != 0)
            UNRESOLVED(ret, "Unable to initialize condvar");

        data.boolcnd = 0;

        ret = pthread_mutexattr_gettype(&ma, &(data.type));
        if (ret != 0)
            UNRESOLVED(ret, "Unable to get type from mutex attr");

#ifdef USE_ALTCLK
        ret = pthread_condattr_getclock(&ca, &(data.cid));
        if (ret != 0)
            UNRESOLVED(ret,
                       "Unable to get clock ID from cond attr");
#else
        data.cid = CLOCK_REALTIME;
#endif

        data.started = 0;
        data.stopped = 0;

        /* Start the threads */
#if VERBOSE > 1
        output("Initialization OK, starting threads\n");
#endif
        for (j = 0; j < NTHREADS; j++) {
            ret =
                pthread_create(&th[j], NULL, threaded,
                               (void *)(long)(j & 1));
            if (ret != 0)
                UNRESOLVED(ret, "Thread creation failed");
        }

        /* Wait for the threads to be started */
        do {
            ret = pthread_mutex_lock(&(data.mtx1));
            if (ret != 0)
                UNRESOLVED(ret, "Unable to lock m1 in parent");
            loc_started = data.started;
            ret = pthread_mutex_unlock(&(data.mtx1));
            if (ret != 0)
                UNRESOLVED(ret,
                           "Unable to unlock m1 in parent");
        } while (loc_started < NTHREADS);

        /* Broadcast the condition until all threads are terminated */
        data.boolcnd = 1;
        do {
            ret = pthread_cond_broadcast(&(data.cnd));
            if (ret != 0)
                UNRESOLVED(ret, "Unable to broadcast cnd");
            sched_yield();
            ret = pthread_mutex_lock(&(data.mtx2));
            if (ret != 0)
                UNRESOLVED(ret, "Unable to lock m2 in parent");
            loc_stopped = data.stopped;
            ret = pthread_mutex_unlock(&(data.mtx2));
            if (ret != 0)
                UNRESOLVED(ret,
                           "Unable to unlock m2 in parent");
        } while (loc_stopped < NTHREADS);

        /* Join the threads */
        for (j = 0; j < NTHREADS; j++) {
            ret = pthread_join(th[j], NULL);
            if (ret != 0)
                UNRESOLVED(ret, "Thread join failed");
        }

#if VERBOSE > 1
        output("Test passed for %s\n", scenar[i].descr);
#endif

        /* Destroy data */
        ret = pthread_cond_destroy(&(data.cnd));
        if (ret != 0)
            UNRESOLVED(ret, "Cond destroy failed");

        ret = pthread_mutex_destroy(&(data.mtx1));
        if (ret != 0)
            UNRESOLVED(ret, "Mutex 1 destroy failed");

        ret = pthread_mutex_destroy(&(data.mtx2));
        if (ret != 0)
            UNRESOLVED(ret, "Mutex 2 destroy failed");

        ret = pthread_condattr_destroy(&ca);
        if (ret != 0)
            UNRESOLVED(ret, "Cond attribute destroy failed");

        ret = pthread_mutexattr_destroy(&ma);
        if (ret != 0)
            UNRESOLVED(ret, "Mutex attr destroy failed");
    }			/* Proceed to next case */

    PASSED;
}
コード例 #5
0
ファイル: stress1.c プロジェクト: andreimironenko/ltp-full
int main(int argc, char * argv[])
{
	int ret, i, j;
	struct sigaction sa;

	pthread_mutexattr_t ma;
	pthread_condattr_t ca;
	clockid_t cid = CLOCK_REALTIME;

	testdata_t * td;
	testdata_t alternativ;

	int do_fork;
	long pshared, monotonic, cs, mf;

	pthread_t th[NTOT];

	output_init();

	pshared = sysconf(_SC_THREAD_PROCESS_SHARED);
	cs = sysconf(_SC_CLOCK_SELECTION);
	monotonic = sysconf(_SC_MONOTONIC_CLOCK);
	mf =sysconf(_SC_MAPPED_FILES);

	#if VERBOSE > 0
	output("Test starting\n");
	output("System abilities:\n");
	output(" TPS : %li\n", pshared);
	output(" CS  : %li\n", cs);
	output(" MON : %li\n", monotonic);
	output(" MF  : %li\n", mf);
	if ((mf < 0) || (pshared < 0))
		output("Process-shared attributes won't be tested\n");
	if ((cs < 0) || (monotonic < 0))
		output("Alternative clock won't be tested\n");
	#endif

	/* We are not interested in testing the clock if we have no other clock available.. */
	if (monotonic < 0)
		cs = -1;

#ifndef USE_ALTCLK
	if (cs > 0)
		output("Implementation supports the MONOTONIC CLOCK but option is disabled in test.\n");
#endif

/**********
 * Allocate space for the testdata structure
 */
	if (mf < 0)
	{
		/* Cannot mmap a file, we use an alternative method */
		td = &alternativ;
		pshared = -1; /* We won't do this testing anyway */
		#if VERBOSE > 0
		output("Testdata allocated in the process memory.\n");
		#endif
	}
	else
	{
		/* We will place the test data in a mmaped file */
		char filename[] = "/tmp/cond_timedwait_st1-XXXXXX";
		size_t sz, ps;
		void * mmaped;
		int fd;
		char * tmp;

		/* We now create the temp files */
		fd = mkstemp(filename);
		if (fd == -1)
		{ UNRESOLVED(errno, "Temporary file could not be created"); }

		/* and make sure the file will be deleted when closed */
		unlink(filename);

		#if VERBOSE > 1
		output("Temp file created (%s).\n", filename);
		#endif

		ps = (size_t)sysconf(_SC_PAGESIZE);
		sz= ((sizeof(testdata_t) / ps) + 1) * ps; /* # pages needed to store the testdata */

		tmp = calloc(1 , sz);
		if (tmp == NULL)
		{ UNRESOLVED(errno, "Memory allocation failed"); }

		/* Write the data to the file.  */
		if (write (fd, tmp, sz) != (ssize_t) sz)
		{ UNRESOLVED(sz, "Writting to the file failed"); }

		free(tmp);

		/* Now we can map the file in memory */
		mmaped = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
		if (mmaped == MAP_FAILED)
		{ UNRESOLVED(errno, "mmap failed"); }

		td = (testdata_t *) mmaped;

		/* Our datatest structure is now in shared memory */
		#if VERBOSE > 1
		output("Testdata allocated in shared memory (%ib).\n", sizeof(testdata_t));
		#endif
	}

	/* Init the signal handler variable */
	pBoolean = &(td->boolean);

	/* Init the structure */
	for (i=0; i< NSCENAR ; i++)
	{
		#if VERBOSE > 1
		output("[parent] Preparing attributes for: %s\n", scenarii[i].descr);
		#ifdef WITHOUT_XOPEN
		output("[parent] Mutex attributes DISABLED -> not used\n");
		#endif
		#endif
		/* set / reset everything */
		do_fork=0;
		ret = pthread_mutexattr_init(&ma);
		if (ret != 0)  {  UNRESOLVED(ret, "[parent] Unable to initialize the mutex attribute object");  }
		ret = pthread_condattr_init(&ca);
		if (ret != 0)  {  UNRESOLVED(ret, "[parent] Unable to initialize the cond attribute object");  }

		#ifndef WITHOUT_XOPEN
		/* Set the mutex type */
		ret = pthread_mutexattr_settype(&ma, scenarii[i].m_type);
		if (ret != 0)  {  UNRESOLVED(ret, "[parent] Unable to set mutex type");  }
		#if VERBOSE > 1
		output("[parent] Mutex type : %i\n", scenarii[i].m_type);
		#endif
		#endif

		/* Set the pshared attributes, if supported */
		if ((pshared > 0) && (scenarii[i].mc_pshared != 0))
		{
			ret = pthread_mutexattr_setpshared(&ma, PTHREAD_PROCESS_SHARED);
			if (ret != 0)  {  UNRESOLVED(ret, "[parent] Unable to set the mutex process-shared");  }
			ret = pthread_condattr_setpshared(&ca, PTHREAD_PROCESS_SHARED);
			if (ret != 0)  {  UNRESOLVED(ret, "[parent] Unable to set the cond var process-shared");  }
			#if VERBOSE > 1
			output("[parent] Mutex & cond are process-shared\n");
			#endif
		}
		#if VERBOSE > 1
		else {
			output("[parent] Mutex & cond are process-private\n");
		}
		#endif

		/* Set the alternative clock, if supported */
		#ifdef USE_ALTCLK
		if ((cs > 0) && (scenarii[i].c_clock != 0))
		{
			ret = pthread_condattr_setclock(&ca, CLOCK_MONOTONIC);
			if (ret != 0)  {  UNRESOLVED(ret, "[parent] Unable to set the monotonic clock for the cond");  }
			#if VERBOSE > 1
			output("[parent] Cond uses the Monotonic clock\n");
			#endif
		}
		#if VERBOSE > 1
		else {
			output("[parent] Cond uses the default clock\n");
		}
		#endif
		ret = pthread_condattr_getclock(&ca, &cid);
		if (ret != 0)  {  UNRESOLVED(ret, "Unable to get clock from cond attr");  }
		#endif

		/* Tell whether the test will be across processes */
		if ((pshared > 0) && (scenarii[i].fork != 0))
		{
			do_fork = 1;
			#if VERBOSE > 1
			output("[parent] Child will be a new process\n");
			#endif
		}
		#if VERBOSE > 1
		else {
			output("[parent] Child will be a new thread\n");
		}
		#endif

		/* Initialize all the mutex and condvars which uses those attributes */
		for (j=0; j < SCALABILITY_FACTOR * NCHILDREN; j++)
		{
			#define CD (td->cd[i+(j*NSCENAR)])
			CD.pBool = &(td->boolean);
			CD.fork = do_fork;
			CD.cid = cid;

			/* initialize the condvar */
			ret = pthread_cond_init(&(CD.cnd), &ca);
			if (ret != 0)  {  UNRESOLVED(ret, "[parent] Cond init failed");  }

			/* initialize the mutex */
			ret = pthread_mutex_init(&(CD.mtx), &ma);
			if (ret != 0)  {  UNRESOLVED(ret, "[parent] Mutex init failed");  }
			#undef CD
		}

		ret = pthread_condattr_destroy(&ca);
		if (ret != 0)  {  UNRESOLVED(ret, "Failed to destroy the cond var attribute object");  }

		ret = pthread_mutexattr_destroy(&ma);
		if (ret != 0)  {  UNRESOLVED(ret, "Failed to destroy the mutex attribute object");  }
	}
	#if VERBOSE > 1
	output("[parent] All condvars & mutex are ready\n");
	#endif

	ret = pthread_attr_init(&ta);
	if (ret != 0)  {  UNRESOLVED(ret, "[parent] Failed to initialize a thread attribute object");  }
	ret = pthread_attr_setstacksize(&ta, sysconf(_SC_THREAD_STACK_MIN));
	if (ret != 0)  {  UNRESOLVED(ret, "[parent] Failed to set thread stack size");  }

	sigemptyset (&sa.sa_mask);
	sa.sa_flags = 0;
	sa.sa_handler = sighdl;
	if ((ret = sigaction (SIGUSR1, &sa, NULL)))
	{ UNRESOLVED(ret, "Unable to register signal handler"); }
	if ((ret = sigaction (SIGALRM, &sa, NULL)))
	{ UNRESOLVED(ret, "Unable to register signal handler"); }
	#if VERBOSE > 1
	output("[parent] Signal handler registered\n");
	#endif

	for (i=0; i<NTOT; i++)
	{
		ret = pthread_create(&th[i], &ta, threaded_A, &(td->cd[i]));
		/* In case of failure we can exit; the child processes will die after a while */
		if (ret != 0)  {  UNRESOLVED(ret, "[Parent] Failed to create a thread");  }

		#if VERBOSE > 1
		if ((i % 10) == 0)
			output("[parent] %i threads created...\n", i+1);
		#endif
	}

	#if VERBOSE > 1
	output("[parent] All %i threads are running...\n", NTOT);
	#endif

	for (i=0; i<NTOT; i++)
	{
		ret = pthread_join(th[i], NULL);
		if (ret != 0)  {  UNRESOLVED(ret, "[Parent] Failed to join a thread");  }
	}

	/* Destroy everything */
	for (i=0; i< NTOT ; i++)
	{
		/* destroy the condvar */
		ret = pthread_cond_destroy(&(td->cd[i].cnd));
		if (ret != 0)  {  UNRESOLVED(ret, "[parent] Cond destroy failed");  }

		/* destroy the mutex */
		ret = pthread_mutex_init(&(td->cd[i].mtx), &ma);
		if (ret != 0)  {  UNRESOLVED(ret, "[parent] Mutex destroy failed");  }
	}

	#if VERBOSE > 0
	output("Test passed\n");
	#endif

	PASSED;
}