xref: /titanic_52/usr/src/lib/libtnfctl/prb_shmem.c (revision fd845fc0cb4fbc8e85f974e2e4eaacca1cc26e81)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright (c) 1994, by Sun Microsytems, Inc.
24  */
25 
26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
27 
28 /*
29  * Interfaces to allocate, control, and free a shared memory lock
30  * XXXX Could we use a semaphore or a shared memory condition variable
31  * instead ?
32  */
33 
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <errno.h>
37 #include <stdlib.h>
38 #include <sys/mman.h>
39 #include <sys/types.h>
40 
41 #include "prb_proc_int.h"
42 #include "dbg.h"
43 
44 static boolean_t getspin(volatile shmem_msg_t *smp);
45 
46 /*
47  * prb_shmem_init() - Allocates and initializes the shared memory region
48  */
49 prb_status_t
50 prb_shmem_init(volatile shmem_msg_t **ret_val)
51 {
52 	int		shmem_fd;
53 	volatile	shmem_msg_t *smp;
54 
55 	DBG_TNF_PROBE_0(prb_shmem_init_1, "libtnfctl", "sunw%verbosity 2");
56 
57 	shmem_fd = open("/dev/zero", O_RDWR);
58 	if (shmem_fd == -1) {
59 		DBG((void) fprintf(stderr, "couldn't open \"/dev/zero\""));
60 		return (prb_status_map(errno));
61 	}
62 	/*LINTED pointer cast may result in improper alignment*/
63 	smp = (shmem_msg_t *) mmap(0, sizeof (struct shmem_msg),
64 			PROT_READ | PROT_WRITE, MAP_SHARED,
65 			shmem_fd, 0);
66 	if (smp == (struct shmem_msg *) - 1) {
67 		DBG((void) fprintf(stderr, "couldn't mmap \"/dev/zero\""));
68 		return (prb_status_map(errno));
69 	}
70 	(void) close(shmem_fd);
71 
72 	/* sets the shared memory region to cause waiting */
73 	smp->spin = B_TRUE;
74 
75 	*ret_val = smp;
76 
77 	return (PRB_STATUS_OK);
78 }
79 
80 /*
81  * prb_shmem_wait() - spins until the shared memory flag is cleared
82  */
83 static boolean_t
84 getspin(volatile shmem_msg_t *smp)
85 {
86 	return (smp->spin);
87 }
88 
89 prb_status_t
90 prb_shmem_wait(volatile shmem_msg_t *smp)
91 {
92 	DBG_TNF_PROBE_0(prb_shmem_wait_start, "libtnfctl",
93 		"sunw%verbosity 2; start prb_shmem_wait");
94 
95 	while (getspin(smp));
96 
97 	DBG_TNF_PROBE_0(prb_shmem_wait_end, "libtnfctl",
98 		"sunw%verbosity 2; end prb_shmem_wait");
99 
100 	return (PRB_STATUS_OK);
101 
102 }
103 
104 
105 /*
106  * prb_shmem_clear() - clears the shared memory flag and allows waiters to
107  * proceed.
108  */
109 prb_status_t
110 prb_shmem_clear(volatile shmem_msg_t *smp)
111 {
112 	DBG_TNF_PROBE_0(prb_shmem_clear_1, "libtnfctl", "sunw%verbosity 2");
113 
114 	smp->spin = B_FALSE;
115 
116 	return (PRB_STATUS_OK);
117 }
118 
119 /*
120  * prb_shmem_free() - Unmaps the shared memory region.
121  */
122 prb_status_t
123 prb_shmem_free(volatile shmem_msg_t *smp)
124 {
125 	DBG_TNF_PROBE_0(prb_shmem_free_1, "libtnfctl", "sunw%verbosity 2");
126 
127 	if (munmap((caddr_t) smp, sizeof (struct shmem_msg)) != 0) {
128 		DBG((void) fprintf(stderr, "couldn't munmap shared memory\n"));
129 		return (prb_status_map(errno));
130 	}
131 
132 	return (PRB_STATUS_OK);
133 }
134