X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/de355530ae67247cbd0da700edb3a2a1dae884c2..ff6e181ae92fc6f1e89841290f461d1f2f9badd9:/bsd/kern/subr_log.c diff --git a/bsd/kern/subr_log.c b/bsd/kern/subr_log.c index 4a4a9a06a..c18de681f 100644 --- a/bsd/kern/subr_log.c +++ b/bsd/kern/subr_log.c @@ -1,21 +1,22 @@ /* - * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.1 (the - * "License"). You may not use this file except in compliance with the - * License. Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. + * 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. * - * This 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 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License. + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -61,14 +62,16 @@ #include #include -#include +#include #include #include #include -#include +#include #include #include +#include #include +#include #define LOG_RDPRI (PZERO + 1) @@ -86,16 +89,21 @@ int log_open; /* also used in log() */ 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. */ -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) @@ -137,9 +145,7 @@ logclose(dev, flag) LOG_LOCK(); log_open = 0; selwakeup(&logsoftc.sc_selp); - oldpri = splhigh(); selthreadclear(&logsoftc.sc_selp); - splx(oldpri); LOG_UNLOCK(); return (0); } @@ -154,42 +160,57 @@ logread(dev, uio, flag) 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) { - splx(s); - return (EWOULDBLOCK); + error = EWOULDBLOCK; + goto out; } if (logsoftc.sc_state & LOG_NBIO) { - splx(s); - return (EWOULDBLOCK); + error = EWOULDBLOCK; + goto out; } 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, - "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; - 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 = min(l, uio->uio_resid); + l = min(l, uio_resid(uio)); 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); + LOG_LOCK(); 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); } @@ -201,19 +222,19 @@ logselect(dev, rw, wql, p) void * wql; struct proc *p; { - int s = splhigh(); switch (rw) { case FREAD: + LOG_LOCK(); if (msgbufp->msg_bufr != msgbufp->msg_bufx) { - splx(s); + LOG_UNLOCK(); return (1); } selrecord(p, &logsoftc.sc_selp, wql); + LOG_UNLOCK(); break; } - splx(s); return (0); } @@ -224,24 +245,26 @@ logwakeup() int pgid; boolean_t funnel_state; - if (!log_open) + LOG_LOCK(); + if (!log_open) { + LOG_UNLOCK(); return; - funnel_state = thread_funnel_set(kernel_flock, TRUE); + } 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); + LOG_LOCK(); } 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 @@ -256,19 +279,18 @@ klogwakeup() /*ARGSUSED*/ int -logioctl(com, data, flag) +logioctl(dev, com, data, flag) caddr_t data; { long l; int s; + LOG_LOCK(); switch (com) { /* return number of characters immediately available */ case FIONREAD: - s = splhigh(); l = msgbufp->msg_bufx - msgbufp->msg_bufr; - splx(s); if (l < 0) l += MSG_BSIZE; *(off_t *)data = l; @@ -289,28 +311,28 @@ logioctl(com, data, flag) break; case TIOCSPGRP: - LOG_LOCK(); logsoftc.sc_pgid = *(int *)data; - LOG_UNLOCK(); break; case TIOCGPGRP: - LOG_LOCK(); *(int *)data = logsoftc.sc_pgid; - LOG_UNLOCK(); break; default: + LOG_UNLOCK(); return (-1); } + LOG_UNLOCK(); return (0); } void -log_init() +bsd_log_init() { - msgbufp = &temp_msgbuf; - LOG_LOCK_INIT(); + if (!log_inited) { + msgbufp = &temp_msgbuf; + log_inited = 1; + } } void @@ -318,8 +340,10 @@ log_putc(char c) { 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) { @@ -334,4 +358,6 @@ log_putc(char c) _logentrypend = 1; if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE) mbp->msg_bufx = 0; + LOG_UNLOCK(); } +