2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
28 * Revision 1.1.1.1 1998/09/22 21:05:34 wsanchez
29 * Import of Mac OS X kernel (~semeria)
31 * Revision 1.1.1.1 1998/03/07 02:25:54 wsanchez
32 * Import of OSF Mach kernel (~mburg)
34 * Revision 1.1.12.1 1996/09/17 16:27:00 bruel
35 * fixed bzero prototype.
38 * Revision 1.1.2.4 1995/10/09 17:13:51 devrcs
39 * Merged in RT3_SHARED ETAP code.
40 * [1995/09/13 18:34:15 joe]
42 * Revision 1.1.2.3 1995/09/18 19:13:37 devrcs
43 * Merged in RT3_SHARED ETAP code.
44 * [1995/09/13 18:34:15 joe]
46 * Revision 1.1.2.2 1995/01/10 05:11:15 devrcs
47 * mk6 CR801 - merge up from nmk18b4 to nmk18b7
48 * patch up spinlock references ==> simplelock
49 * [1994/12/09 20:54:30 dwm]
51 * mk6 CR801 - new file for mk6_shared from cnmk_shared.
52 * [1994/12/01 21:11:49 dwm]
54 * Revision 1.1.2.1 1994/10/21 18:28:50 joe
55 * Initial ETAP submission
56 * [1994/10/20 19:31:33 joe]
63 * etap_pool.c contains the functions for maintenance
64 * of the start_data_pool. The start_data_pool is
65 * used by the ETAP package. Its primary
66 * objective is to provide start_data_nodes to complex
67 * locks so they can hold start information for read
68 * locks (since multiple readers can acquire a read
69 * lock). Each complex lock will maintain a linked
70 * list of these nodes.
72 * NOTES: The start_data_pool is used instead of zalloc to
73 * eliminate complex lock dependancies. If zalloc was used,
74 * then no complex locks could be used in zalloc code paths.
75 * This is both difficult and unrealistic, since zalloc
76 * allocates memory dynamically. Hence, this dependancy is
77 * eliminated with the use of the statically allocated
82 #include <kern/lock.h>
84 #include <kern/etap_pool.h>
85 #include <kern/sched_prim.h>
86 #include <kern/macro_help.h>
91 * Statically allocate the start data pool,
95 struct start_data_node sd_pool
[SD_POOL_ENTRIES
]; /* static buffer */
96 start_data_node_t sd_free_list
; /* pointer to free node list */
97 int sd_sleepers
; /* number of blocked threads */
99 simple_lock_data_t sd_pool_lock
;
103 * Interrupts must be disabled while the
104 * sd_pool_lock is taken.
107 #define pool_lock(s) \
110 simple_lock(&sd_pool_lock); \
113 #define pool_unlock(s) \
115 simple_unlock(&sd_pool_lock); \
121 * ROUTINE: init_start_data_pool
123 * FUNCTION: Initialize the start_data_pool:
124 * - create the free list chain for the max
126 * - initialize the sd_pool_lock
130 init_start_data_pool(void)
134 simple_lock_init(&sd_pool_lock
, ETAP_MISC_SD_POOL
);
137 * Establish free list pointer chain
140 for (x
=0; x
< SD_POOL_ENTRIES
-1; x
++)
141 sd_pool
[x
].next
= &sd_pool
[x
+1];
143 sd_pool
[SD_POOL_ENTRIES
-1].next
= SD_ENTRY_NULL
;
144 sd_free_list
= &sd_pool
[0];
149 * ROUTINE: get_start_data_node
151 * FUNCTION: Returns a free node from the start data pool
152 * to the caller. If none are available, the
153 * call will block, then try again.
157 get_start_data_node(void)
159 start_data_node_t avail_node
;
165 * If the pool does not have any nodes available,
166 * block until one becomes free.
169 while (sd_free_list
== SD_ENTRY_NULL
) {
172 assert_wait((event_t
) &sd_pool
[0], THREAD_UNINT
);
175 printf ("DEBUG-KERNEL: empty start_data_pool\n");
176 thread_block((void (*)(void)) 0);
182 avail_node
= sd_free_list
;
183 sd_free_list
= sd_free_list
->next
;
187 bzero ((char *) avail_node
, sizeof(struct start_data_node
));
188 avail_node
->next
= SD_ENTRY_NULL
;
194 * ROUTINE: free_start_data_node
196 * FUNCTION: Releases start data node back to the sd_pool,
197 * so that it can be used again.
201 free_start_data_node (
202 start_data_node_t node
)
204 boolean_t wakeup
= FALSE
;
207 if (node
== SD_ENTRY_NULL
)
212 node
->next
= sd_free_list
;
221 thread_wakeup((event_t
) &sd_pool
[0]);
224 #endif /* ETAP_LOCK_TRACE */