gonzui


Format: Advanced Search

t2ex/t2ex_source/t2ex/network/net/src/netmain/tkn_intr.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T2EX Software Package
    4:  *
    5:  *    Copyright 2012 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2012/12/12.
   10:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/04.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: /*
   15:  * This software package is available for use, modification, 
   16:  * and redistribution in accordance with the terms of the attached 
   17:  * T-License 2.x.
   18:  * If you want to redistribute the source code, you need to attach 
   19:  * the T-License 2.x document.
   20:  * There's no obligation to publish the content, and no obligation 
   21:  * to disclose it to the TRON Forum if you have modified the 
   22:  * software package.
   23:  * You can also distribute the modified source code. In this case, 
   24:  * please register the modification to T-Kernel traceability service.
   25:  * People can know the history of modifications by the service, 
   26:  * and can be sure that the version you have inherited some 
   27:  * modification of a particular version or not.
   28:  *
   29:  *    http://trace.tron.org/tk/?lang=en
   30:  *    http://trace.tron.org/tk/?lang=ja
   31:  *
   32:  * As per the provisions of the T-License 2.x, TRON Forum ensures that 
   33:  * the portion of the software that is copyrighted by Ken Sakamura or 
   34:  * the TRON Forum does not infringe the copyrights of a third party.
   35:  * However, it does not make any warranty other than this.
   36:  * DISCLAIMER: TRON Forum and Ken Sakamura shall not be held
   37:  * responsible for any consequences or damages caused directly or
   38:  * indirectly by the use of this software package.
   39:  *
   40:  * The source codes in bsd_source.tar.gz in this software package are 
   41:  * derived from NetBSD or OpenBSD and not covered under T-License 2.x.
   42:  * They need to be changed or redistributed according to the 
   43:  * representation of each source header.
   44:  */
   45: 
   46: /*
   47:  *      @(#)tkn_intr.c
   48:  *
   49:  */
   50: 
   51: #include <tk/tkernel.h>
   52: #include "netmain/tkn_spl.h"
   53: 
   54: #include <sys/param.h>
   55: #include <sys/systm.h>
   56: #include <sys/syslog.h>
   57: #include <sys/tkn_intr.h>
   58: #include <sys/intr.h>
   59: #include <sys/lwp.h>
   60: #include <sys/malloc.h>
   61: 
   62: #include "tkn.h"
   63: #include "netmain/tkn_taskutil.h"
   64: 
   65: 
   66: struct tkn_intrhand {
   67:         ID task;
   68:         ID sem;
   69: };
   70: 
   71: struct tkn_spl_trampo {
   72:         struct tkn_intrhand ih;
   73:         int level;
   74:         int mpsafe;
   75:         void (*hand)(void*);
   76:         void* arg;
   77: };
   78: 
   79: static void spl_trampo(INT arg, VP vp)
   80: {
   81:         ER er = 0;
   82:         lwp_t *lwp = curlwp;
   83:         struct tkn_spl_trampo *trampo = vp;
   84:         if (trampo == NULL)
   85:                 goto err_bad_arg;
   86: 
   87:         ID sem = trampo->ih.sem;
   88:         void (*hand)(void*) = trampo->hand;
   89:         void* p_arg = trampo->arg;
   90:         int level = trampo->level;
   91:         int mpsafe = trampo->mpsafe;
   92:         int s;
   93: 
   94:         for (;;) {
   95:                 /*
   96:                  * Wait for a software interrupt notification.
   97:                  */
   98:                 er = tk_wai_sem(sem, 1, TMO_FEVR);
   99:                 if (er < 0) {
  100:                         if (er == E_NOEXS || er == E_DLT)
  101:                                 goto err_exit;
  102:                         goto err_sem;
  103:                 }
  104: 
  105:                 s = tkn_spl_lock(level);
  106:                 if ( mpsafe ) {
  107:                         KERNEL_LOCK(1, lwp);
  108:                         hand(p_arg);
  109:                         KERNEL_UNLOCK_ONE(lwp);
  110:                 } else {
  111:                         hand(p_arg);
  112:                 }
  113:                 tkn_spl_unlock(s);
  114:         }
  115:         /* Never reach here. */
  116:         return;
  117: 
  118: err_bad_arg:
  119:         /* Invalid arguments. */
  120:         log(LOG_ERR, "%s:tid=%d bad args", __func__, tk_get_tid());
  121:         tk_exd_tsk();
  122:         return;
  123: err_sem:
  124:         log(LOG_ERR, "%s: unexpected error %d(%d, %d)", __func__, er, MERCD(er), SERCD(er));
  125: err_exit:
  126:         /* Request for terminating the task by deleting the semaphore. */
  127:         free(trampo, M_SOFTINTR);
  128:         tk_exd_tsk();
  129: }
  130: 
  131: 
  132: /*
  133:  * This function can be called from the context in which interrupts are disabled.
  134:  */
  135: int
  136: tkn_spl_submit_intr_di(int id)
  137: {
  138:         return tk_sig_sem(id, 1);
  139: }
  140: 
  141: int
  142: tkn_spl_submit_intr(int id)
  143: {
  144:         ER er;
  145: 
  146:         er = tkn_spl_submit_intr_di(id);
  147:         if (er < 0)
  148:                 goto err_signal;
  149:         return 0;
  150: 
  151: err_signal:
  152:         log(LOG_ERR, "%s: unexpected error %d(%d, %d) ID=%d\n", __func__, er, MERCD(er), SERCD(er), id);
  153:         return er;
  154: }
  155: 
  156: /*
  157:  * Create a software interrupt handler task.
  158:  *
  159:  *   hand:  task start address
  160:  *   level: interrupt level (a higher level value means a higher priority.)
  161:  *
  162:  * This returns a non-zero value which represents a semaphore ID, or a negative
  163:  * value which represents an error. This semaphore tirggers a software interrupt
  164:  * by calling tk_sig_sem() with the returned semaphore ID.
  165:  *
  166:  * Deleting the semaphore terminates the handler task.
  167:  */
  168: int
  169: tkn_spl_make_handler(void (*hand)(), int flags, void* arg)
  170: {
  171:         int level = flags & SOFTINT_LVLMASK;
  172:         int mpsafe = flags & SOFTINT_MPSAFE;
  173:         int ipl_level;
  174: 
  175:         switch(level) {
  176:         case SOFTINT_BIO:
  177:                 ipl_level = IPL_BIO;
  178:                 break;
  179:         case SOFTINT_CLOCK:
  180:                 ipl_level = IPL_CLOCK;
  181:                 break;
  182:         case SOFTINT_SERIAL:
  183:                 ipl_level = IPL_SERIAL;
  184:                 break;
  185:         case SOFTINT_NET:
  186:                 ipl_level = IPL_NET;
  187:                 break;
  188:         default:
  189:                 ipl_level = level;
  190:         }
  191: 
  192:         /*
  193:          * Allocate memory to store context information.
  194:          */
  195:         struct tkn_spl_trampo *trampo;
  196:         trampo = malloc(sizeof(struct tkn_spl_trampo), M_SOFTINTR, M_NOWAIT | M_ZERO);
  197:         if (trampo == NULL)
  198:                 goto err_trampo;
  199: 
  200:         struct tkn_intrhand ih;
  201: 
  202:         ih.sem = tkn_cre_sem("Nsih");
  203:         if (ih.sem < 0)
  204:                 goto err_sem;
  205: 
  206:         /*
  207:          * Create a task
  208:          */
  209:         PRI prio;
  210:         trampo->level = ipl_level;
  211:         trampo->mpsafe = mpsafe;
  212:         trampo->hand  = hand;
  213:         trampo->arg   = arg;
  214:         prio = tkn_spl_priority(ipl_level);
  215:         ih.task = tkn_cre_tsk(spl_trampo, prio, TKN_SPLTRAMPO_STKSZ, trampo);
  216:         if (ih.task < 0)
  217:                 goto err_task;
  218:         trampo->ih = ih;
  219: 
  220:         /*
  221:          * Start the task
  222:          */
  223:         ER er;
  224:         er = tk_sta_tsk(ih.task, 0);
  225:         if (er < 0)
  226:                 goto err_task_start;
  227: 
  228:         return ih.sem;
  229: 
  230: err_task_start:
  231:         tk_del_tsk(ih.task);
  232: err_task:
  233:         tk_del_sem(ih.sem);
  234: err_sem:
  235:         free(trampo, M_RTABLE);
  236: err_trampo:
  237:         log(LOG_ERR, "%s: unexpected error\n", __func__);
  238:         return -1;
  239: }
  240: 
  241: int tkn_spl_delete_handler(int id)
  242: {
  243:         return tk_del_sem(id);
  244: }
  245: 
  246: void* softint_establish(unsigned int flags, void (*func)(void*), void* arg)
  247: {
  248:         int ret = tkn_spl_make_handler(func, flags, arg);
  249: 
  250:         return (ret < 0 ? NULL : (void*)ret);
  251: }
  252: 
  253: void softint_disestablish(void* handle)
  254: {
  255:         tk_del_sem((ID)handle);
  256: }
  257: 
  258: void softint_schedule(void* handle)
  259: {
  260:         tkn_spl_submit_intr((ID)handle);
  261: }