OpenCores
URL https://opencores.org/ocsvn/funbase_ip_library/funbase_ip_library/trunk

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.swp.api/] [openmcapi/] [1.0/] [libmcapi/] [mcapi/] [mcapi_wait_any.c] - Blame information for rev 145

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 145 lanttu
/*
2
 * Copyright (c) 2010, Mentor Graphics Corporation
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * 1. Redistributions of source code must retain the above copyright notice,
9
 *    this list of conditions and the following disclaimer.
10
 * 2. Redistributions in binary form must reproduce the above copyright notice,
11
 *    this list of conditions and the following disclaimer in the documentation
12
 *    and/or other materials provided with the distribution.
13
 * 3. Neither the name of the <ORGANIZATION> nor the names of its contributors
14
 *    may be used to endorse or promote products derived from this software
15
 *    without specific prior written permission.
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 * POSSIBILITY OF SUCH DAMAGE.
28
 */
29
 
30
 
31
 
32
#include <openmcapi.h>
33
 
34
/*************************************************************************
35
*
36
*   FUNCTION
37
*
38
*       mcapi_wait_any
39
*
40
*   DESCRIPTION
41
*
42
*       Blocking API routine that waits for any non-blocking operation in
43
*       a list of operations to complete.  The routine returns if any of
44
*       the specific operations has completed or been canceled, or if the
45
*       call to mcapi_wait_any times out on completion of the respective
46
*       operation.
47
*
48
*   INPUTS
49
*
50
*       number                  The number of non-blocking operations in
51
*                               the *requests array.
52
*       **requests              A pointer to an array of number request
53
*                               structures, each filled in by the specific
54
*                               operation waiting for completion.
55
*       *size                   A pointer to memory that will be filled in
56
*                               with the number of bytes sent/received if
57
*                               the operation in question is a send or
58
*                               receive operation.
59
*       timeout                 The number milliseconds to wait for
60
*                               completion of the respective operation
61
*                               before returning from mcapi_wait_any().
62
*                               A value of MCAPI_TIMEOUT_INFINITE indicates no
63
*                               timeout.
64
*       *mcapi_status           A pointer to memory that will be filled in
65
*                               with the status of the call.
66
*
67
*   OUTPUTS
68
*
69
*       The index into the requests array indicating which operation
70
*       completed.
71
*
72
*************************************************************************/
73
mcapi_int_t mcapi_wait_any(size_t number, mcapi_request_t **requests,
74
                           size_t *size, mcapi_timeout_t timeout,
75
                           mcapi_status_t *mcapi_status)
76
{
77
    int                 i, j;
78
    MCAPI_GLOBAL_DATA   *node_data;
79
    mcapi_int_t         req_idx = 0;
80
    MCAPI_COND_STRUCT   condition;
81
    mcapi_request_t     *req_ptr;
82
    mcapi_request_t     *req_list[MCAPI_FREE_REQUEST_COUNT];
83
 
84
    /* Validate the mcapi_status input parameter. */
85
    if (mcapi_status)
86
    {
87
        /* Validate the input parameters. */
88
        if ( (number > 0) && (size) && (requests) )
89
        {
90
            /* Check if any of the requests are already complete. */
91
            for (i = 0; i < number; i ++)
92
            {
93
                /* Ensure the request is valid. */
94
                if (requests[i])
95
                {
96
                    /* Check this request. */
97
                    mcapi_test(requests[i], size, mcapi_status);
98
 
99
                    /* If the request structure is not valid. */
100
                    if (*mcapi_status == MCAPI_ERR_REQUEST_INVALID)
101
                    {
102
                        break;
103
                    }
104
 
105
                    /* If the request has completed or been canceled. */
106
                    else if (*mcapi_status != MCAPI_PENDING)
107
                    {
108
                        req_idx = i;
109
                        break;
110
                    }
111
                }
112
 
113
                /* The request is either invalid or null. */
114
                else
115
                {
116
                    *mcapi_status = MCAPI_ERR_REQUEST_INVALID;
117
                    break;
118
                }
119
            }
120
 
121
            /* If none of the requests has completed. */
122
            if ( (*mcapi_status != MCAPI_ERR_REQUEST_INVALID) &&
123
                 (i == number) )
124
            {
125
                /* Initialize the status to indicate that the operation
126
                 * timed out.
127
                 */
128
                *mcapi_status = MCAPI_TIMEOUT;
129
 
130
                /* Get the lock. */
131
                mcapi_lock_node_data();
132
 
133
                /* Get a pointer to the global node list. */
134
                node_data = mcapi_get_node_data();
135
 
136
                /* Initialize the OS specific conditions for waking this
137
                 * task.
138
                 */
139
                MCAPI_Init_Condition(&condition);
140
 
141
                /* Add each request structure to the list. */
142
                for (i = 0; i < number; i ++)
143
                {
144
                    /* Get a new request structure. */
145
                    req_ptr = mcapi_get_free_request_struct();
146
 
147
                    if (req_ptr)
148
                    {
149
                        /* Replicate the target request structure. */
150
                        memcpy(req_ptr, requests[i], sizeof(mcapi_request_t));
151
 
152
                        /* Save a pointer to this structure since it will
153
                         * get removed from the global list if the request
154
                         * completes successfully.
155
                         */
156
                        req_list[i] = req_ptr;
157
 
158
                        /* Set the OS specific condition for identifying this task
159
                         * for resume.
160
                         */
161
                        MCAPI_Set_Condition(req_ptr, &condition);
162
 
163
                        /* Add the request to the queue of pending requests. */
164
                        mcapi_enqueue(&node_data->mcapi_local_req_queue, req_ptr);
165
                    }
166
 
167
                    /* There are no request structures available. */
168
                    else
169
                    {
170
                        *mcapi_status = MCAPI_ERR_REQUEST_LIMIT;
171
 
172
                        /* Remove any requests that were put on the queue.  If all
173
                         * requests cannot be serviced, then no requests get
174
                         * serviced.
175
                         */
176
                        for (j = 0; j < i; j ++)
177
                        {
178
                            /* Remove this entry. */
179
                            mcapi_remove(&node_data->mcapi_local_req_queue, req_list[j]);
180
 
181
                            /* Clear the OS specific condition. */
182
                            MCAPI_Clear_Condition(req_list[j]);
183
 
184
                            /* Return this request structure to the free list. */
185
                            mcapi_release_request_struct(req_list[j]);
186
                        }
187
 
188
                        break;
189
                    }
190
                }
191
 
192
                /* If all requests can be serviced with this call. */
193
                if (*mcapi_status != MCAPI_ERR_REQUEST_LIMIT)
194
                {
195
                    /* Suspend this task, passing in MCAPI_NULL as the
196
                     * request structure since all request structures have
197
                     * been added to the list.
198
                     */
199
                    MCAPI_Suspend_Task(node_data, MCAPI_NULL, &condition, timeout);
200
 
201
                    /* Initialize the index so we know when the first completed
202
                     * request has been found.
203
                     */
204
                    req_idx = -1;
205
 
206
                    /* Remove each request structure from the list of waiting tasks. */
207
                    for (i = 0; i < number; i ++)
208
                    {
209
                        /* Clear the OS specific condition for resuming the thread. */
210
                        MCAPI_Clear_Condition(req_list[i]);
211
 
212
                        /* If the wait operation timed out before the operation being
213
                         * tested could finish.
214
                         */
215
                        if (req_list[i]->mcapi_status == MCAPI_PENDING)
216
                        {
217
                            /* Remove the request from the list. */
218
                            mcapi_remove(&node_data->mcapi_local_req_queue, req_list[i]);
219
                        }
220
 
221
                        /* Remove the request from the queue of pending requests. */
222
                        mcapi_remove(&node_data->mcapi_local_req_queue, req_list[i]);
223
 
224
                        /* If a request structure has not been found already
225
                         * and the status is not "pending".
226
                         */
227
                        if ( (req_idx == -1) &&
228
                             (req_list[i]->mcapi_status != MCAPI_PENDING) )
229
                        {
230
                            /* Return the status of the request. */
231
                            *mcapi_status = req_list[i]->mcapi_status;
232
 
233
                            /* Set the status of the original request structure
234
                             * in case this request was not on the global list.
235
                             */
236
                            requests[i]->mcapi_status = *mcapi_status;
237
 
238
                            /* Return the index into the request structure. */
239
                            req_idx = i;
240
 
241
                            /* If the status is successful, and the request was
242
                             * to send or receive data, return the number of
243
                             * bytes sent or received.
244
                             */
245
                            if ( (*mcapi_status == MCAPI_SUCCESS) &&
246
                                 ((req_list[i]->mcapi_type == MCAPI_REQ_TX_FIN) ||
247
                                  (req_list[i]->mcapi_type == MCAPI_REQ_RX_FIN)) )
248
                            {
249
                                *size = req_list[i]->mcapi_byte_count;
250
                            }
251
                        }
252
 
253
                        /* Indicate that this request structure can be reused. */
254
                        mcapi_release_request_struct(req_list[i]);
255
                    }
256
 
257
                    /* If no matching index was found, return MCAPI_NULL. */
258
                    if (req_idx == -1)
259
                    {
260
                        req_idx = 0;
261
                    }
262
                }
263
 
264
                /* Release the lock. */
265
                mcapi_unlock_node_data();
266
            }
267
        }
268
 
269
        /* The request pointer or size value is not valid. */
270
        else
271
        {
272
            *mcapi_status = MCAPI_ERR_PARAMETER;
273
        }
274
    }
275
 
276
    return (req_idx);
277
 
278
}
279
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.