00001 /* 00002 * TOPPERS/ASP Kernel 00003 * Toyohashi Open Platform for Embedded Real-Time Systems/ 00004 * Advanced Standard Profile Kernel 00005 * 00006 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory 00007 * Toyohashi Univ. of Technology, JAPAN 00008 * Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory 00009 * Graduate School of Information Science, Nagoya Univ., JAPAN 00010 * 00011 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ 00012 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改 00013 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する. 00014 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 00015 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 00016 * スコード中に含まれていること. 00017 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 00018 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 00019 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 00020 * の無保証規定を掲載すること. 00021 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 00022 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 00023 * と. 00024 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 00025 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 00026 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 00027 * 報告すること. 00028 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 00029 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 00030 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理 00031 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを 00032 * 免責すること. 00033 * 00034 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 00035 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的 00036 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ 00037 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ 00038 * の責任を負わない. 00039 * 00040 * @(#) $Id: semaphore.c 748 2008-03-07 17:18:06Z hiro $ 00041 */ 00042 00043 /* 00044 * セマフォ機能 00045 */ 00046 00047 #include "kernel_impl.h" 00048 #include "check.h" 00049 #include "task.h" 00050 #include "wait.h" 00051 #include "semaphore.h" 00052 00053 /* 00054 * トレースログマクロのデフォルト定義 00055 */ 00056 #ifndef LOG_SIG_SEM_ENTER 00057 #define LOG_SIG_SEM_ENTER(semid) 00058 #endif /* LOG_SIG_SEM_ENTER */ 00059 00060 #ifndef LOG_SIG_SEM_LEAVE 00061 #define LOG_SIG_SEM_LEAVE(ercd) 00062 #endif /* LOG_SIG_SEM_LEAVE */ 00063 00064 #ifndef LOG_ISIG_SEM_ENTER 00065 #define LOG_ISIG_SEM_ENTER(semid) 00066 #endif /* LOG_ISIG_SEM_ENTER */ 00067 00068 #ifndef LOG_ISIG_SEM_LEAVE 00069 #define LOG_ISIG_SEM_LEAVE(ercd) 00070 #endif /* LOG_ISIG_SEM_LEAVE */ 00071 00072 #ifndef LOG_WAI_SEM_ENTER 00073 #define LOG_WAI_SEM_ENTER(semid) 00074 #endif /* LOG_WAI_SEM_ENTER */ 00075 00076 #ifndef LOG_WAI_SEM_LEAVE 00077 #define LOG_WAI_SEM_LEAVE(ercd) 00078 #endif /* LOG_WAI_SEM_LEAVE */ 00079 00080 #ifndef LOG_POL_SEM_ENTER 00081 #define LOG_POL_SEM_ENTER(semid) 00082 #endif /* LOG_POL_SEM_ENTER */ 00083 00084 #ifndef LOG_POL_SEM_LEAVE 00085 #define LOG_POL_SEM_LEAVE(ercd) 00086 #endif /* LOG_POL_SEM_LEAVE */ 00087 00088 #ifndef LOG_TWAI_SEM_ENTER 00089 #define LOG_TWAI_SEM_ENTER(semid, tmout) 00090 #endif /* LOG_TWAI_SEM_ENTER */ 00091 00092 #ifndef LOG_TWAI_SEM_LEAVE 00093 #define LOG_TWAI_SEM_LEAVE(ercd) 00094 #endif /* LOG_TWAI_SEM_LEAVE */ 00095 00096 #ifndef LOG_INI_SEM_ENTER 00097 #define LOG_INI_SEM_ENTER(semid) 00098 #endif /* LOG_INI_SEM_ENTER */ 00099 00100 #ifndef LOG_INI_SEM_LEAVE 00101 #define LOG_INI_SEM_LEAVE(ercd) 00102 #endif /* LOG_INI_SEM_LEAVE */ 00103 00104 #ifndef LOG_REF_SEM_ENTER 00105 #define LOG_REF_SEM_ENTER(semid, pk_rsem) 00106 #endif /* LOG_REF_SEM_ENTER */ 00107 00108 #ifndef LOG_REF_SEM_LEAVE 00109 #define LOG_REF_SEM_LEAVE(ercd, pk_rsem) 00110 #endif /* LOG_REF_SEM_LEAVE */ 00111 00112 /* 00113 * セマフォの数 00114 */ 00115 #define tnum_sem ((uint_t)(tmax_semid - TMIN_SEMID + 1)) 00116 00117 /* 00118 * セマフォIDからセマフォ管理ブロックを取り出すためのマクロ 00119 */ 00120 #define INDEX_SEM(semid) ((uint_t)((semid) - TMIN_SEMID)) 00121 #define get_semcb(semid) (&(semcb_table[INDEX_SEM(semid)])) 00122 00123 /* 00124 * セマフォ機能の初期化 00125 */ 00126 #ifdef TOPPERS_semini 00127 00128 void 00129 initialize_semaphore(void) 00130 { 00131 uint_t i; 00132 SEMCB *p_semcb; 00133 00134 for (p_semcb = semcb_table, i = 0; i < tnum_sem; p_semcb++, i++) { 00135 queue_initialize(&(p_semcb->wait_queue)); 00136 p_semcb->p_seminib = &(seminib_table[i]); 00137 p_semcb->semcnt = p_semcb->p_seminib->isemcnt; 00138 } 00139 } 00140 00141 #endif /* TOPPERS_semini */ 00142 00143 /* 00144 * セマフォ資源の返却 00145 */ 00146 #ifdef TOPPERS_sig_sem 00147 00148 ER 00149 sig_sem(ID semid) 00150 { 00151 SEMCB *p_semcb; 00152 TCB *p_tcb; 00153 ER ercd; 00154 00155 LOG_SIG_SEM_ENTER(semid); 00156 CHECK_TSKCTX_UNL(); 00157 CHECK_SEMID(semid); 00158 p_semcb = get_semcb(semid); 00159 00160 t_lock_cpu(); 00161 if (!queue_empty(&(p_semcb->wait_queue))) { 00162 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue)); 00163 if (wait_complete(p_tcb)) { 00164 dispatch(); 00165 } 00166 ercd = E_OK; 00167 } 00168 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) { 00169 p_semcb->semcnt += 1; 00170 ercd = E_OK; 00171 } 00172 else { 00173 ercd = E_QOVR; 00174 } 00175 t_unlock_cpu(); 00176 00177 error_exit: 00178 LOG_SIG_SEM_LEAVE(ercd); 00179 return(ercd); 00180 } 00181 00182 #endif /* TOPPERS_sig_sem */ 00183 00184 /* 00185 * セマフォ資源の返却(非タスクコンテキスト用) 00186 */ 00187 #ifdef TOPPERS_isig_sem 00188 00189 ER 00190 isig_sem(ID semid) 00191 { 00192 SEMCB *p_semcb; 00193 TCB *p_tcb; 00194 ER ercd; 00195 00196 LOG_ISIG_SEM_ENTER(semid); 00197 CHECK_INTCTX_UNL(); 00198 CHECK_SEMID(semid); 00199 p_semcb = get_semcb(semid); 00200 00201 i_lock_cpu(); 00202 if (!queue_empty(&(p_semcb->wait_queue))) { 00203 p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue)); 00204 if (wait_complete(p_tcb)) { 00205 reqflg = true; 00206 } 00207 ercd = E_OK; 00208 } 00209 else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) { 00210 p_semcb->semcnt += 1; 00211 ercd = E_OK; 00212 } 00213 else { 00214 ercd = E_QOVR; 00215 } 00216 i_unlock_cpu(); 00217 00218 error_exit: 00219 LOG_ISIG_SEM_LEAVE(ercd); 00220 return(ercd); 00221 } 00222 00223 #endif /* TOPPERS_isig_sem */ 00224 00225 /* 00226 * セマフォ資源の獲得 00227 */ 00228 #ifdef TOPPERS_wai_sem 00229 00230 ER 00231 wai_sem(ID semid) 00232 { 00233 SEMCB *p_semcb; 00234 WINFO_SEM winfo_sem; 00235 ER ercd; 00236 00237 LOG_WAI_SEM_ENTER(semid); 00238 CHECK_DISPATCH(); 00239 CHECK_SEMID(semid); 00240 p_semcb = get_semcb(semid); 00241 00242 t_lock_cpu(); 00243 if (p_semcb->semcnt >= 1) { 00244 p_semcb->semcnt -= 1; 00245 ercd = E_OK; 00246 } 00247 else { 00248 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM); 00249 wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem); 00250 dispatch(); 00251 ercd = winfo_sem.winfo.wercd; 00252 } 00253 t_unlock_cpu(); 00254 00255 error_exit: 00256 LOG_WAI_SEM_LEAVE(ercd); 00257 return(ercd); 00258 } 00259 00260 #endif /* TOPPERS_wai_sem */ 00261 00262 /* 00263 * セマフォ資源の獲得(ポーリング) 00264 */ 00265 #ifdef TOPPERS_pol_sem 00266 00267 ER 00268 pol_sem(ID semid) 00269 { 00270 SEMCB *p_semcb; 00271 ER ercd; 00272 00273 LOG_POL_SEM_ENTER(semid); 00274 CHECK_TSKCTX_UNL(); 00275 CHECK_SEMID(semid); 00276 p_semcb = get_semcb(semid); 00277 00278 t_lock_cpu(); 00279 if (p_semcb->semcnt >= 1) { 00280 p_semcb->semcnt -= 1; 00281 ercd = E_OK; 00282 } 00283 else { 00284 ercd = E_TMOUT; 00285 } 00286 t_unlock_cpu(); 00287 00288 error_exit: 00289 LOG_POL_SEM_LEAVE(ercd); 00290 return(ercd); 00291 } 00292 00293 #endif /* TOPPERS_pol_sem */ 00294 00295 /* 00296 * セマフォ資源の獲得(タイムアウトあり) 00297 */ 00298 #ifdef TOPPERS_twai_sem 00299 00300 ER 00301 twai_sem(ID semid, TMO tmout) 00302 { 00303 SEMCB *p_semcb; 00304 WINFO_SEM winfo_sem; 00305 TMEVTB tmevtb; 00306 ER ercd; 00307 00308 LOG_TWAI_SEM_ENTER(semid, tmout); 00309 CHECK_DISPATCH(); 00310 CHECK_SEMID(semid); 00311 CHECK_TMOUT(tmout); 00312 p_semcb = get_semcb(semid); 00313 00314 t_lock_cpu(); 00315 if (p_semcb->semcnt >= 1) { 00316 p_semcb->semcnt -= 1; 00317 ercd = E_OK; 00318 } 00319 else if (tmout == TMO_POL) { 00320 ercd = E_TMOUT; 00321 } 00322 else { 00323 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM); 00324 wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem, 00325 &tmevtb, tmout); 00326 dispatch(); 00327 ercd = winfo_sem.winfo.wercd; 00328 } 00329 t_unlock_cpu(); 00330 00331 error_exit: 00332 LOG_TWAI_SEM_LEAVE(ercd); 00333 return(ercd); 00334 } 00335 00336 #endif /* TOPPERS_twai_sem */ 00337 00338 /* 00339 * セマフォの再初期化 00340 */ 00341 #ifdef TOPPERS_ini_sem 00342 00343 ER 00344 ini_sem(ID semid) 00345 { 00346 SEMCB *p_semcb; 00347 bool_t dspreq; 00348 ER ercd; 00349 00350 LOG_INI_SEM_ENTER(semid); 00351 CHECK_TSKCTX_UNL(); 00352 CHECK_SEMID(semid); 00353 p_semcb = get_semcb(semid); 00354 00355 t_lock_cpu(); 00356 dspreq = init_wait_queue(&(p_semcb->wait_queue)); 00357 p_semcb->semcnt = p_semcb->p_seminib->isemcnt; 00358 if (dspreq) { 00359 dispatch(); 00360 } 00361 ercd = E_OK; 00362 t_unlock_cpu(); 00363 00364 error_exit: 00365 LOG_INI_SEM_LEAVE(ercd); 00366 return(ercd); 00367 } 00368 00369 #endif /* TOPPERS_ini_sem */ 00370 00371 /* 00372 * セマフォの状態参照 00373 */ 00374 #ifdef TOPPERS_ref_sem 00375 00376 ER 00377 ref_sem(ID semid, T_RSEM *pk_rsem) 00378 { 00379 SEMCB *p_semcb; 00380 ER ercd; 00381 00382 LOG_REF_SEM_ENTER(semid, pk_rsem); 00383 CHECK_TSKCTX_UNL(); 00384 CHECK_SEMID(semid); 00385 p_semcb = get_semcb(semid); 00386 00387 t_lock_cpu(); 00388 pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue)); 00389 pk_rsem->semcnt = p_semcb->semcnt; 00390 ercd = E_OK; 00391 t_unlock_cpu(); 00392 00393 error_exit: 00394 LOG_REF_SEM_LEAVE(ercd, pk_rsem); 00395 return(ercd); 00396 } 00397 00398 #endif /* TOPPERS_ref_sem */
Copyright © 2008 by Kijineko Inc.