Home | History | Annotate | Line # | Download | only in rumpkern
sleepq.c revision 1.23
      1  1.23  knakahar /*	$NetBSD: sleepq.c,v 1.23 2022/06/30 07:47:07 knakahara Exp $	*/
      2   1.1     pooka 
      3   1.1     pooka /*
      4   1.1     pooka  * Copyright (c) 2008 Antti Kantee.  All Rights Reserved.
      5   1.1     pooka  *
      6   1.1     pooka  * Redistribution and use in source and binary forms, with or without
      7   1.1     pooka  * modification, are permitted provided that the following conditions
      8   1.1     pooka  * are met:
      9   1.1     pooka  * 1. Redistributions of source code must retain the above copyright
     10   1.1     pooka  *    notice, this list of conditions and the following disclaimer.
     11   1.1     pooka  * 2. Redistributions in binary form must reproduce the above copyright
     12   1.1     pooka  *    notice, this list of conditions and the following disclaimer in the
     13   1.1     pooka  *    documentation and/or other materials provided with the distribution.
     14   1.1     pooka  *
     15   1.1     pooka  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
     16   1.1     pooka  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     17   1.1     pooka  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     18   1.1     pooka  * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
     19   1.1     pooka  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     20   1.1     pooka  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
     21   1.1     pooka  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     22   1.1     pooka  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     23   1.1     pooka  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     24   1.1     pooka  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     25   1.1     pooka  * SUCH DAMAGE.
     26   1.1     pooka  */
     27   1.1     pooka 
     28   1.2     pooka #include <sys/cdefs.h>
     29  1.23  knakahar __KERNEL_RCSID(0, "$NetBSD: sleepq.c,v 1.23 2022/06/30 07:47:07 knakahara Exp $");
     30   1.2     pooka 
     31   1.1     pooka #include <sys/param.h>
     32   1.1     pooka #include <sys/condvar.h>
     33   1.1     pooka #include <sys/mutex.h>
     34   1.6     pooka #include <sys/once.h>
     35   1.1     pooka #include <sys/queue.h>
     36   1.1     pooka #include <sys/sleepq.h>
     37   1.1     pooka #include <sys/syncobj.h>
     38  1.10     skrll #include <sys/atomic.h>
     39   1.1     pooka 
     40  1.17     pooka #include <rump-sys/kern.h>
     41   1.3     pooka 
     42   1.1     pooka syncobj_t sleep_syncobj;
     43   1.1     pooka 
     44  1.21  christos void
     45  1.21  christos sleepq_init(sleepq_t *sq)
     46   1.6     pooka {
     47   1.6     pooka 
     48  1.21  christos 	LIST_INIT(sq);
     49  1.21  christos 	cv_init(&sq->sq_cv, "sleepq");
     50   1.6     pooka }
     51   1.6     pooka 
     52   1.1     pooka void
     53  1.21  christos sleepq_destroy(sleepq_t *sq)
     54   1.1     pooka {
     55   1.1     pooka 
     56  1.21  christos 	cv_destroy(&sq->sq_cv);
     57   1.1     pooka }
     58   1.1     pooka 
     59   1.1     pooka void
     60  1.19        ad sleepq_enqueue(sleepq_t *sq, wchan_t wc, const char *wmsg, syncobj_t *sob,
     61  1.19        ad     bool catch_p)
     62   1.1     pooka {
     63   1.1     pooka 	struct lwp *l = curlwp;
     64   1.1     pooka 
     65   1.1     pooka 	l->l_wchan = wc;
     66  1.12     pooka 	l->l_wmesg = wmsg;
     67   1.3     pooka 	l->l_sleepq = sq;
     68  1.18        ad 	LIST_INSERT_HEAD(sq, l, l_sleepchain);
     69   1.1     pooka }
     70   1.1     pooka 
     71   1.1     pooka int
     72  1.23  knakahar sleepq_block(int timo, bool catch, struct syncobj *syncobj __unused)
     73   1.1     pooka {
     74   1.1     pooka 	struct lwp *l = curlwp;
     75   1.3     pooka 	int error = 0;
     76   1.3     pooka 	kmutex_t *mp = l->l_mutex;
     77   1.3     pooka 	int biglocks = l->l_biglocks;
     78   1.1     pooka 
     79   1.3     pooka 	while (l->l_wchan) {
     80  1.13     pooka 		l->l_mutex = mp; /* keep sleepq lock until woken up */
     81  1.21  christos 		error = cv_timedwait(&l->l_sleepq->sq_cv, mp, timo);
     82  1.11     pooka 		if (error == EWOULDBLOCK || error == EINTR) {
     83  1.13     pooka 			if (l->l_wchan) {
     84  1.18        ad 				LIST_REMOVE(l, l_sleepchain);
     85  1.13     pooka 				l->l_wchan = NULL;
     86  1.13     pooka 				l->l_wmesg = NULL;
     87  1.13     pooka 			}
     88   1.4     pooka 		}
     89   1.3     pooka 	}
     90   1.3     pooka 	mutex_spin_exit(mp);
     91   1.1     pooka 
     92   1.3     pooka 	if (biglocks)
     93   1.3     pooka 		KERNEL_LOCK(biglocks, curlwp);
     94   1.1     pooka 
     95   1.3     pooka 	return error;
     96   1.1     pooka }
     97   1.1     pooka 
     98  1.16     pooka void
     99   1.1     pooka sleepq_wake(sleepq_t *sq, wchan_t wchan, u_int expected, kmutex_t *mp)
    100   1.1     pooka {
    101   1.3     pooka 	struct lwp *l, *l_next;
    102   1.1     pooka 	bool found = false;
    103   1.1     pooka 
    104  1.18        ad 	for (l = LIST_FIRST(sq); l; l = l_next) {
    105  1.18        ad 		l_next = LIST_NEXT(l, l_sleepchain);
    106   1.1     pooka 		if (l->l_wchan == wchan) {
    107   1.1     pooka 			found = true;
    108   1.1     pooka 			l->l_wchan = NULL;
    109  1.12     pooka 			l->l_wmesg = NULL;
    110  1.18        ad 			LIST_REMOVE(l, l_sleepchain);
    111  1.15     pooka 			if (--expected == 0)
    112  1.15     pooka 				break;
    113   1.1     pooka 		}
    114   1.1     pooka 	}
    115   1.1     pooka 	if (found)
    116  1.21  christos 		cv_broadcast(&sq->sq_cv);
    117   1.1     pooka 
    118   1.1     pooka 	mutex_spin_exit(mp);
    119   1.1     pooka }
    120   1.1     pooka 
    121   1.5     rmind void
    122   1.3     pooka sleepq_unsleep(struct lwp *l, bool cleanup)
    123   1.3     pooka {
    124   1.3     pooka 
    125   1.3     pooka 	l->l_wchan = NULL;
    126  1.12     pooka 	l->l_wmesg = NULL;
    127  1.18        ad 	LIST_REMOVE(l, l_sleepchain);
    128  1.21  christos 	cv_broadcast(&l->l_sleepq->sq_cv);
    129   1.3     pooka 
    130   1.3     pooka 	if (cleanup) {
    131   1.3     pooka 		mutex_spin_exit(l->l_mutex);
    132   1.3     pooka 	}
    133   1.3     pooka }
    134   1.3     pooka 
    135   1.1     pooka /*
    136   1.3     pooka  * Thread scheduler handles priorities.  Therefore no action here.
    137   1.3     pooka  * (maybe do something if we're deperate?)
    138   1.3     pooka  */
    139   1.3     pooka void
    140   1.3     pooka sleepq_changepri(struct lwp *l, pri_t pri)
    141   1.3     pooka {
    142   1.3     pooka 
    143   1.3     pooka }
    144   1.3     pooka 
    145   1.3     pooka void
    146   1.3     pooka sleepq_lendpri(struct lwp *l, pri_t pri)
    147   1.3     pooka {
    148   1.3     pooka 
    149   1.3     pooka }
    150   1.3     pooka 
    151   1.3     pooka struct lwp *
    152   1.3     pooka syncobj_noowner(wchan_t wc)
    153   1.3     pooka {
    154   1.3     pooka 
    155   1.3     pooka 	return NULL;
    156   1.3     pooka }
    157   1.3     pooka 
    158   1.9     rmind void
    159   1.9     rmind lwp_unlock_to(struct lwp *l, kmutex_t *new)
    160   1.1     pooka {
    161   1.9     rmind 	kmutex_t *old;
    162   1.1     pooka 
    163   1.9     rmind 	KASSERT(mutex_owned(l->l_mutex));
    164   1.9     rmind 
    165   1.9     rmind 	old = l->l_mutex;
    166  1.22  riastrad 	atomic_store_release(&l->l_mutex, new);
    167   1.9     rmind 	mutex_spin_exit(old);
    168   1.1     pooka }
    169