[BACK]Return to sys_lwp.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / kern

Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.

Diff for /src/sys/kern/sys_lwp.c between version 1.37 and 1.37.2.2

version 1.37, 2008/03/17 16:55:27 version 1.37.2.2, 2008/11/01 21:22:27
Line 15 
Line 15 
  * 2. Redistributions in binary form must reproduce the above copyright   * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the   *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.   *    documentation and/or other materials provided with the distribution.
  * 3. All advertising materials mentioning features or use of this software  
  *    must display the following acknowledgement:  
  *        This product includes software developed by the NetBSD  
  *        Foundation, Inc. and its contributors.  
  * 4. Neither the name of The NetBSD Foundation nor the names of its  
  *    contributors may be used to endorse or promote products derived  
  *    from this software without specific prior written permission.  
  *   *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS   * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
Line 57  __KERNEL_RCSID(0, "$NetBSD$");
Line 50  __KERNEL_RCSID(0, "$NetBSD$");
   
 #include <uvm/uvm_extern.h>  #include <uvm/uvm_extern.h>
   
   #include "opt_sa.h"
   
 #define LWP_UNPARK_MAX          1024  #define LWP_UNPARK_MAX          1024
   
 syncobj_t lwp_park_sobj = {  syncobj_t lwp_park_sobj = {
Line 91  sys__lwp_create(struct lwp *l, const str
Line 86  sys__lwp_create(struct lwp *l, const str
         ucontext_t *newuc;          ucontext_t *newuc;
         int error, lid;          int error, lid;
   
   #ifdef KERN_SA
           mutex_enter(p->p_lock);
           if ((p->p_sflag & (PS_SA | PS_WEXIT)) != 0 || p->p_sa != NULL) {
                   mutex_exit(p->p_lock);
                   return EINVAL;
           }
           mutex_exit(p->p_lock);
   #endif
   
         newuc = pool_get(&lwp_uc_pool, PR_WAITOK);          newuc = pool_get(&lwp_uc_pool, PR_WAITOK);
   
         error = copyin(SCARG(uap, ucp), newuc, p->p_emul->e_ucsize);          error = copyin(SCARG(uap, ucp), newuc, p->p_emul->e_ucsize);
Line 128  sys__lwp_create(struct lwp *l, const str
Line 132  sys__lwp_create(struct lwp *l, const str
          * it be created in suspended state.  If the process is stopping,           * it be created in suspended state.  If the process is stopping,
          * then the LWP is created stopped.           * then the LWP is created stopped.
          */           */
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
         lwp_lock(l2);          lwp_lock(l2);
         if ((SCARG(uap, flags) & LWP_SUSPENDED) == 0 &&          if ((SCARG(uap, flags) & LWP_SUSPENDED) == 0 &&
             (l->l_flag & (LW_WREBOOT | LW_WSUSPEND | LW_WEXIT)) == 0) {              (l->l_flag & (LW_WREBOOT | LW_WSUSPEND | LW_WEXIT)) == 0) {
Line 145  sys__lwp_create(struct lwp *l, const str
Line 149  sys__lwp_create(struct lwp *l, const str
                 l2->l_stat = LSSUSPENDED;                  l2->l_stat = LSSUSPENDED;
                 lwp_unlock_to(l2, l2->l_cpu->ci_schedstate.spc_lwplock);                  lwp_unlock_to(l2, l2->l_cpu->ci_schedstate.spc_lwplock);
         }          }
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
   
         return 0;          return 0;
 }  }
Line 195  sys__lwp_suspend(struct lwp *l, const st
Line 199  sys__lwp_suspend(struct lwp *l, const st
         struct lwp *t;          struct lwp *t;
         int error;          int error;
   
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
   
   #ifdef KERN_SA
           if ((p->p_sflag & PS_SA) != 0 || p->p_sa != NULL) {
                   mutex_exit(p->p_lock);
                   return EINVAL;
           }
   #endif
   
         if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {          if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 return ESRCH;                  return ESRCH;
         }          }
   
Line 212  sys__lwp_suspend(struct lwp *l, const st
Line 224  sys__lwp_suspend(struct lwp *l, const st
         if ((t == l && p->p_nrlwps == 1) ||          if ((t == l && p->p_nrlwps == 1) ||
             (l->l_flag & (LW_WCORE | LW_WEXIT)) != 0) {              (l->l_flag & (LW_WCORE | LW_WEXIT)) != 0) {
                 lwp_unlock(t);                  lwp_unlock(t);
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 return EDEADLK;                  return EDEADLK;
         }          }
   
Line 224  sys__lwp_suspend(struct lwp *l, const st
Line 236  sys__lwp_suspend(struct lwp *l, const st
          */           */
         error = lwp_suspend(l, t);          error = lwp_suspend(l, t);
         if (error) {          if (error) {
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 return error;                  return error;
         }          }
   
Line 236  sys__lwp_suspend(struct lwp *l, const st
Line 248  sys__lwp_suspend(struct lwp *l, const st
          *  o target LWP exited           *  o target LWP exited
          */           */
         for (;;) {          for (;;) {
                 error = cv_wait_sig(&p->p_lwpcv, &p->p_smutex);                  error = cv_wait_sig(&p->p_lwpcv, p->p_lock);
                 if (error) {                  if (error) {
                         error = ERESTART;                          error = ERESTART;
                         break;                          break;
Line 253  sys__lwp_suspend(struct lwp *l, const st
Line 265  sys__lwp_suspend(struct lwp *l, const st
                     (t->l_flag & LW_WSUSPEND) == 0)                      (t->l_flag & LW_WSUSPEND) == 0)
                         break;                          break;
         }          }
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
   
         return error;          return error;
 }  }
Line 270  sys__lwp_continue(struct lwp *l, const s
Line 282  sys__lwp_continue(struct lwp *l, const s
   
         error = 0;          error = 0;
   
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
         if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {          if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 return ESRCH;                  return ESRCH;
         }          }
   
         lwp_lock(t);          lwp_lock(t);
         lwp_continue(t);          lwp_continue(t);
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
   
         return error;          return error;
 }  }
Line 294  sys__lwp_wakeup(struct lwp *l, const str
Line 306  sys__lwp_wakeup(struct lwp *l, const str
         int error;          int error;
   
         p = l->l_proc;          p = l->l_proc;
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
   
         if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {          if ((t = lwp_find(p, SCARG(uap, target))) == NULL) {
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 return ESRCH;                  return ESRCH;
         }          }
   
Line 316  sys__lwp_wakeup(struct lwp *l, const str
Line 328  sys__lwp_wakeup(struct lwp *l, const str
                 error = 0;                  error = 0;
         }          }
   
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
   
         return error;          return error;
 }  }
Line 332  sys__lwp_wait(struct lwp *l, const struc
Line 344  sys__lwp_wait(struct lwp *l, const struc
         int error;          int error;
         lwpid_t dep;          lwpid_t dep;
   
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
         error = lwp_wait1(l, SCARG(uap, wait_for), &dep, 0);          error = lwp_wait1(l, SCARG(uap, wait_for), &dep, 0);
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
   
         if (error)          if (error)
                 return error;                  return error;
Line 367  sys__lwp_kill(struct lwp *l, const struc
Line 379  sys__lwp_kill(struct lwp *l, const struc
   
         KSI_INIT(&ksi);          KSI_INIT(&ksi);
         ksi.ksi_signo = signo;          ksi.ksi_signo = signo;
         ksi.ksi_code = SI_USER;          ksi.ksi_code = SI_LWP;
         ksi.ksi_pid = p->p_pid;          ksi.ksi_pid = p->p_pid;
         ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);          ksi.ksi_uid = kauth_cred_geteuid(l->l_cred);
         ksi.ksi_lid = SCARG(uap, target);          ksi.ksi_lid = SCARG(uap, target);
   
         mutex_enter(&proclist_mutex);          mutex_enter(proc_lock);
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
         if ((t = lwp_find(p, ksi.ksi_lid)) == NULL)          if ((t = lwp_find(p, ksi.ksi_lid)) == NULL)
                 error = ESRCH;                  error = ESRCH;
         else if (signo != 0)          else if (signo != 0)
                 kpsignal2(p, &ksi);                  kpsignal2(p, &ksi);
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
         mutex_exit(&proclist_mutex);          mutex_exit(proc_lock);
   
         return error;          return error;
 }  }
Line 398  sys__lwp_detach(struct lwp *l, const str
Line 410  sys__lwp_detach(struct lwp *l, const str
         target = SCARG(uap, target);          target = SCARG(uap, target);
         p = l->l_proc;          p = l->l_proc;
   
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
   
         if (l->l_lid == target)          if (l->l_lid == target)
                 t = l;                  t = l;
Line 442  sys__lwp_detach(struct lwp *l, const str
Line 454  sys__lwp_detach(struct lwp *l, const str
         } else          } else
                 error = ESRCH;                  error = ESRCH;
   
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
   
         return error;          return error;
 }  }
Line 460  lwp_unpark(lwpid_t target, const void *h
Line 472  lwp_unpark(lwpid_t target, const void *h
         sleepq_t *sq;          sleepq_t *sq;
         wchan_t wchan;          wchan_t wchan;
         int swapin;          int swapin;
           kmutex_t *mp;
         proc_t *p;          proc_t *p;
         lwp_t *t;          lwp_t *t;
   
Line 469  lwp_unpark(lwpid_t target, const void *h
Line 482  lwp_unpark(lwpid_t target, const void *h
          */           */
         p = curproc;          p = curproc;
         wchan = lwp_park_wchan(p, hint);          wchan = lwp_park_wchan(p, hint);
         sq = sleeptab_lookup(&lwp_park_tab, wchan);          sq = sleeptab_lookup(&lwp_park_tab, wchan, &mp);
   
         TAILQ_FOREACH(t, &sq->sq_queue, l_sleepchain)          TAILQ_FOREACH(t, sq, l_sleepchain)
                 if (t->l_proc == p && t->l_lid == target)                  if (t->l_proc == p && t->l_lid == target)
                         break;                          break;
   
         if (__predict_true(t != NULL)) {          if (__predict_true(t != NULL)) {
                 swapin = sleepq_remove(sq, t);                  swapin = sleepq_remove(sq, t);
                 sleepq_unlock(sq);                  mutex_spin_exit(mp);
                 if (swapin)                  if (swapin)
                         uvm_kick_scheduler();                          uvm_kick_scheduler();
                 return 0;                  return 0;
Line 487  lwp_unpark(lwpid_t target, const void *h
Line 500  lwp_unpark(lwpid_t target, const void *h
          * The LWP hasn't parked yet.  Take the hit and mark the           * The LWP hasn't parked yet.  Take the hit and mark the
          * operation as pending.           * operation as pending.
          */           */
         sleepq_unlock(sq);          mutex_spin_exit(mp);
   
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
         if ((t = lwp_find(p, target)) == NULL) {          if ((t = lwp_find(p, target)) == NULL) {
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 return ESRCH;                  return ESRCH;
         }          }
   
Line 512  lwp_unpark(lwpid_t target, const void *h
Line 525  lwp_unpark(lwpid_t target, const void *h
                 lwp_unlock(t);                  lwp_unlock(t);
         }          }
   
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
         return 0;          return 0;
 }  }
   
Line 521  lwp_park(struct timespec *ts, const void
Line 534  lwp_park(struct timespec *ts, const void
 {  {
         struct timespec tsx;          struct timespec tsx;
         sleepq_t *sq;          sleepq_t *sq;
           kmutex_t *mp;
         wchan_t wchan;          wchan_t wchan;
         int timo, error;          int timo, error;
         lwp_t *l;          lwp_t *l;
Line 541  lwp_park(struct timespec *ts, const void
Line 555  lwp_park(struct timespec *ts, const void
         /* Find and lock the sleep queue. */          /* Find and lock the sleep queue. */
         l = curlwp;          l = curlwp;
         wchan = lwp_park_wchan(l->l_proc, hint);          wchan = lwp_park_wchan(l->l_proc, hint);
         sq = sleeptab_lookup(&lwp_park_tab, wchan);          sq = sleeptab_lookup(&lwp_park_tab, wchan, &mp);
   
         /*          /*
          * Before going the full route and blocking, check to see if an           * Before going the full route and blocking, check to see if an
Line 551  lwp_park(struct timespec *ts, const void
Line 565  lwp_park(struct timespec *ts, const void
         if ((l->l_flag & (LW_CANCELLED | LW_UNPARKED)) != 0) {          if ((l->l_flag & (LW_CANCELLED | LW_UNPARKED)) != 0) {
                 l->l_flag &= ~(LW_CANCELLED | LW_UNPARKED);                  l->l_flag &= ~(LW_CANCELLED | LW_UNPARKED);
                 lwp_unlock(l);                  lwp_unlock(l);
                 sleepq_unlock(sq);                  mutex_spin_exit(mp);
                 return EALREADY;                  return EALREADY;
         }          }
         lwp_unlock_to(l, sq->sq_mutex);          lwp_unlock_to(l, mp);
         l->l_biglocks = 0;          l->l_biglocks = 0;
         sleepq_enqueue(sq, wchan, "parked", &lwp_park_sobj);          sleepq_enqueue(sq, wchan, "parked", &lwp_park_sobj);
         error = sleepq_block(timo, true);          error = sleepq_block(timo, true);
Line 578  lwp_park(struct timespec *ts, const void
Line 592  lwp_park(struct timespec *ts, const void
  * requests that it be unparked.   * requests that it be unparked.
  */   */
 int  int
 sys__lwp_park(struct lwp *l, const struct sys__lwp_park_args *uap, register_t *retval)  sys____lwp_park50(struct lwp *l, const struct sys____lwp_park50_args *uap,
       register_t *retval)
 {  {
         /* {          /* {
                 syscallarg(const struct timespec *)     ts;                  syscallarg(const struct timespec *)     ts;
Line 632  sys__lwp_unpark_all(struct lwp *l, const
Line 647  sys__lwp_unpark_all(struct lwp *l, const
         wchan_t wchan;          wchan_t wchan;
         lwpid_t targets[32], *tp, *tpp, *tmax, target;          lwpid_t targets[32], *tp, *tpp, *tmax, target;
         int swapin, error;          int swapin, error;
           kmutex_t *mp;
         u_int ntargets;          u_int ntargets;
         size_t sz;          size_t sz;
   
Line 671  sys__lwp_unpark_all(struct lwp *l, const
Line 687  sys__lwp_unpark_all(struct lwp *l, const
   
         swapin = 0;          swapin = 0;
         wchan = lwp_park_wchan(p, SCARG(uap, hint));          wchan = lwp_park_wchan(p, SCARG(uap, hint));
         sq = sleeptab_lookup(&lwp_park_tab, wchan);          sq = sleeptab_lookup(&lwp_park_tab, wchan, &mp);
   
         for (tmax = tp + ntargets, tpp = tp; tpp < tmax; tpp++) {          for (tmax = tp + ntargets, tpp = tp; tpp < tmax; tpp++) {
                 target = *tpp;                  target = *tpp;
Line 680  sys__lwp_unpark_all(struct lwp *l, const
Line 696  sys__lwp_unpark_all(struct lwp *l, const
                  * Easy case: search for the LWP on the sleep queue.  If                   * Easy case: search for the LWP on the sleep queue.  If
                  * it's parked, remove it from the queue and set running.                   * it's parked, remove it from the queue and set running.
                  */                   */
                 TAILQ_FOREACH(t, &sq->sq_queue, l_sleepchain)                  TAILQ_FOREACH(t, sq, l_sleepchain)
                         if (t->l_proc == p && t->l_lid == target)                          if (t->l_proc == p && t->l_lid == target)
                                 break;                                  break;
   
Line 693  sys__lwp_unpark_all(struct lwp *l, const
Line 709  sys__lwp_unpark_all(struct lwp *l, const
                  * The LWP hasn't parked yet.  Take the hit and                   * The LWP hasn't parked yet.  Take the hit and
                  * mark the operation as pending.                   * mark the operation as pending.
                  */                   */
                 sleepq_unlock(sq);                  mutex_spin_exit(mp);
                 mutex_enter(&p->p_smutex);                  mutex_enter(p->p_lock);
                 if ((t = lwp_find(p, target)) == NULL) {                  if ((t = lwp_find(p, target)) == NULL) {
                         mutex_exit(&p->p_smutex);                          mutex_exit(p->p_lock);
                         sleepq_lock(sq);                          mutex_spin_enter(mp);
                         continue;                          continue;
                 }                  }
                 lwp_lock(t);                  lwp_lock(t);
Line 718  sys__lwp_unpark_all(struct lwp *l, const
Line 734  sys__lwp_unpark_all(struct lwp *l, const
                         lwp_unlock(t);                          lwp_unlock(t);
                 }                  }
   
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 sleepq_lock(sq);                  mutex_spin_enter(mp);
         }          }
   
         sleepq_unlock(sq);          mutex_spin_exit(mp);
         if (tp != targets)          if (tp != targets)
                 kmem_free(tp, sz);                  kmem_free(tp, sz);
         if (swapin)          if (swapin)
Line 762  sys__lwp_setname(struct lwp *l, const st
Line 778  sys__lwp_setname(struct lwp *l, const st
         }          }
   
         p = curproc;          p = curproc;
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
         if ((t = lwp_find(p, target)) == NULL) {          if ((t = lwp_find(p, target)) == NULL) {
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 kmem_free(name, MAXCOMLEN);                  kmem_free(name, MAXCOMLEN);
                 return ESRCH;                  return ESRCH;
         }          }
Line 772  sys__lwp_setname(struct lwp *l, const st
Line 788  sys__lwp_setname(struct lwp *l, const st
         oname = t->l_name;          oname = t->l_name;
         t->l_name = name;          t->l_name = name;
         lwp_unlock(t);          lwp_unlock(t);
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
   
         if (oname != NULL)          if (oname != NULL)
                 kmem_free(oname, MAXCOMLEN);                  kmem_free(oname, MAXCOMLEN);
Line 797  sys__lwp_getname(struct lwp *l, const st
Line 813  sys__lwp_getname(struct lwp *l, const st
                 target = l->l_lid;                  target = l->l_lid;
   
         p = curproc;          p = curproc;
         mutex_enter(&p->p_smutex);          mutex_enter(p->p_lock);
         if ((t = lwp_find(p, target)) == NULL) {          if ((t = lwp_find(p, target)) == NULL) {
                 mutex_exit(&p->p_smutex);                  mutex_exit(p->p_lock);
                 return ESRCH;                  return ESRCH;
         }          }
         lwp_lock(t);          lwp_lock(t);
Line 808  sys__lwp_getname(struct lwp *l, const st
Line 824  sys__lwp_getname(struct lwp *l, const st
         else          else
                 strcpy(name, t->l_name);                  strcpy(name, t->l_name);
         lwp_unlock(t);          lwp_unlock(t);
         mutex_exit(&p->p_smutex);          mutex_exit(p->p_lock);
   
         return copyoutstr(name, SCARG(uap, name), SCARG(uap, len), NULL);          return copyoutstr(name, SCARG(uap, name), SCARG(uap, len), NULL);
 }  }

Legend:
Removed from v.1.37  
changed lines
  Added in v.1.37.2.2

CVSweb <webmaster@jp.NetBSD.org>