/*
- * 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@
*/
#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/file.h>
+#include <sys/file_internal.h>
#include <sys/errno.h>
#include <sys/select.h>
+#include <sys/kernel.h>
#include <kern/thread.h>
+#include <sys/lock.h>
#define LOG_RDPRI (PZERO + 1)
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)
LOG_LOCK();
log_open = 0;
selwakeup(&logsoftc.sc_selp);
- oldpri = splhigh();
selthreadclear(&logsoftc.sc_selp);
- splx(oldpri);
LOG_UNLOCK();
return (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) {
- 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);
}
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);
}
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
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;
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
{
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) {
_logentrypend = 1;
if (mbp->msg_bufx < 0 || mbp->msg_bufx >= MSG_BSIZE)
mbp->msg_bufx = 0;
+ LOG_UNLOCK();
}
+