Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Demiurg

macrumors newbie
Original poster
Mar 11, 2008
3
0
Hi All,

I'm now working on porting our system to the Mac OS X. Everything works well except one strange thing on process's exit and I can't understand where we have gone worng.

Application (which is multiprocess in nature) extensively uses shm_open/mmap/munmap system calls to share memory between processes. The problem is that on exit this application hangs (almost absolutely) whole system for a few seconds. Removing of some mmap/munmap calls solves this problem. I don't know what is going on at this moment. I want also to mention that this code works perfectly on FreeBSD/Linux/Windows.

Are there any ideas?

System is 10.4.11 PPC.
 

Sayer

macrumors 6502a
Jan 4, 2002
981
0
Austin, TX
Try attaching Shark to sample the process to see where its hanging up. If you are using Xcode on Tiger, I think there's an option to attach Shark in the Debug menu (in that version of Xcode).

Otherwise Shark is in Developer > Applications > Performance Tools

You can attach to any process and sample for a bit and see where the app is spending the time while it quits.
 

Demiurg

macrumors newbie
Original poster
Mar 11, 2008
3
0
Try attaching Shark to sample the process to see where its hanging up. If you are using Xcode on Tiger, I think there's an option to attach Shark in the Debug menu (in that version of Xcode).

Otherwise Shark is in Developer > Applications > Performance Tools

You can attach to any process and sample for a bit and see where the app is spending the time while it quits.

Thanks for the answer.

Below is the result of the sampling of the "everything" (I can't sample one process since Shark stops sampling before exit call):
Note that 99.6% takes apprx. 2 seconds during which system absolutely hangs.

99.6% 99.6% mach_kernel ----- hw_rem_map
0.0% 99.6% mach_kernel ------- mapping_remove
0.0% 99.6% mach_kernel --------- pmap_remove
0.0% 99.6% mach_kernel ----------- vm_map_submap_pmap_clean
0.0% 99.6% mach_kernel ------------- vm_map_remove
0.0% 99.6% mach_kernel --------------- task_terminate_internal
0.0% 99.6% mach_kernel ----------------- exit1
0.0% 99.6% mach_kernel ------------------- exit
0.0% 99.6% mach_kernel --------------------- unix_syscall
0.0% 99.6% mach_kernel ----------------------- shandler
0.0% 0.0% mach_kernel mapping_remove
0.0% 0.0% mach_kernel pmap_remove
0.0% 0.0% mach_kernel vm_map_submap_pmap_clean
 

Demiurg

macrumors newbie
Original poster
Mar 11, 2008
3
0
Here is complete and very simple "killing" application.
And here (http://discussions.apple.com/thread.jspa?threadID=1436846&tstart=0) this "bug" was confirmed on the similar system.

Firstly you should run this one (and DO NOT perform exit from it):

=========================================================
Code:
#include <stdio.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>

#define SHM_NAME "/tmp/zeroSharedMemory" /* Shared memory name */
#define SHM_SIZE 0x10000 /* Shared memory region size in bytes (64Kb) */

/* Clean ups given shared memory object */
static inline void destroy_shared_memory(int shm_fd, const char* shm_name)
{
	if(-1 == close(shm_fd))
	{
		perror("close");
		exit(-1);
	}
	if (-1 == shm_unlink(shm_name))
	{
		perror("shm_unlink");
		exit(-1);
	}
}

/* Creates shared memory object, zeroing it and waiting any key to be inputted */
int main (int argc, const char * argv[]) {
	int shm_fd; //shared memory file descriptor
	void* shm_addr; //shared memory attach address

	/* Create new shared memory object on filesystem */
	shm_fd = shm_open(SHM_NAME, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
	if(shm_fd == -1)
	{
		perror("shm_open");
		return -1;
	}

	/* Truncate to the defined size */
	if (ftruncate(shm_fd, (off_t) SHM_SIZE) == -1)
	{
		perror("ftruncate");
		destroy_shared_memory(shm_fd, SHM_NAME);
		return -1;
	}

	/* mmap shared memory object into virtual address space */
	shm_addr = mmap(NULL,
		(size_t)(SHM_SIZE),
		PROT_READ | PROT_WRITE,
		MAP_SHARED,
		shm_fd,
		(off_t)0);

	if(shm_addr == MAP_FAILED)
	{
		perror("mmap");
		destroy_shared_memory(shm_fd, SHM_NAME);
		return -1;
	}

	/* Zeroing memory */
	memset(shm_addr, 0, (size_t)SHM_SIZE);

	/* Waiting until key pressed ... and perform cleanup */
	printf("Press any key to perform cleanup and exit ...\n");
	getchar();
	destroy_shared_memory(shm_fd, SHM_NAME);
	return 0;
}
=========================================================

Now start this one:

=========================================================
Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>

#define SHM_NAME "/tmp/zeroSharedMemory" /* Shared memory name */
#define SHM_SIZE 0x10000 /* Shared memory region size in bytes (64Kb) */
#define REGIONS_NUM 16000 /* mmap regions number */

/* Close shared memory object descriptor */
static inline void close_shared_memory(int shm_fd, const char* shm_name)
{
	if(-1 == close(shm_fd))
	{
		perror("close");
		exit(-1);
	}
}

/* Opens shared memory object, mmaps it REGIONS_NUM times, checks each header and exits */
int main (int argc, const char * argv[]) {
	int shm_fd; //shared memory file descriptor
	void* shm_addr[REGIONS_NUM]; //shared memory attach address(es)
	int i; //for iteration

	/* Open shared memory object on filesystem */
	shm_fd = shm_open(SHM_NAME, O_RDWR, 0);
	if(shm_fd == -1)
	{
		perror("shm_open");
		return -1;
	}

	/* mmap zero page of the shared memory object into virtual address space */
	printf("Going to create initial mapping ...");
	for(i = 0; i < REGIONS_NUM; i++)
	{
		shm_addr = mmap(NULL,
			(size_t)SHM_SIZE,
			PROT_READ | PROT_WRITE,
			MAP_SHARED,
			shm_fd,
			(off_t) 0);

		if(MAP_FAILED == shm_addr)
		{
			perror("mmap");
			close_shared_memory(shm_fd, SHM_NAME);
			return -1;
		}
	}
	printf(" OK\n");

	printf("Going to unmap ...");
	/* unmap a number of blocks */
	for(i = 0; i < REGIONS_NUM; i++)
	{
		// Check header of the block
		if( ((char*)(shm_addr))[0] != '\0')
		{
			// Actually we don't perform this operation in this example application since header
			// always contains zeroes ...
			munmap(shm_addr, (size_t)SHM_SIZE);
		}
	}
	printf(" OK\n");

	/* Waiting until key pressed ... and perform cleanup */
	printf("Press any key to perform clean up and exit ...\n");
	getchar();
	close_shared_memory(shm_fd, SHM_NAME);
	return 0;
}
=========================================================

My system (PPC, 10.4.11) hangs (only mouse pointer is alive) on exit from the second process for 3-4 seconds.
 

yeroen

macrumors 6502a
Mar 8, 2007
944
2
Cambridge, MA
Thanks for providing the source code.

I've been puzzling over this topic for the last several days. Now I want to know why also.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.