]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/subr_log.c
xnu-792.21.3.tar.gz
[apple/xnu.git] / bsd / kern / subr_log.c
index bd3e360a2e1f03f60b1afbf8e56772e6c7af1899..4f9e8c260474d2203960a55dd896d171057789d6 100644 (file)
@@ -1,16 +1,19 @@
 /*
 /*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
  *
  *
- * @APPLE_LICENSE_HEADER_START@
- * 
- * Copyright (c) 1999-2003 Apple Computer, Inc.  All Rights Reserved.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
  * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
  * 
  * This file contains Original Code and/or Modifications of Original Code
  * as defined in and that are subject to the Apple Public Source License
  * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
@@ -20,7 +23,7 @@
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * 
  * Please see the License for the specific language governing rights and
  * limitations under the License.
  * 
- * @APPLE_LICENSE_HEADER_END@
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
  */
 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
 /*
  */
 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
 /*
 
 #include <sys/param.h>
 #include <sys/systm.h>
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/proc.h>
+#include <sys/proc_internal.h>
 #include <sys/vnode.h>
 #include <sys/ioctl.h>
 #include <sys/msgbuf.h>
 #include <sys/vnode.h>
 #include <sys/ioctl.h>
 #include <sys/msgbuf.h>
-#include <sys/file.h>
+#include <sys/file_internal.h>
 #include <sys/errno.h>
 #include <sys/select.h>
 #include <sys/errno.h>
 #include <sys/select.h>
+#include <sys/kernel.h>
 #include <kern/thread.h>
 #include <kern/thread.h>
+#include <sys/lock.h>
 
 #define LOG_RDPRI      (PZERO + 1)
 
 
 #define LOG_RDPRI      (PZERO + 1)
 
@@ -89,16 +94,21 @@ int log_open;                       /* also used in log() */
 struct msgbuf temp_msgbuf;
 struct msgbuf *msgbufp;
 static int _logentrypend = 0;
 struct msgbuf temp_msgbuf;
 struct msgbuf *msgbufp;
 static int _logentrypend = 0;
+static int log_inited = 0;
+void bsd_log_lock(void);
+/* the following two are implemented in osfmk/kern/printf.c  */
+extern void bsd_log_unlock(void);
+extern void bsd_log_init(void);
 
 /*
  * Serialize log access.  Note that the log can be written at interrupt level,
  * so any log manipulations that can be done from, or affect, another processor
  * at interrupt level must be guarded with a spin lock.
  */
 
 /*
  * Serialize log access.  Note that the log can be written at interrupt level,
  * so any log manipulations that can be done from, or affect, another processor
  * at interrupt level must be guarded with a spin lock.
  */
-decl_simple_lock_data(,log_lock);      /* stop races dead in their tracks */
-#define        LOG_LOCK()      simple_lock(&log_lock)
-#define        LOG_UNLOCK()    simple_unlock(&log_lock)
-#define        LOG_LOCK_INIT() simple_lock_init(&log_lock)
+
+#define        LOG_LOCK() bsd_log_lock()
+#define        LOG_UNLOCK() bsd_log_unlock()
+
 
 /*ARGSUSED*/
 logopen(dev, flags, mode, p)
 
 /*ARGSUSED*/
 logopen(dev, flags, mode, p)
@@ -140,9 +150,7 @@ logclose(dev, flag)
        LOG_LOCK();
        log_open = 0;
        selwakeup(&logsoftc.sc_selp);
        LOG_LOCK();
        log_open = 0;
        selwakeup(&logsoftc.sc_selp);
-       oldpri = splhigh();
        selthreadclear(&logsoftc.sc_selp);
        selthreadclear(&logsoftc.sc_selp);
-       splx(oldpri);
        LOG_UNLOCK();
        return (0);
 }
        LOG_UNLOCK();
        return (0);
 }
@@ -157,42 +165,57 @@ logread(dev, uio, flag)
        register long l;
        register int s;
        int error = 0;
        register long l;
        register int s;
        int error = 0;
+       char localbuff[MSG_BSIZE];
+       int copybytes;
 
 
-       s = splhigh();
+       LOG_LOCK();
        while (msgbufp->msg_bufr == msgbufp->msg_bufx) {
                if (flag & IO_NDELAY) {
        while (msgbufp->msg_bufr == msgbufp->msg_bufx) {
                if (flag & IO_NDELAY) {
-                       splx(s);
-                       return (EWOULDBLOCK);
+                       error = EWOULDBLOCK;
+                       goto out;
                }
                if (logsoftc.sc_state & LOG_NBIO) {
                }
                if (logsoftc.sc_state & LOG_NBIO) {
-                       splx(s);
-                       return (EWOULDBLOCK);
+                       error = EWOULDBLOCK;
+                       goto out;
                }
                logsoftc.sc_state |= LOG_RDWAIT;
                }
                logsoftc.sc_state |= LOG_RDWAIT;
+               LOG_UNLOCK();
+               /*
+                * If the wakeup is missed the ligtening bolt will wake this up 
+                * if there are any new characters. If that doesn't do it
+                * then wait for 5 sec and reevaluate 
+                */
                if (error = tsleep((caddr_t)msgbufp, LOG_RDPRI | PCATCH,
                if (error = tsleep((caddr_t)msgbufp, LOG_RDPRI | PCATCH,
-                               "klog", 0)) {
-                       splx(s);
-                       return (error);
+                               "klog", 5 * hz)) {
+                       /* if it times out; ignore */
+                       if (error != EWOULDBLOCK)
+                               return (error);
                }
                }
+               LOG_LOCK();
        }
        }
-       splx(s);
        logsoftc.sc_state &= ~LOG_RDWAIT;
 
        logsoftc.sc_state &= ~LOG_RDWAIT;
 
-       while (uio->uio_resid > 0) {
+
+       while (uio_resid(uio) > 0) {
                l = msgbufp->msg_bufx - msgbufp->msg_bufr;
                if (l < 0)
                        l = MSG_BSIZE - msgbufp->msg_bufr;
                l = msgbufp->msg_bufx - msgbufp->msg_bufr;
                if (l < 0)
                        l = MSG_BSIZE - msgbufp->msg_bufr;
-               l = min(l, uio->uio_resid);
+               l = min(l, uio_resid(uio));
                if (l == 0)
                        break;
                if (l == 0)
                        break;
-               error = uiomove((caddr_t)&msgbufp->msg_bufc[msgbufp->msg_bufr],
+               bcopy(&msgbufp->msg_bufc[msgbufp->msg_bufr], &localbuff[0], l);
+               LOG_UNLOCK();
+               error = uiomove((caddr_t)&localbuff[0],
                        (int)l, uio);
                        (int)l, uio);
+               LOG_LOCK();
                if (error)
                        break;
                msgbufp->msg_bufr += l;
                if (msgbufp->msg_bufr < 0 || msgbufp->msg_bufr >= MSG_BSIZE)
                        msgbufp->msg_bufr = 0;
        }
                if (error)
                        break;
                msgbufp->msg_bufr += l;
                if (msgbufp->msg_bufr < 0 || msgbufp->msg_bufr >= MSG_BSIZE)
                        msgbufp->msg_bufr = 0;
        }
+out:
+       LOG_UNLOCK();
        return (error);
 }
 
        return (error);
 }
 
@@ -204,19 +227,19 @@ logselect(dev, rw, wql, p)
        void * wql;
        struct proc *p;
 {
        void * wql;
        struct proc *p;
 {
-       int s = splhigh();
 
        switch (rw) {
 
        case FREAD:
 
        switch (rw) {
 
        case FREAD:
+               LOG_LOCK();     
                if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
                if (msgbufp->msg_bufr != msgbufp->msg_bufx) {
-                       splx(s);
+                       LOG_UNLOCK();
                        return (1);
                }
                selrecord(p, &logsoftc.sc_selp, wql);
                        return (1);
                }
                selrecord(p, &logsoftc.sc_selp, wql);
+               LOG_UNLOCK();
                break;
        }
                break;
        }
-       splx(s);
        return (0);
 }
 
        return (0);
 }
 
@@ -227,24 +250,26 @@ logwakeup()
        int pgid;
        boolean_t funnel_state;
 
        int pgid;
        boolean_t funnel_state;
 
-       if (!log_open)
+       LOG_LOCK();     
+       if (!log_open) {
+               LOG_UNLOCK();
                return;
                return;
-       funnel_state = thread_funnel_set(kernel_flock, TRUE);
+       }
        selwakeup(&logsoftc.sc_selp);
        if (logsoftc.sc_state & LOG_ASYNC) {
        selwakeup(&logsoftc.sc_selp);
        if (logsoftc.sc_state & LOG_ASYNC) {
-               LOG_LOCK();
                pgid = logsoftc.sc_pgid;
                LOG_UNLOCK();
                if (pgid < 0)
                        gsignal(-pgid, SIGIO); 
                else if (p = pfind(pgid))
                        psignal(p, SIGIO);
                pgid = logsoftc.sc_pgid;
                LOG_UNLOCK();
                if (pgid < 0)
                        gsignal(-pgid, SIGIO); 
                else if (p = pfind(pgid))
                        psignal(p, SIGIO);
+               LOG_LOCK();
        }
        if (logsoftc.sc_state & LOG_RDWAIT) {
                wakeup((caddr_t)msgbufp);
                logsoftc.sc_state &= ~LOG_RDWAIT;
        }
        }
        if (logsoftc.sc_state & LOG_RDWAIT) {
                wakeup((caddr_t)msgbufp);
                logsoftc.sc_state &= ~LOG_RDWAIT;
        }
-       (void) thread_funnel_set(kernel_flock, funnel_state);
+       LOG_UNLOCK();
 }
 
 void
 }
 
 void
@@ -265,13 +290,12 @@ logioctl(dev, com, data, flag)
        long l;
        int s;
 
        long l;
        int s;
 
+       LOG_LOCK();     
        switch (com) {
 
        /* return number of characters immediately available */
        case FIONREAD:
        switch (com) {
 
        /* return number of characters immediately available */
        case FIONREAD:
-               s = splhigh();
                l = msgbufp->msg_bufx - msgbufp->msg_bufr;
                l = msgbufp->msg_bufx - msgbufp->msg_bufr;
-               splx(s);
                if (l < 0)
                        l += MSG_BSIZE;
                *(off_t *)data = l;
                if (l < 0)
                        l += MSG_BSIZE;
                *(off_t *)data = l;
@@ -292,28 +316,28 @@ logioctl(dev, com, data, flag)
                break;
 
        case TIOCSPGRP:
                break;
 
        case TIOCSPGRP:
-               LOG_LOCK();
                logsoftc.sc_pgid = *(int *)data;
                logsoftc.sc_pgid = *(int *)data;
-               LOG_UNLOCK();
                break;
 
        case TIOCGPGRP:
                break;
 
        case TIOCGPGRP:
-               LOG_LOCK();
                *(int *)data = logsoftc.sc_pgid;
                *(int *)data = logsoftc.sc_pgid;
-               LOG_UNLOCK();
                break;
 
        default:
                break;
 
        default:
+               LOG_UNLOCK();
                return (-1);
        }
                return (-1);
        }
+       LOG_UNLOCK();
        return (0);
 }
 
 void
        return (0);
 }
 
 void
-log_init()
+bsd_log_init()
 {
 {
-       msgbufp = &temp_msgbuf;
-       LOG_LOCK_INIT();
+       if (!log_inited) { 
+               msgbufp = &temp_msgbuf;
+               log_inited = 1;
+       }
 }
 
 void
 }
 
 void
@@ -321,8 +345,10 @@ log_putc(char c)
 {
        register struct msgbuf *mbp;
 
 {
        register struct msgbuf *mbp;
 
-       if (msgbufp == NULL)
-               msgbufp =&temp_msgbuf;
+       if (!log_inited) {
+               panic("bsd log is not inited");
+       }
+       LOG_LOCK();
 
        mbp = msgbufp; 
        if (mbp-> msg_magic != MSG_MAGIC) { 
 
        mbp = msgbufp; 
        if (mbp-> msg_magic != MSG_MAGIC) { 
@@ -337,4 +363,6 @@ log_putc(char c)
        _logentrypend = 1;
        if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE)
                mbp->msg_bufx = 0;
        _logentrypend = 1;
        if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE)
                mbp->msg_bufx = 0;
+       LOG_UNLOCK();
 }
 }
+