Training courses

Kernel and Embedded Linux

Bootlin training courses

Embedded Linux, kernel,
Yocto Project, Buildroot, real-time,
graphics, boot time, debugging...

Bootlin logo

Elixir Cross Referencer

/*
 * Copyright (c) 2000-2002, 2004, 2005 Proofpoint, Inc. and its suppliers.
 *      All rights reserved.
 *
 * By using this file, you agree to the terms and conditions set
 * forth in the LICENSE file which can be found at the top level of
 * the sendmail distribution.
 */

#include <sm/gen.h>
SM_RCSID("@(#)$Id: t-shm.c,v 1.23 2013-11-22 20:51:43 ca Exp $")

#include <stdio.h>

#if SM_CONF_SHM
# include <stdlib.h>
# include <unistd.h>
# include <sys/wait.h>

# include <sm/heap.h>
# include <sm/string.h>
# include <sm/test.h>
# include <sm/shm.h>

# define SHMSIZE	1024
# define SHM_MAX	6400000
# define T_SHMKEY	21


/*
**  SHMINTER -- interactive testing of shared memory
**
**	Parameters:
**		owner -- create segment.
**
**	Returns:
**		0 on success
**		< 0 on failure.
*/

int shminter __P((bool));

int
shminter(owner)
	bool owner;
{
	int *shm, shmid;
	int i, t;

	shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
	if (shm == (int *) 0)
	{
		perror("shminit failed");
		return -1;
	}

	while ((t = getchar()) != EOF)
	{
		switch (t)
		{
		  case 'c':
			*shm = 0;
			break;
		  case 'i':
			++*shm;
			break;
		  case 'd':
			--*shm;
			break;
		  case 's':
			sleep(1);
			break;
		  case 'l':
			t = *shm;
			for (i = 0; i < SHM_MAX; i++)
			{
				++*shm;
			}
			if (*shm != SHM_MAX + t)
				fprintf(stderr, "error: %d != %d\n",
					*shm, SHM_MAX + t);
			break;
		  case 'v':
			printf("shmval: %d\n", *shm);
			break;
		  case 'S':
			i = sm_shmsetowner(shmid, getuid(), getgid(), 0644);
			printf("sm_shmsetowner=%d\n", i);
			break;
		}
	}
	return sm_shmstop((void *) shm, shmid, owner);
}


/*
**  SHMBIG -- testing of shared memory
**
**	Parameters:
**		owner -- create segment.
**		size -- size of segment.
**
**	Returns:
**		0 on success
**		< 0 on failure.
*/

int shmbig __P((bool, int));

int
shmbig(owner, size)
	bool owner;
	int size;
{
	int *shm, shmid;
	int i;

	shm = (int *) sm_shmstart(T_SHMKEY, size, 0, &shmid, owner);
	if (shm == (int *) 0)
	{
		perror("shminit failed");
		return -1;
	}

	for (i = 0; i < size / sizeof(int); i++)
		shm[i] = i;
	for (i = 0; i < size / sizeof(int); i++)
	{
		if (shm[i] != i)
		{
			fprintf(stderr, "failed at %d: %d", i, shm[i]);
		}
	}

	return sm_shmstop((void *) shm, shmid, owner);
}


/*
**  SHMTEST -- test of shared memory
**
**	Parameters:
**		owner -- create segment.
**
**	Returns:
**		0 on success
**		< 0 on failure.
*/

# define MAX_CNT	10

int shmtest __P((int));

int
shmtest(owner)
	int owner;
{
	int *shm, shmid;
	int cnt = 0;

	shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
	if (shm == (int *) 0)
	{
		perror("shminit failed");
		return -1;
	}

	if (owner)
	{
		int r;

		r = sm_shmsetowner(shmid, getuid(), getgid(), 0660);
		SM_TEST(r == 0);
		*shm = 1;
		while (*shm == 1 && cnt++ < MAX_CNT)
			sleep(1);
		SM_TEST(cnt <= MAX_CNT);

		/* release and re-acquire the segment */
		r = sm_shmstop((void *) shm, shmid, owner);
		SM_TEST(r == 0);
		shm = (int *) sm_shmstart(T_SHMKEY, SHMSIZE, 0, &shmid, owner);
		SM_TEST(shm != (int *) 0);
	}
	else
	{
		while (*shm != 1 && cnt++ < MAX_CNT)
			sleep(1);
		SM_TEST(cnt <= MAX_CNT);
		*shm = 2;

		/* wait a momemt so the segment is still in use */
		sleep(2);
	}
	return sm_shmstop((void *) shm, shmid, owner);
}

int
main(argc, argv)
	int argc;
	char *argv[];
{
	bool interactive = false;
	bool owner = false;
	int big = -1;
	int ch;
	int r = 0;
	int status;
	extern char *optarg;

# define OPTIONS	"b:io"
	while ((ch = getopt(argc, argv, OPTIONS)) != -1)
	{
		switch ((char) ch)
		{
		  case 'b':
			big = atoi(optarg);
			break;

		  case 'i':
			interactive = true;
			break;

		  case 'o':
			owner = true;
			break;

		  default:
			break;
		}
	}

	if (interactive)
		r = shminter(owner);
	else if (big > 0)
		r = shmbig(true, big);
	else
	{
		pid_t pid;
		extern int SmTestNumErrors;

		if ((pid = fork()) < 0)
		{
			perror("fork failed\n");
			return -1;
		}

		sm_test_begin(argc, argv, "test shared memory");
		if (pid == 0)
		{
			/* give the parent the chance to setup data */
			sleep(1);
			r = shmtest(false);
		}
		else
		{
			r = shmtest(true);
			(void) wait(&status);
		}
		SM_TEST(r == 0);
		if (SmTestNumErrors > 0)
			printf("add -DSM_CONF_SHM=0 to confENVDEF in devtools/Site/site.config.m4\nand start over.\n");
		return sm_test_end();
	}
	return r;
}
#else /* SM_CONF_SHM */
int
main(argc, argv)
	int argc;
	char *argv[];
{
	printf("No support for shared memory configured on this machine\n");
	return 0;
}
#endif /* SM_CONF_SHM */