NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: PR/53998 CVS commit: src/sys/kern



	Hello,

	In attachement a quick and dirty program that shows sem_init() bugs. If
I remove fork() in child thread, sem_init() runs fine.

	Best regards,

	JB
semaphore: semaphore.o
	gcc -g -o $@ $+ -lpthread

clean:
	rm -f *.o semaphore

%.o: %.c
	gcc -g -c $< -Wall -o $@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>

#define NUMBER_OF_THREADS	8

typedef struct
{
	pthread_t		tid;
	volatile bool	active;
	long long		i;
	sem_t			s;
} thread_arg_t;

thread_arg_t targ[NUMBER_OF_THREADS];

void *
thread(void *arg)
{
	char			**arguments;

	pid_t			pid;
	thread_arg_t	*ta = arg;

	if (sem_init(&(ta->s), 0, 0) != 0)
	{
		perror("sem_init()");
		_exit(EXIT_FAILURE);
	}

	pid = fork();

	if (pid < 0)
	{
		perror("fork()");
		_exit(EXIT_FAILURE);
	}
	else if (pid == 0)
	{
		// Child

		if ((arguments = malloc(3 * sizeof(char *))) == NULL)
		{
			perror("malloc()");
			_exit(EXIT_FAILURE);
		}

		if ((arguments[0] = malloc(5 * sizeof(char *))) == NULL)
		{
			perror("malloc(0)");
			_exit(EXIT_FAILURE);
		}

		if ((arguments[1] = malloc(40 * sizeof(char *))) == NULL)
		{
			perror("malloc(1)");
			_exit(EXIT_FAILURE);
		}

		strcpy(arguments[0], "echo");
		sprintf(arguments[1], "< %lld >", ta->i);
		arguments[2] = NULL;

		execvp(arguments[0], arguments);
		perror("execvp()");
		_exit(EXIT_FAILURE);
	}

	if (sem_destroy(&(ta->s)) != 0)
	{
		perror("sem_destroy()");
		_exit(EXIT_FAILURE);
	}

	ta->active = false;
	pthread_exit(NULL);
}

int
main()
{
	int			i;
	long long	nt;

	for(nt = 0;;)
	{
		for(i = 0; i < NUMBER_OF_THREADS; i++)
		{
			if (targ[i].active == false)
			{
				break;
			}
		}

		if (i < NUMBER_OF_THREADS)
		{
			printf("Free slot : %d (%lld threads)\n", i, ++nt);
			targ[i].active = true;
			targ[i].i = nt;

			if (pthread_create(&(targ[i].tid), NULL, thread, &(targ[i])) != 0)
			{
				perror("pthread_create()");
				exit(EXIT_FAILURE);
			}

			if (pthread_detach(targ[i].tid) != 0)
			{
				perror("pthread_detach()");
				exit(EXIT_FAILURE);
			}
		}
		else
		{
			usleep(1000);
		}
	}

	exit(EXIT_SUCCESS);
}


Home | Main Index | Thread Index | Old Index