xref: /freebsd/tools/test/stress2/misc/machipc.sh (revision 8a272653d9fbd9fc37691c9aad6a05089b4ecb4d)
1*8a272653SPeter Holm#!/bin/sh
2*8a272653SPeter Holm
3*8a272653SPeter Holm#
4*8a272653SPeter Holm# Copyright (c) 2015 EMC Corp.
5*8a272653SPeter Holm# All rights reserved.
6*8a272653SPeter Holm#
7*8a272653SPeter Holm# Redistribution and use in source and binary forms, with or without
8*8a272653SPeter Holm# modification, are permitted provided that the following conditions
9*8a272653SPeter Holm# are met:
10*8a272653SPeter Holm# 1. Redistributions of source code must retain the above copyright
11*8a272653SPeter Holm#    notice, this list of conditions and the following disclaimer.
12*8a272653SPeter Holm# 2. Redistributions in binary form must reproduce the above copyright
13*8a272653SPeter Holm#    notice, this list of conditions and the following disclaimer in the
14*8a272653SPeter Holm#    documentation and/or other materials provided with the distribution.
15*8a272653SPeter Holm#
16*8a272653SPeter Holm# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*8a272653SPeter Holm# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*8a272653SPeter Holm# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*8a272653SPeter Holm# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*8a272653SPeter Holm# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*8a272653SPeter Holm# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*8a272653SPeter Holm# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*8a272653SPeter Holm# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*8a272653SPeter Holm# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*8a272653SPeter Holm# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*8a272653SPeter Holm# SUCH DAMAGE.
27*8a272653SPeter Holm#
28*8a272653SPeter Holm
29*8a272653SPeter Holm# Threaded Mach IPC test scenario
30*8a272653SPeter Holm# https://people.freebsd.org/~pho/stress/log/kip014.txt
31*8a272653SPeter Holm
32*8a272653SPeter Holmps -p1 | grep -q launchd || exit 0
33*8a272653SPeter Holm
34*8a272653SPeter Holmodir=`pwd`
35*8a272653SPeter Holmcd /tmp
36*8a272653SPeter Holmsed '1,/^EOF/d' < $odir/$0 > machipc.c
37*8a272653SPeter Holmcc -o machipc -Wall -Wextra -O2 -g machipc.c -lmach -lpthread || exit 1
38*8a272653SPeter Holmrm machipc.c
39*8a272653SPeter Holmcd $odir
40*8a272653SPeter Holm
41*8a272653SPeter Holm(cd ../testcases/swap; ./swap -t 20m -i 20 -h -v) > /dev/null 2>&1 &
42*8a272653SPeter Holmsleep 5
43*8a272653SPeter Holm/tmp/machipc
44*8a272653SPeter Holmpkill swap
45*8a272653SPeter Holmwait
46*8a272653SPeter Holmrm -f /tmp/machipc
47*8a272653SPeter Holmexit 0
48*8a272653SPeter HolmEOF
49*8a272653SPeter Holm#include <sys/types.h>
50*8a272653SPeter Holm
51*8a272653SPeter Holm#include <mach/mach.h>
52*8a272653SPeter Holm
53*8a272653SPeter Holm#include <err.h>
54*8a272653SPeter Holm#include <pthread.h>
55*8a272653SPeter Holm#include <stdlib.h>
56*8a272653SPeter Holm#include <stdio.h>
57*8a272653SPeter Holm#include <string.h>
58*8a272653SPeter Holm#include <unistd.h>
59*8a272653SPeter Holm
60*8a272653SPeter Holmtypedef struct {
61*8a272653SPeter Holm	unsigned int msgt_name : 8,
62*8a272653SPeter Holm		     msgt_size : 8,
63*8a272653SPeter Holm		     msgt_number : 12,
64*8a272653SPeter Holm		     msgt_inline : 1,
65*8a272653SPeter Holm		     msgt_longform : 1,
66*8a272653SPeter Holm		     msgt_deallocate : 1,
67*8a272653SPeter Holm		     msgt_unused : 1;
68*8a272653SPeter Holm} mach_msg_type_t;
69*8a272653SPeter Holm
70*8a272653SPeter Holmstruct integer_message {
71*8a272653SPeter Holm	mach_msg_header_t head;
72*8a272653SPeter Holm	mach_msg_type_t type;
73*8a272653SPeter Holm
74*8a272653SPeter Holm	int inline_integer;
75*8a272653SPeter Holm};
76*8a272653SPeter Holm
77*8a272653SPeter Holmstruct message_recv
78*8a272653SPeter Holm{
79*8a272653SPeter Holm	mach_msg_header_t head;
80*8a272653SPeter Holm	mach_msg_type_t type;
81*8a272653SPeter Holm	int inline_integer;
82*8a272653SPeter Holm	mach_msg_trailer_t trailer;
83*8a272653SPeter Holm};
84*8a272653SPeter Holm
85*8a272653SPeter Holmmach_port_t bootstrap_port;
86*8a272653SPeter Holm
87*8a272653SPeter Holm#define MACH_MSG_TYPE_INTEGER_32 2
88*8a272653SPeter Holm#define N 100000000
89*8a272653SPeter Holm
90*8a272653SPeter Holmstatic void
91*8a272653SPeter Holmerror(int exitcode, int macherr, const char *funcname)
92*8a272653SPeter Holm{
93*8a272653SPeter Holm	printf("%s failed with %x\n", funcname, macherr);
94*8a272653SPeter Holm	exit(exitcode);
95*8a272653SPeter Holm}
96*8a272653SPeter Holm
97*8a272653SPeter Holmvoid *
98*8a272653SPeter Holmclient(void *arg)
99*8a272653SPeter Holm{
100*8a272653SPeter Holm	mach_port_t port = *(mach_port_t *) arg;
101*8a272653SPeter Holm	struct message_recv message = {};
102*8a272653SPeter Holm	int err, i;
103*8a272653SPeter Holm
104*8a272653SPeter Holm	message.head.msgh_local_port = port;
105*8a272653SPeter Holm	message.head.msgh_size = sizeof(message);
106*8a272653SPeter Holm
107*8a272653SPeter Holm	for (i = 0; i < N; i++) {
108*8a272653SPeter Holm		/* Receive a message */
109*8a272653SPeter Holm		err = mach_msg(&message.head,	/* The header */
110*8a272653SPeter Holm		    MACH_RCV_MSG,		/* Flags */
111*8a272653SPeter Holm		    0,				/* Send size */
112*8a272653SPeter Holm		    sizeof(message),		/* Max receive size */
113*8a272653SPeter Holm		    port,			/* Receive port */
114*8a272653SPeter Holm		    MACH_MSG_TIMEOUT_NONE,	/* No timeout */
115*8a272653SPeter Holm		    MACH_PORT_NULL);		/* No notification */
116*8a272653SPeter Holm		if (err)
117*8a272653SPeter Holm			error(1, err, "server mach_msg MACH_RCV_MSG");
118*8a272653SPeter Holm		if (message.inline_integer != i)
119*8a272653SPeter Holm			errx(1, "FAIL message.inline_integer = %d, i = %d",
120*8a272653SPeter Holm			    message.inline_integer, i);
121*8a272653SPeter Holm	}
122*8a272653SPeter Holm
123*8a272653SPeter Holm	return(0);
124*8a272653SPeter Holm}
125*8a272653SPeter Holm
126*8a272653SPeter Holmint
127*8a272653SPeter Holmmain(void)
128*8a272653SPeter Holm{
129*8a272653SPeter Holm	pthread_t ptd;
130*8a272653SPeter Holm	mach_port_t port;
131*8a272653SPeter Holm	struct integer_message message;
132*8a272653SPeter Holm	int err, i;
133*8a272653SPeter Holm
134*8a272653SPeter Holm	/* Allocate a port */
135*8a272653SPeter Holm	err = mach_port_allocate(mach_task_self(),
136*8a272653SPeter Holm	    MACH_PORT_RIGHT_RECEIVE, &port);
137*8a272653SPeter Holm	if (err)
138*8a272653SPeter Holm		error(1, err, "mach_port_allocate");
139*8a272653SPeter Holm
140*8a272653SPeter Holm	err = mach_port_insert_right(mach_task_self(),
141*8a272653SPeter Holm	    port, port, MACH_MSG_TYPE_MAKE_SEND);
142*8a272653SPeter Holm
143*8a272653SPeter Holm	if (err)
144*8a272653SPeter Holm		error(10, err, "mach_port_insert_right");
145*8a272653SPeter Holm
146*8a272653SPeter Holm	if ((err = pthread_create(&ptd, NULL, client, &port)) != 0) {
147*8a272653SPeter Holm		errc(1, err, "pthread_create failed");
148*8a272653SPeter Holm	}
149*8a272653SPeter Holm
150*8a272653SPeter Holm	/* Fill the header fields : */
151*8a272653SPeter Holm	message.head.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_COPY_SEND, MACH_MSG_TYPE_MAKE_SEND);
152*8a272653SPeter Holm	message.head.msgh_size = sizeof( struct integer_message );
153*8a272653SPeter Holm	message.head.msgh_local_port = MACH_PORT_NULL;
154*8a272653SPeter Holm	message.head.msgh_remote_port = port;
155*8a272653SPeter Holm	message.head.msgh_id = 0;			/* Message id */
156*8a272653SPeter Holm	message.head.msgh_size = sizeof(message);	/* Message size */
157*8a272653SPeter Holm
158*8a272653SPeter Holm	/* Set the message type */
159*8a272653SPeter Holm	message.type.msgt_name = MACH_MSG_TYPE_INTEGER_32;
160*8a272653SPeter Holm	message.type.msgt_size = sizeof(message);
161*8a272653SPeter Holm	message.type.msgt_number = 1;
162*8a272653SPeter Holm	message.type.msgt_inline = TRUE;
163*8a272653SPeter Holm	message.type.msgt_longform = FALSE;
164*8a272653SPeter Holm	message.type.msgt_deallocate = FALSE;
165*8a272653SPeter Holm
166*8a272653SPeter Holm	for (i = 0; i < N; i++) {
167*8a272653SPeter Holm
168*8a272653SPeter Holm		message.inline_integer = i;
169*8a272653SPeter Holm
170*8a272653SPeter Holm		/* Send the message */
171*8a272653SPeter Holm		err = mach_msg(&message.head,	/* The header */
172*8a272653SPeter Holm		    MACH_SEND_MSG,		/* Flags */
173*8a272653SPeter Holm		    sizeof(message),		/* Send size */
174*8a272653SPeter Holm		    0,				/* Max receive Size */
175*8a272653SPeter Holm		    port,			/* Send port */
176*8a272653SPeter Holm		    MACH_MSG_TIMEOUT_NONE,	/* No timeout */
177*8a272653SPeter Holm		    MACH_PORT_NULL);		/* No notification */
178*8a272653SPeter Holm		if (err)
179*8a272653SPeter Holm			error(3, err, "client mach_msg");
180*8a272653SPeter Holm	}
181*8a272653SPeter Holm	pthread_join(ptd, NULL);
182*8a272653SPeter Holm
183*8a272653SPeter Holm	return (0);
184*8a272653SPeter Holm}
185