async.c (f30d5b307c694e03368ab55f2f96b0ca4131e775) async.c (766ccb9ed406c230d13c145def08ebea1b932982)
1/*
2 * async.c: Asynchronous function calls for boot performance
3 *
4 * (C) Copyright 2009 Intel Corporation
5 * Author: Arjan van de Ven <arjan@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License

--- 210 unchanged lines hidden (view full) ---

219 */
220async_cookie_t async_schedule(async_func_ptr *ptr, void *data)
221{
222 return __async_schedule(ptr, data, &async_running);
223}
224EXPORT_SYMBOL_GPL(async_schedule);
225
226/**
1/*
2 * async.c: Asynchronous function calls for boot performance
3 *
4 * (C) Copyright 2009 Intel Corporation
5 * Author: Arjan van de Ven <arjan@linux.intel.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License

--- 210 unchanged lines hidden (view full) ---

219 */
220async_cookie_t async_schedule(async_func_ptr *ptr, void *data)
221{
222 return __async_schedule(ptr, data, &async_running);
223}
224EXPORT_SYMBOL_GPL(async_schedule);
225
226/**
227 * async_schedule_special - schedule a function for asynchronous execution with a special running queue
227 * async_schedule_domain - schedule a function for asynchronous execution within a certain domain
228 * @ptr: function to execute asynchronously
229 * @data: data pointer to pass to the function
228 * @ptr: function to execute asynchronously
229 * @data: data pointer to pass to the function
230 * @running: list head to add to while running
230 * @running: running list for the domain
231 *
232 * Returns an async_cookie_t that may be used for checkpointing later.
231 *
232 * Returns an async_cookie_t that may be used for checkpointing later.
233 * @running may be used in the async_synchronize_*_special() functions
234 * to wait on a special running queue rather than on the global running
235 * queue.
233 * @running may be used in the async_synchronize_*_domain() functions
234 * to wait within a certain synchronization domain rather than globally.
235 * A synchronization domain is specified via the running queue @running to use.
236 * Note: This function may be called from atomic or non-atomic contexts.
237 */
236 * Note: This function may be called from atomic or non-atomic contexts.
237 */
238async_cookie_t async_schedule_special(async_func_ptr *ptr, void *data, struct list_head *running)
238async_cookie_t async_schedule_domain(async_func_ptr *ptr, void *data,
239 struct list_head *running)
239{
240 return __async_schedule(ptr, data, running);
241}
240{
241 return __async_schedule(ptr, data, running);
242}
242EXPORT_SYMBOL_GPL(async_schedule_special);
243EXPORT_SYMBOL_GPL(async_schedule_domain);
243
244/**
245 * async_synchronize_full - synchronize all asynchronous function calls
246 *
247 * This function waits until all asynchronous function calls have been done.
248 */
249void async_synchronize_full(void)
250{
251 do {
252 async_synchronize_cookie(next_cookie);
253 } while (!list_empty(&async_running) || !list_empty(&async_pending));
254}
255EXPORT_SYMBOL_GPL(async_synchronize_full);
256
257/**
244
245/**
246 * async_synchronize_full - synchronize all asynchronous function calls
247 *
248 * This function waits until all asynchronous function calls have been done.
249 */
250void async_synchronize_full(void)
251{
252 do {
253 async_synchronize_cookie(next_cookie);
254 } while (!list_empty(&async_running) || !list_empty(&async_pending));
255}
256EXPORT_SYMBOL_GPL(async_synchronize_full);
257
258/**
258 * async_synchronize_full_special - synchronize all asynchronous function calls for a running list
259 * async_synchronize_full_domain - synchronize all asynchronous function within a certain domain
259 * @list: running list to synchronize on
260 *
260 * @list: running list to synchronize on
261 *
261 * This function waits until all asynchronous function calls for the running
262 * list @list have been done.
262 * This function waits until all asynchronous function calls for the
263 * synchronization domain specified by the running list @list have been done.
263 */
264 */
264void async_synchronize_full_special(struct list_head *list)
265void async_synchronize_full_domain(struct list_head *list)
265{
266{
266 async_synchronize_cookie_special(next_cookie, list);
267 async_synchronize_cookie_domain(next_cookie, list);
267}
268}
268EXPORT_SYMBOL_GPL(async_synchronize_full_special);
269EXPORT_SYMBOL_GPL(async_synchronize_full_domain);
269
270/**
270
271/**
271 * async_synchronize_cookie_special - synchronize asynchronous function calls on a running list with cookie checkpointing
272 * async_synchronize_cookie_domain - synchronize asynchronous function calls within a certain domain with cookie checkpointing
272 * @cookie: async_cookie_t to use as checkpoint
273 * @running: running list to synchronize on
274 *
273 * @cookie: async_cookie_t to use as checkpoint
274 * @running: running list to synchronize on
275 *
275 * This function waits until all asynchronous function calls for the running
276 * list @list submitted prior to @cookie have been done.
276 * This function waits until all asynchronous function calls for the
277 * synchronization domain specified by the running list @list submitted
278 * prior to @cookie have been done.
277 */
279 */
278void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *running)
280void async_synchronize_cookie_domain(async_cookie_t cookie,
281 struct list_head *running)
279{
280 ktime_t starttime, delta, endtime;
281
282 if (initcall_debug && system_state == SYSTEM_BOOTING) {
283 printk("async_waiting @ %i\n", task_pid_nr(current));
284 starttime = ktime_get();
285 }
286
287 wait_event(async_done, lowest_in_progress(running) >= cookie);
288
289 if (initcall_debug && system_state == SYSTEM_BOOTING) {
290 endtime = ktime_get();
291 delta = ktime_sub(endtime, starttime);
292
293 printk("async_continuing @ %i after %lli usec\n",
294 task_pid_nr(current),
295 (long long)ktime_to_ns(delta) >> 10);
296 }
297}
282{
283 ktime_t starttime, delta, endtime;
284
285 if (initcall_debug && system_state == SYSTEM_BOOTING) {
286 printk("async_waiting @ %i\n", task_pid_nr(current));
287 starttime = ktime_get();
288 }
289
290 wait_event(async_done, lowest_in_progress(running) >= cookie);
291
292 if (initcall_debug && system_state == SYSTEM_BOOTING) {
293 endtime = ktime_get();
294 delta = ktime_sub(endtime, starttime);
295
296 printk("async_continuing @ %i after %lli usec\n",
297 task_pid_nr(current),
298 (long long)ktime_to_ns(delta) >> 10);
299 }
300}
298EXPORT_SYMBOL_GPL(async_synchronize_cookie_special);
301EXPORT_SYMBOL_GPL(async_synchronize_cookie_domain);
299
300/**
301 * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing
302 * @cookie: async_cookie_t to use as checkpoint
303 *
304 * This function waits until all asynchronous function calls prior to @cookie
305 * have been done.
306 */
307void async_synchronize_cookie(async_cookie_t cookie)
308{
302
303/**
304 * async_synchronize_cookie - synchronize asynchronous function calls with cookie checkpointing
305 * @cookie: async_cookie_t to use as checkpoint
306 *
307 * This function waits until all asynchronous function calls prior to @cookie
308 * have been done.
309 */
310void async_synchronize_cookie(async_cookie_t cookie)
311{
309 async_synchronize_cookie_special(cookie, &async_running);
312 async_synchronize_cookie_domain(cookie, &async_running);
310}
311EXPORT_SYMBOL_GPL(async_synchronize_cookie);
312
313
314static int async_thread(void *unused)
315{
316 DECLARE_WAITQUEUE(wq, current);
317 add_wait_queue(&async_new, &wq);

--- 87 unchanged lines hidden ---
313}
314EXPORT_SYMBOL_GPL(async_synchronize_cookie);
315
316
317static int async_thread(void *unused)
318{
319 DECLARE_WAITQUEUE(wq, current);
320 add_wait_queue(&async_new, &wq);

--- 87 unchanged lines hidden ---