1/* 2 * sync.c 3 * 4 * DSP-BIOS Bridge driver support functions for TI OMAP processors. 5 * 6 * Synchronization services. 7 * 8 * Copyright (C) 2005-2006 Texas Instruments, Inc. 9 * 10 * This package is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 * 14 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 16 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 17 */ 18 19/* ----------------------------------- Host OS */ 20#include <dspbridge/host_os.h> 21 22/* ----------------------------------- This */ 23#include <dspbridge/sync.h> 24 25DEFINE_SPINLOCK(sync_lock); 26 27/** 28 * sync_set_event() - set or signal and specified event 29 * @event: Event to be set.. 30 * 31 * set the @event, if there is an thread waiting for the event 32 * it will be waken up, this function only wakes one thread. 33 */ 34 35void sync_set_event(struct sync_object *event) 36{ 37 spin_lock_bh(&sync_lock); 38 complete(&event->comp); 39 if (event->multi_comp) 40 complete(event->multi_comp); 41 spin_unlock_bh(&sync_lock); 42} 43 44/** 45 * sync_wait_on_multiple_events() - waits for multiple events to be set. 46 * @events: Array of events to wait for them. 47 * @count: number of elements of the array. 48 * @timeout timeout on waiting for the evetns. 49 * @pu_index index of the event set. 50 * 51 * This functios will wait until any of the array element is set or until 52 * timeout. In case of success the function will return 0 and 53 * @pu_index will store the index of the array element set or in case 54 * of timeout the function will return -ETIME or in case of 55 * interrupting by a signal it will return -EPERM. 56 */ 57 58int sync_wait_on_multiple_events(struct sync_object **events, 59 unsigned count, unsigned timeout, 60 unsigned *index) 61{ 62 unsigned i; 63 int status = -EPERM; 64 struct completion m_comp; 65 66 init_completion(&m_comp); 67 68 if (SYNC_INFINITE == timeout) 69 timeout = MAX_SCHEDULE_TIMEOUT; 70 71 spin_lock_bh(&sync_lock); 72 for (i = 0; i < count; i++) { 73 if (completion_done(&events[i]->comp)) { 74 INIT_COMPLETION(events[i]->comp); 75 *index = i; 76 spin_unlock_bh(&sync_lock); 77 status = 0; 78 goto func_end; 79 } 80 } 81 82 for (i = 0; i < count; i++) 83 events[i]->multi_comp = &m_comp; 84 85 spin_unlock_bh(&sync_lock); 86 87 if (!wait_for_completion_interruptible_timeout(&m_comp, 88 msecs_to_jiffies(timeout))) 89 status = -ETIME; 90 91 spin_lock_bh(&sync_lock); 92 for (i = 0; i < count; i++) { 93 if (completion_done(&events[i]->comp)) { 94 INIT_COMPLETION(events[i]->comp); 95 *index = i; 96 status = 0; 97 } 98 events[i]->multi_comp = NULL; 99 } 100 spin_unlock_bh(&sync_lock); 101func_end: 102 return status; 103} 104