Example #1
0
static void
check_result (int expected, int actual)
{
	if (expected != actual)
		log_error ("expected %d, returned %d\n", expected, actual);
	else
		log_pass ();
}
Example #2
0
/*
 * Check to see that the threads ran in the specified order.
 */
static void
check_run_order (char *order)
{
	const char *sep = ":,";
	char *tok, *last, *idstr, *endptr;
	int expected_id, bytes, count = 0, errors = 0;
	u_int8_t id;

	assert ((tok = (char *) malloc (strlen(order) + 1)) != NULL);
	strcpy (tok, order);	/* tok has to be larger than order */
	assert (ioctl (pipefd[0], FIONREAD, &bytes) == 0);
	log_trace ("%d bytes read from FIFO.\n", bytes);

	for (idstr = strtok_r (tok, sep, &last);
	     (idstr != NULL) && (count < bytes);
	     idstr = strtok_r (NULL, sep, &last)) {

		/* Get the expected id: */
		expected_id = (int) strtol (idstr, &endptr, 10);
		assert ((endptr != NULL) && (*endptr == '\0'));

		/* Read the actual id from the pipe: */
		assert (read (pipefd[0], &id, sizeof (id)) == sizeof (id));
		count = count + sizeof (id);

		if (id != expected_id) {
			log_trace ("Thread %d ran out of order.\n", id);
			errors = errors + 1;
		}
		else {
			log_trace ("Thread %d at priority %d reporting.\n",
			    (int) id, states[id].priority);
		}
	}

	if (count < bytes) {
		/* Clear the pipe: */
		while (count < bytes) {
			read (pipefd[0], &id, sizeof (id));
			count = count + 1;
			errors = errors + 1;
		}
	}
	else if (bytes < count)
		errors = errors + count - bytes;

	if (errors == 0)
		log_pass ();
	else
		log_error ("%d threads ran out of order", errors);
}
Example #3
0
static void
mutex_prioceiling_test (void)
{
	const int test_thread_id = 0;	/* ID of test thread */
	pthread_mutexattr_t mattr;
	struct sched_param param;
	pthread_mutex_t	m[3];
	mutex_kind_t	mkind;
	int		i, ret, policy, my_prio, old_ceiling;

	log ("Testing priority ceilings\n");
	log ("-------------------------\n");
	for (mkind = M_POSIX; mkind <= M_SS2_RECURSIVE; mkind++) {

		log ("  Protype PTHREAD_PRIO_PROTECT, Type %s\n",
		    mutextype_strs[mkind]);

		/*
		 * Initialize and create a mutex.
		 */
		assert (pthread_mutexattr_init (&mattr) == 0);

		/* Get this threads current priority. */
		assert (pthread_getschedparam (pthread_self(), &policy,
		    &param) == 0);
		my_prio = param.sched_priority;	/* save for later use */
		log_trace ("Current scheduling policy %d, priority %d\n",
		    policy, my_prio);

		/*
		 * Initialize and create 3 priority protection mutexes with
		 * default (max priority) ceilings.
		 */
		assert (pthread_mutexattr_setprotocol(&mattr,
		    PTHREAD_PRIO_PROTECT) == 0);

		/*
		 * Ensure that the first mutex type is a POSIX
		 * compliant mutex.
		 */
		if (mkind != M_POSIX) {
			assert (pthread_mutexattr_settype (&mattr,
			    mutex_types[mkind]) == 0);
		}

		for (i = 0; i < 3; i++)
			assert (pthread_mutex_init (&m[i], &mattr) == 0);

		/*
		 * Set the ceiling priorities for the 3 priority protection
		 * mutexes to, 5 less than, equal to, and 5 greater than,
		 * this threads current priority.
		 */
		for (i = 0; i < 3; i++)
			assert (pthread_mutex_setprioceiling (&m[i],
			    my_prio - 5 + 5*i, &old_ceiling) == 0);

		/*
		 * Check that if we attempt to take a mutex whose priority
		 * ceiling is lower than our priority, we get an error.
		 */
		log ("    Lock with ceiling priority < thread priority - ");
		ret = pthread_mutex_lock (&m[0]);
		check_result (/* expected */ EINVAL, ret);
		if (ret == 0)
			pthread_mutex_unlock (&m[0]);

		/*
		 * Check that we can take a mutex whose priority ceiling
		 * is equal to our priority.
		 */
		log ("    Lock with ceiling priority = thread priority - ");
		ret = pthread_mutex_lock (&m[1]);
		check_result (/* expected */ 0, ret);
		if (ret == 0)
			pthread_mutex_unlock (&m[1]);

		/*
		 * Check that we can take a mutex whose priority ceiling
		 * is higher than our priority.
		 */
		log ("    Lock with ceiling priority > thread priority - ");
		ret = pthread_mutex_lock (&m[2]);
		check_result (/* expected */ 0, ret);
		if (ret == 0)
			pthread_mutex_unlock (&m[2]);

		/*
		 * Have the test thread go into a busy loop for 5 seconds
		 * and see that it doesn't block this thread (since the
		 * priority ceiling of mutex 0 and the priority of the test
		 * thread are both less than the priority of this thread).
		 */
		log ("    Preemption with ceiling priority < thread "
		    "priority - ");
		/* Have the test thread take mutex 0. */
		send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[0]);
		sleep (1);

		log_trace ("Sending busy command.\n");
		send_cmd (test_thread_id, CMD_BUSY_LOOP);
		log_trace ("Busy sent, yielding\n");
		pthread_yield ();
		log_trace ("Returned from yield.\n");
		if (states[test_thread_id].flags &
		    (FLAGS_IS_BUSY | FLAGS_WAS_BUSY))
			log_error ("test thread inproperly preempted us.\n");
		else {
			/* Let the thread finish its busy loop. */
			sleep (6);
			if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0)
				log_error ("test thread never finished.\n");
			else
				log_pass ();
		}
		states[test_thread_id].flags &= ~FLAGS_WAS_BUSY;

		/* Have the test thread release mutex 0. */
		send_cmd (test_thread_id, CMD_RELEASE_ALL);
		sleep (1);

		/*
		 * Have the test thread go into a busy loop for 5 seconds
		 * and see that it preempts this thread (since the priority
		 * ceiling of mutex 1 is the same as the priority of this
		 * thread).  The test thread should not run to completion
		 * as its time quantum should expire before the 5 seconds
		 * are up.
		 */
		log ("    Preemption with ceiling priority = thread "
		    "priority - ");

		/* Have the test thread take mutex 1. */
		send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]);
		sleep (1);

		log_trace ("Sending busy\n");
		send_cmd (test_thread_id, CMD_BUSY_LOOP);
		log_trace ("Busy sent, yielding\n");
		pthread_yield ();
		log_trace ("Returned from yield.\n");
		if ((states[test_thread_id].flags & FLAGS_IS_BUSY) == 0)
			log_error ("test thread did not switch in on yield.\n");
		else if (states[test_thread_id].flags & FLAGS_WAS_BUSY)
			log_error ("test thread ran to completion.\n");
		else {
			/* Let the thread finish its busy loop. */
			sleep (6);
			if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0)
				log_error ("test thread never finished.\n");
			else
				log_pass ();
		}
		states[test_thread_id].flags &= ~FLAGS_WAS_BUSY;

		/* Have the test thread release mutex 1. */
		send_cmd (test_thread_id, CMD_RELEASE_ALL);
		sleep (1);

		/*
		 * Set the scheduling policy of the test thread to SCHED_FIFO
		 * and have it go into a busy loop for 5 seconds.  This
		 * thread is SCHED_RR, and since the priority ceiling of
		 * mutex 1 is the same as the priority of this thread, the
		 * test thread should run to completion once it is switched
		 * in.
		 */
		log ("    SCHED_FIFO scheduling and ceiling priority = "
		    "thread priority - ");
		param.sched_priority = states[test_thread_id].priority;
		assert (pthread_setschedparam (states[test_thread_id].tid,
		    SCHED_FIFO, &param) == 0);

		/* Have the test thread take mutex 1. */
		send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[1]);
		sleep (1);

		log_trace ("Sending busy\n");
		send_cmd (test_thread_id, CMD_BUSY_LOOP);
		log_trace ("Busy sent, yielding\n");
		pthread_yield ();
		log_trace ("Returned from yield.\n");
		if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0) {
			log_error ("test thread did not run to completion.\n");
			/* Let the thread finish it's busy loop. */
			sleep (6);
		}
		else
			log_pass ();
		states[test_thread_id].flags &= ~FLAGS_WAS_BUSY;

		/* Restore the test thread scheduling parameters. */
		param.sched_priority = states[test_thread_id].priority;
		assert (pthread_setschedparam (states[test_thread_id].tid,
		    SCHED_RR, &param) == 0);

		/* Have the test thread release mutex 1. */
		send_cmd (test_thread_id, CMD_RELEASE_ALL);
		sleep (1);

		/*
		 * Have the test thread go into a busy loop for 5 seconds
		 * and see that it preempts this thread (since the priority
		 * ceiling of mutex 2 is the greater than the priority of
		 * this thread).  The test thread should run to completion
		 * and block this thread because its active priority is
		 * higher.
		 */
		log ("    SCHED_FIFO scheduling and ceiling priority > "
		    "thread priority - ");
		/* Have the test thread take mutex 2. */
		send_mutex_cmd (test_thread_id, CMD_TAKE_MUTEX, &m[2]);
		sleep (1);

		log_trace ("Sending busy\n");
		send_cmd (test_thread_id, CMD_BUSY_LOOP);
		log_trace ("Busy sent, yielding\n");
		pthread_yield ();
		log_trace ("Returned from yield.\n");
		if ((states[test_thread_id].flags & FLAGS_IS_BUSY) != 0) {
			log_error ("test thread did not run to completion.\n");
			/* Let the thread finish it's busy loop. */
			sleep (6);
		}
		else if ((states[test_thread_id].flags & FLAGS_WAS_BUSY) == 0)
			log_error ("test thread never finished.\n");
		else
			log_pass ();
		states[test_thread_id].flags &= ~FLAGS_WAS_BUSY;

		/* Have the test thread release mutex 2. */
		send_cmd (test_thread_id, CMD_RELEASE_ALL);
		sleep (1);

		/* Destroy the mutexes. */
		for (i = 0; i < 3; i++)
			assert (pthread_mutex_destroy (&m[i]) == 0);
	}
}
Example #4
0
void
main(int argc, char *argv[])
{
	int i, ret, fd;
	char *penv[] = {"mnt", "test_file"};

	log_assert("Verify access time will be changed when file data" \
	    "was last accessed.");
	log_onexit(cleanup);

	/*
	 * Get envirnment variable value
	 */
/*	for (i = 0; i < sizeof (penv) / sizeof (char *); i++) {
		if ((penv[i] = getenv(penv[i])) == NULL) {
			log_must(-1, "getenv(penv[i])");
		}
	}*/
	(void) snprintf(tfile, sizeof (tfile), "%s/%s", "/tank/zfs","test_file");

	/*
	 * If the test file is existing, remove it firstly
	 */

        printf("file :  %s\n", tfile);
   
	if (access(tfile, F_OK) == 0) {
		unlink(tfile);
	}
	ret = 0;
	if ((fd = open(tfile, O_WRONLY | O_CREAT | O_TRUNC, ALL_MODE)) == -1) {
		ret = errno;
	}
	if (fd != -1) {
		(void) close(fd);
	}
	(void) snprintf(msg, sizeof (msg), \
	    "open(%s, O_WRONLY | O_CREAT | O_TRUNC, ALL_MODE)", tfile);
	log_must(ret, msg);

	for (i = 5; i < NCOMMAND; i++) {
		time_t t1, t2;

		/*
		 * Get original time before operating.
		 */

		ret = get_file_time(tfile, timetest_table[i].type, &t1);
		if (ret != 0) {
			(void) snprintf(msg, sizeof (msg),
			    "get_file_time(%s, %d, &t1)",
			    tfile, timetest_table[i].type);
			log_must(ret, msg);
		}

		/*
		 * Sleep 2 seconds, then invoke command on givin file
		 */
		sleep(2);
		timetest_table[i].func(tfile);

		/*
		 * Get time after operating.
		 */
		ret = get_file_time(tfile, timetest_table[i].type, &t2);
		if (ret != 0) {
			(void) snprintf(msg, sizeof (msg),
			    "get_file_time(%s, %d, &t2)",
			    tfile, timetest_table[i].type);
			log_must(ret, msg);
		}

		if (t1 == t2) {
			snprintf(msg, sizeof (msg), "%s: t1(%ld) == t2(%ld)",
			    timetest_table[i].name, (long)t1, (long)t2);
			log_must(-1, msg);
		} else {
			snprintf(msg, sizeof (msg), "%s: t1(%ld) != t2(%ld)",
			    timetest_table[i].name, (long)t1, (long)t2);
			log_must(0, msg);
		}
	}

	(void) unlink(tfile);

	log_pass("Verify access time will be changed passed.");
}