This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Memory fencing problem in pthread cancellation


Forgot the testcase. Run as a normal user.

#include <sys/wait.h>
#include <stdio.h>
#include <signal.h>
#include <pthread.h>
#include <errno.h>
#include <stdlib.h>

// gcc -g3 -O0 gcc_assert_dw2.c -lpthread
// http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52839#c10

void *foo(void *arg)
{
	pthread_detach(pthread_self());
	return NULL;	
}

int create_foo_will_fail_with_eperm()
{
	int ret;
	int old;
	pthread_t t;
	struct sched_param sp;

	pthread_attr_t ta;
	ret = pthread_attr_init(&ta);
	if (ret != 0) {
		printf("attr init: %d %d\n", ret, errno);
		exit(1);
	}

	ret = pthread_attr_setinheritsched(&ta,	PTHREAD_EXPLICIT_SCHED);
	if (ret != 0) {
		printf("attr setinheritsched: %d %d\n", ret, errno);
		exit(1);
	}

        ret = pthread_attr_setschedpolicy(&ta, SCHED_RR);
	if (ret != 0) {
		printf("attr setschedpolicy: %d %d\n", ret, errno);
		exit(1);
	}

	sp.sched_priority = sched_get_priority_max(SCHED_RR);
	ret = pthread_attr_setschedparam(&ta, &sp);
	if (ret != 0) {
		printf("attr setschedparam: %d %d\n", ret, errno);
		exit(1);
	}

	ret = pthread_create(&t, &ta, foo, NULL);
	if (ret == EPERM) {
		/*
		this is expected
		printf("create foo: %d %d\n", ret, errno);
		*/
	} else {
		printf("create foo suceeded: %d %d\n", ret, errno);
		exit(2);
	}
	return 0;
}

int create_foo_thread()
{
	int ret;
	pthread_t t;
	ret = pthread_create(&t, NULL, foo, NULL);
	if (ret != 0) {
		printf("create foo2: %d %d\n", ret, errno);
		exit(3);
	}
}

void *bar(void *arg)
{
	int i;
	int max1 = rand() % 8;
	int max2 = rand() % 8;
	int max3 = rand() % 8;

	for (i=0; i < max1; i++)
		create_foo_thread();

	for (i=0; i < max2; i++)
		create_foo_will_fail_with_eperm();

	for (i=0; i < max3; i++)
		create_foo_thread();
}

int do_child()
{
	int ret;
	pthread_t t;

	ret = pthread_create(&t, NULL, bar, NULL);
	if (ret != 0) {
		printf("create bar: %d %d\n", ret, errno);
		exit(4);
	}

	ret = pthread_join(t, NULL);
	if (ret != 0) {
		printf("join bar: %d\n", ret, errno);
		exit(4);
	}
}

int main()
{
	int child;
	int ret;
	int status;
	int i = 0;

	srand(0);

	while (1) {
		i++;
		if (i % 1000 == 0)
			printf("%d\n", i);

		child = fork();
		if (child == 0) {
			do_child();
			pthread_exit(0);
			printf("should not be reached\n");
			exit(2);
		}

		ret = waitpid(child, &status, 0);
		if (ret != child) {
			printf("Waitpid returned the wrong PID");
			exit(5);
		}

		if (!WIFEXITED(status)) {
			printf("status: %d\n", status);
			exit(6);
		}

		if (WEXITSTATUS(status) != 0) {
			printf("exit status: %d\n", WEXITSTATUS(status));
			exit(7);
		}
	}
	return 0;
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]