summaryrefslogtreecommitdiff
path: root/include/mach/profil.h
blob: 0eb4ce474368cbec6b56e5d2860cfa21899700f6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
/* 
 * Mach Operating System
 * Copyright (c) 1991,1990,1989 Carnegie Mellon University
 * All Rights Reserved.
 * 
 * Permission to use, copy, modify and distribute this software and its
 * documentation is hereby granted, provided that both the copyright
 * notice and this permission notice appear in all copies of the
 * software, derivative works or modified versions, and any portions
 * thereof, and that both notices appear in supporting documentation.
 * 
 * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
 * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
 * 
 * Carnegie Mellon requests users of this software to return to
 * 
 *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
 *  School of Computer Science
 *  Carnegie Mellon University
 *  Pittsburgh PA 15213-3890
 * 
 * any improvements or extensions that they make and grant Carnegie Mellon
 * the rights to redistribute these changes.
 */

/*
 * Copyright 1991 by Open Software Foundation,
 * Grenoble, FRANCE
 *
 * 		All Rights Reserved
 * 
 *   Permission to use, copy, modify, and distribute this software and
 * its documentation for any purpose and without fee is hereby granted,
 * provided that the above copyright notice appears in all copies and
 * that both the copyright notice and this permission notice appear in
 * supporting documentation, and that the name of OSF or Open Software
 * Foundation not be used in advertising or publicity pertaining to
 * distribution of the software without specific, written prior
 * permission.
 * 
 *   OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
 * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
 * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
 * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */


#ifndef _MACH_PROFIL_H_
#define _MACH_PROFIL_H_

#include <mach/boolean.h>
#include <ipc/ipc_object.h>
#include <vm/vm_kern.h> 


#define	NB_PROF_BUFFER		2	/* number of buffers servicing a 
					 * profiled thread */
#define	SIZE_PROF_BUFFER	100	/* size of a profil buffer (in int) 
					 * This values is also defined in
					 * the server (ugly), be careful ! */


struct	prof_data {
	ipc_object_t	prof_port;	/* where to send a full buffer */

	struct buffer {
	    int	*p_zone;		/* points to the actual storage area */
	    int			p_index;/* next slot to be filled */
	    boolean_t		p_full;	/* is the current buffer full ? */ 
	} prof_area[NB_PROF_BUFFER];

	int		prof_index;	/* index of the buffer structure
					 *   currently in use */

};
typedef struct prof_data	*prof_data_t;
#define NULLPBUF ((prof_data_t) 0)
typedef struct buffer		*buffer_t;

/* Macros */

#define	set_pbuf_nb(pbuf, nb) \
         (((nb) >= 0 && (nb) < NB_PROF_BUFFER) \
	 ? (pbuf)->prof_index = (nb), 1 \
	 : 0)


#define	get_pbuf_nb(pbuf) \
	(pbuf)->prof_index


extern vm_map_t kernel_map; 

#define dealloc_pbuf_area(pbuf) \
          { \
	  register int i; \
				   \
	    for(i=0; i < NB_PROF_BUFFER ; i++)  \
	      kmem_free(kernel_map, \
                        (vm_offset_t) (pbuf)->prof_area[i].p_zone, \
                        SIZE_PROF_BUFFER*sizeof(int)); \
            kmem_free(kernel_map, \
                          (vm_offset_t)(pbuf), \
                          sizeof(struct prof_data)); \
          }
	

#define alloc_pbuf_area(pbuf, vmpbuf) \
      (vmpbuf) = (vm_offset_t) 0; \
      if (kmem_alloc(kernel_map, &(vmpbuf) , sizeof(struct prof_data)) == \
                                           KERN_SUCCESS) { \
	   register int i; \
	   register boolean_t end; \
				   \
	   (pbuf) = (prof_data_t) (vmpbuf); \
	   for(i=0, end=FALSE; i < NB_PROF_BUFFER && end == FALSE; i++) { \
              (vmpbuf) = (vm_offset_t) 0; \
	      if (kmem_alloc(kernel_map,&(vmpbuf),SIZE_PROF_BUFFER*sizeof(int)) == KERN_SUCCESS) { \
		 (pbuf)->prof_area[i].p_zone = (int *) (vmpbuf); \
		 (pbuf)->prof_area[i].p_full = FALSE; \
	      } \
	      else { \
	         (pbuf) = NULLPBUF; \
		 end = TRUE; \
	      } \
       	    } \
	} \
	else \
	  (pbuf) = NULLPBUF; 
	


/* MACRO set_pbuf_value 
** 
** enters the value 'val' in the buffer 'pbuf' and returns the following
** indications:     0: means that a fatal error occured: the buffer was full
**                       (it hasn't been sent yet)
**                  1: means that a value has been inserted successfully
**		    2: means that we'v just entered the last value causing 
**			the current buffer to be full.(must switch to 
** 			another buffer and signal the sender to send it)
*/ 
	  
#define set_pbuf_value(pbuf, val) \
	 { \
	  register buffer_t a = &((pbuf)->prof_area[(pbuf)->prof_index]); \
	  register int i = a->p_index++; \
	  register boolean_t f = a->p_full; \
			  \
	  if (f == TRUE ) \
             *(val) = 0; \
	  else { \
	    a->p_zone[i] = *(val); \
	    if (i == SIZE_PROF_BUFFER-1) { \
               a->p_full = TRUE; \
               *(val) = 2; \
            } \
            else \
		*(val) = 1; \
          } \
	}

         
#define	reset_pbuf_area(pbuf) \
	{ \
	 register int *i = &((pbuf)->prof_index); \
					      \
	 *i = (*i == NB_PROF_BUFFER-1) ? 0 : ++(*i); \
	 (pbuf)->prof_area[*i].p_index = 0; \
	}


/**************************************************************/
/* Structure, elements used for queuing operations on buffers */
/**************************************************************/

#define	thread_t int *
/*
** This must be done in order to avoid a circular inclusion 
** with file kern/thread.h . 
** When using this data structure, one must cast the actual 
** type, this is (int *) or (thread_t)
*/

struct buf_to_send {
   	queue_chain_t list;
	thread_t thread;
        int number;         /* the number of the buffer to be sent */
	char wakeme;	    /* do wakeup when buffer has been sent */
        }	;

#undef	thread_t



typedef struct buf_to_send *buf_to_send_t;

#define	NULLBTS		((buf_to_send_t) 0)

/*
** Global variable: the head of the queue of buffers to send 
** It is a queue with locks (uses macros from queue.h) and it
** is shared by hardclock() and the sender_thread() 
*/

mpqueue_head_t prof_queue; 

#endif	/* _MACH_PROF_H_ */