1 /*- 2 * Copyright (c) 2010 Isilon Systems, Inc. 3 * Copyright (c) 2010 iX Systems, Inc. 4 * Copyright (c) 2010 Panasas, Inc. 5 * Copyright (c) 2013, 2014 Mellanox Technologies, Ltd. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice unmodified, this list of conditions, and the following 13 * disclaimer. 14 * 2. Redistributions in binary form must reproduce the above copyright 15 * notice, this list of conditions and the following disclaimer in the 16 * documentation and/or other materials provided with the distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 #ifndef _LINUXKPI_LINUX_COMPLETION_H_ 30 #define _LINUXKPI_LINUX_COMPLETION_H_ 31 32 #include "los_sys.h" 33 34 #ifdef __cplusplus 35 #if __cplusplus 36 extern "C" { 37 #endif /* __cplusplus */ 38 #endif /* __cplusplus */ 39 40 enum CompletionState { 41 COMPLETION_ONE, 42 COMPLETION_ALL 43 }; 44 45 #define COMPLETION_EVT 0x1 46 47 typedef struct completion { 48 LOS_DL_LIST comList; 49 UINT32 comCount; 50 enum CompletionState state; 51 } completion_t; 52 53 #define init_completion(x) \ 54 linux_init_completion(x) 55 56 /* This inline function should be used to reinitialize a completion structure so it can 57 * be reused. This is especially important after complete_all() is used. 58 */ 59 #define reinit_completion(x) \ 60 do { (x)->comCount = 0; } while (0) 61 62 #define complete(x) \ 63 linux_complete(x) 64 65 #define wait_for_completion(x) \ 66 linux_wait_for_completion(x) 67 68 #define wait_for_completion_timeout(x, timeout) \ 69 linux_wait_for_completion_timeout(x, timeout) 70 71 #define complete_all(x) \ 72 linux_complete_all(x) 73 74 #define completion_done(x) \ 75 linux_completion_done(x) 76 77 /** 78 * @ingroup completion 79 * @brief Initialize a completion. 80 * 81 * @par Description: 82 * This API is used to initialize a specified completion. 83 * @attention 84 * <ul> 85 * <li>The input parameter x must point to valid memory, otherwise, initilize a completion would failed.</li> 86 * </ul> 87 * 88 * @param x [IN] Pointer to the completion to be initialized,which must point to valid memory. 89 * 90 * @retval None. 91 * @par Dependency: none 92 * <ul><li>completion.h: the header file that contains the API declaration.</li></ul> 93 * @see 94 */ 95 extern void linux_init_completion(struct completion *x); 96 97 /** 98 * @ingroup completion 99 * @brief Wake up a task that is waiting on this completion. 100 * 101 * @par Description: 102 * This API is used to wake up a task that is waiting on the completion. 103 * @attention 104 * <ul> 105 * <li>The input parameter x must point to valid memory, otherwise, the system would be abnormal.</li> 106 * <li>It suggested that calling complete() after wait_for_completion() or wait_for_completion_timeout(), 107 * otherwise, wait_for_completion() or wait_for_completion_timeout() would not block 108 * because there is already a completion completed.</li> 109 * </ul> 110 * 111 * @param x [IN] Pointer to the completion on which the task to be woken up is waiting, 112 * which must point to valid memory. 113 * 114 * @retval None. 115 * @par Dependency: 116 * <ul> 117 * <li>this function should be used after init_completion() be called.</li> 118 * <li>completion.h: the header file that contains the API declaration.</li> 119 * </ul> 120 * @see 121 */ 122 extern void linux_complete(struct completion *x); 123 124 /** 125 * @ingroup completion 126 * @brief Wait on a completion forever. 127 * 128 * @par Description: 129 * This API is used to wait on a completion forever. 130 * @attention 131 * <ul> 132 * <li>The input parameter x must point to valid memory, otherwise, the system would be abnormal.</li> 133 * <li>Can not be used in interrupt.</li> 134 * <li>DO NOT call this API in system tasks. </li> 135 * </ul> 136 * 137 * @param x [IN] Pointer to the completion to be waited on, which must point to valid memory. 138 * 139 * @retval None. 140 * @par Dependency: 141 * <ul> 142 * <li>this function should be used after init_completion() be called.</li> 143 * <li>completion.h: the header file that contains the API declaration.</li> 144 * </ul> 145 * @see 146 */ 147 extern void linux_wait_for_completion(struct completion *x); 148 149 /** 150 * @ingroup completion 151 * @brief Wait on a completion within a certain time period. 152 * 153 * @par Description: 154 * This API is used to wait on a completion within a certain time period (timeout). 155 * @attention 156 * <ul> 157 * <li>The input parameter x must point to valid memory, otherwise, the system would be abnormal.</li> 158 * <li>Timeout interval timeout should be in [1 , 0xFFFFFFFF], otherwise, 159 * it would return OS_WAIT_COMPLETION_ERROR but not wait for completion.</li> 160 * <li>Can not be used in interrupt.</li> 161 * <li>DO NOT call this API in software timer callback. </li> 162 * </ul> 163 * 164 * @param x [IN] Pointer to the completion to be waited on, which must point to valid memory. 165 * @param timeout [IN] Timeout interval for waiting on the completion (unit: Tick). 166 * 167 * @retval 0 The timeout period expires before the task is blocked or scheduled, or that timeout period is 0. 168 * @retval [1,0xFFFFFFFF] Remaining waiting time. 169 * @par Dependency: 170 * <ul> 171 * <li>this function should be used after init_completion() be called.</li> 172 * <li>completion.h: the header file that contains the API declaration.</li> 173 * </ul> 174 * @see 175 */ 176 extern unsigned long linux_wait_for_completion_timeout(struct completion *x, unsigned long timeout); 177 178 /** 179 * @ingroup completion 180 * @brief Wake up all tasks that are waiting on this completion. 181 * 182 * @par Description: 183 * This API is used to wake up all tasks that are waiting on the completion. 184 * @attention 185 * <ul> 186 * <li>The input parameter x must point to valid memory, otherwise, the system would be abnormal.</li> 187 * <li>It suggested that calling complete_all() after wait_for_completion() or wait_for_completion_timeout(), 188 * otherwise, wait_for_completion() or wait_for_completion_timeout() would not block 189 * because there is already a completion completed.</li> 190 * </ul> 191 * 192 * @param x [IN] Pointer to the completion on which the task to be woken up is waiting, 193 * which must point to valid memory. 194 * 195 * @retval None. 196 * @par Dependency: 197 * <ul> 198 * <li>this function should be used after init_completion() be called.</li> 199 * <li>completion.h: the header file that contains the API declaration.</li> 200 * </ul> 201 * @see 202 */ 203 extern void linux_complete_all(struct completion *x); 204 extern int linux_completion_done(struct completion *x); 205 206 #ifdef __cplusplus 207 #if __cplusplus 208 } 209 #endif /* __cplusplus */ 210 #endif /* __cplusplus */ 211 212 #endif /* _LINUXKPI_LINUX_COMPLETION_H_ */ 213