2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
23 * @APPLE_LICENSE_HEADER_END@
31 * Revision 1.1.1.1 1998/09/22 21:05:34 wsanchez
32 * Import of Mac OS X kernel (~semeria)
34 * Revision 1.1.1.1 1998/03/07 02:25:54 wsanchez
35 * Import of OSF Mach kernel (~mburg)
37 * Revision 1.1.12.1 1996/09/17 16:27:00 bruel
38 * fixed bzero prototype.
41 * Revision 1.1.2.4 1995/10/09 17:13:51 devrcs
42 * Merged in RT3_SHARED ETAP code.
43 * [1995/09/13 18:34:15 joe]
45 * Revision 1.1.2.3 1995/09/18 19:13:37 devrcs
46 * Merged in RT3_SHARED ETAP code.
47 * [1995/09/13 18:34:15 joe]
49 * Revision 1.1.2.2 1995/01/10 05:11:15 devrcs
50 * mk6 CR801 - merge up from nmk18b4 to nmk18b7
51 * patch up spinlock references ==> simplelock
52 * [1994/12/09 20:54:30 dwm]
54 * mk6 CR801 - new file for mk6_shared from cnmk_shared.
55 * [1994/12/01 21:11:49 dwm]
57 * Revision 1.1.2.1 1994/10/21 18:28:50 joe
58 * Initial ETAP submission
59 * [1994/10/20 19:31:33 joe]
66 * etap_pool.c contains the functions for maintenance
67 * of the start_data_pool. The start_data_pool is
68 * used by the ETAP package. Its primary
69 * objective is to provide start_data_nodes to complex
70 * locks so they can hold start information for read
71 * locks (since multiple readers can acquire a read
72 * lock). Each complex lock will maintain a linked
73 * list of these nodes.
75 * NOTES: The start_data_pool is used instead of zalloc to
76 * eliminate complex lock dependancies. If zalloc was used,
77 * then no complex locks could be used in zalloc code paths.
78 * This is both difficult and unrealistic, since zalloc
79 * allocates memory dynamically. Hence, this dependancy is
80 * eliminated with the use of the statically allocated
85 #include <kern/lock.h>
87 #include <kern/etap_pool.h>
88 #include <kern/sched_prim.h>
89 #include <kern/macro_help.h>
94 * Statically allocate the start data pool,
98 struct start_data_node sd_pool
[SD_POOL_ENTRIES
]; /* static buffer */
99 start_data_node_t sd_free_list
; /* pointer to free node list */
100 int sd_sleepers
; /* number of blocked threads */
102 simple_lock_data_t sd_pool_lock
;
106 * Interrupts must be disabled while the
107 * sd_pool_lock is taken.
110 #define pool_lock(s) \
113 simple_lock(&sd_pool_lock); \
116 #define pool_unlock(s) \
118 simple_unlock(&sd_pool_lock); \
124 * ROUTINE: init_start_data_pool
126 * FUNCTION: Initialize the start_data_pool:
127 * - create the free list chain for the max
129 * - initialize the sd_pool_lock
133 init_start_data_pool(void)
137 simple_lock_init(&sd_pool_lock
, ETAP_MISC_SD_POOL
);
140 * Establish free list pointer chain
143 for (x
=0; x
< SD_POOL_ENTRIES
-1; x
++)
144 sd_pool
[x
].next
= &sd_pool
[x
+1];
146 sd_pool
[SD_POOL_ENTRIES
-1].next
= SD_ENTRY_NULL
;
147 sd_free_list
= &sd_pool
[0];
152 * ROUTINE: get_start_data_node
154 * FUNCTION: Returns a free node from the start data pool
155 * to the caller. If none are available, the
156 * call will block, then try again.
160 get_start_data_node(void)
162 start_data_node_t avail_node
;
168 * If the pool does not have any nodes available,
169 * block until one becomes free.
172 while (sd_free_list
== SD_ENTRY_NULL
) {
175 assert_wait((event_t
) &sd_pool
[0], THREAD_UNINT
);
178 printf ("DEBUG-KERNEL: empty start_data_pool\n");
179 thread_block(THREAD_CONTINUE_NULL
);
185 avail_node
= sd_free_list
;
186 sd_free_list
= sd_free_list
->next
;
190 bzero ((char *) avail_node
, sizeof(struct start_data_node
));
191 avail_node
->next
= SD_ENTRY_NULL
;
197 * ROUTINE: free_start_data_node
199 * FUNCTION: Releases start data node back to the sd_pool,
200 * so that it can be used again.
204 free_start_data_node (
205 start_data_node_t node
)
207 boolean_t wakeup
= FALSE
;
210 if (node
== SD_ENTRY_NULL
)
215 node
->next
= sd_free_list
;
224 thread_wakeup((event_t
) &sd_pool
[0]);
227 #endif /* ETAP_LOCK_TRACE */