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
|
/*
* sync.c
*
* DSP-BIOS Bridge driver support functions for TI OMAP processors.
*
* Synchronization services.
*
* Copyright (C) 2005-2006 Texas Instruments, Inc.
*
* This package is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* ----------------------------------- Host OS */
#include <dspbridge/host_os.h>
/* ----------------------------------- This */
#include <dspbridge/sync.h>
#include <dspbridge/ntfy.h>
DEFINE_SPINLOCK(sync_lock);
/**
* sync_set_event() - set or signal and specified event
* @event: Event to be set..
*
* set the @event, if there is an thread waiting for the event
* it will be waken up, this function only wakes one thread.
*/
void sync_set_event(struct sync_object *event)
{
spin_lock_bh(&sync_lock);
complete(&event->comp);
if (event->multi_comp)
complete(event->multi_comp);
spin_unlock_bh(&sync_lock);
}
/**
* sync_wait_on_multiple_events() - waits for multiple events to be set.
* @events: Array of events to wait for them.
* @count: number of elements of the array.
* @timeout timeout on waiting for the evetns.
* @pu_index index of the event set.
*
* This functios will wait until any of the array element is set or until
* timeout. In case of success the function will return 0 and
* @pu_index will store the index of the array element set or in case
* of timeout the function will return -ETIME or in case of
* interrupting by a signal it will return -EPERM.
*/
int sync_wait_on_multiple_events(struct sync_object **events,
unsigned count, unsigned timeout,
unsigned *index)
{
unsigned i;
int status = -EPERM;
struct completion m_comp;
init_completion(&m_comp);
if (SYNC_INFINITE == timeout)
timeout = MAX_SCHEDULE_TIMEOUT;
spin_lock_bh(&sync_lock);
for (i = 0; i < count; i++) {
if (completion_done(&events[i]->comp)) {
INIT_COMPLETION(events[i]->comp);
*index = i;
spin_unlock_bh(&sync_lock);
status = 0;
goto func_end;
}
}
for (i = 0; i < count; i++)
events[i]->multi_comp = &m_comp;
spin_unlock_bh(&sync_lock);
if (!wait_for_completion_interruptible_timeout(&m_comp,
msecs_to_jiffies(timeout)))
status = -ETIME;
spin_lock_bh(&sync_lock);
for (i = 0; i < count; i++) {
if (completion_done(&events[i]->comp)) {
INIT_COMPLETION(events[i]->comp);
*index = i;
status = 0;
}
events[i]->multi_comp = NULL;
}
spin_unlock_bh(&sync_lock);
func_end:
return status;
}
/**
* dsp_notifier_event() - callback function to nofity events
* @this: pointer to itself struct notifier_block
* @event: event to be notified.
* @data: Currently not used.
*
*/
int dsp_notifier_event(struct notifier_block *this, unsigned long event,
void *data)
{
struct ntfy_event *ne = container_of(this, struct ntfy_event,
noti_block);
if (ne->event & event)
sync_set_event(&ne->sync_obj);
return NOTIFY_OK;
}
|