freebsd11_network: Avoid triggering timer interrupts 1000 times/sec.
FreeBSD's "ticks" has a granularity of whatever "hz" is, presently 1000. It's declared as "extern int32" in FreeBSD's codebase, as it's the defining unit of time for most operations. We just use system_time() for essentially the same purpose, which requires no hard-clock timer interrupts at all, and so Colin seems to have decided to emulate "ticks" by just triggering a timer once per millisecond and then incrementing the "ticks" variable. 1000 timer interrupts per second is quite a lot (assuming the kernel actually combined these between drivers, otherwise it would be 1000 *per driver*), and probably a contributor to Haiku's not-so-great battery performance on most laptops.
This commit is contained in:
@@ -5,12 +5,11 @@
|
||||
*/
|
||||
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#include <lock.h>
|
||||
#include <thread.h>
|
||||
|
||||
extern "C" {
|
||||
# include "device.h"
|
||||
# include <sys/callout.h>
|
||||
# include <sys/mutex.h>
|
||||
}
|
||||
@@ -176,7 +175,7 @@ callout_init_mtx(struct callout *c, struct mtx *mtx, int flags)
|
||||
|
||||
|
||||
int
|
||||
callout_reset(struct callout *c, int ticks, void (*func)(void *), void *arg)
|
||||
callout_reset(struct callout *c, int _ticks, void (*func)(void *), void *arg)
|
||||
{
|
||||
int canceled = callout_stop(c);
|
||||
|
||||
@@ -192,7 +191,7 @@ callout_reset(struct callout *c, int ticks, void (*func)(void *), void *arg)
|
||||
if (c->due <= 0)
|
||||
list_add_item(&sTimers, c);
|
||||
|
||||
c->due = system_time() + ticks_to_usecs(ticks);
|
||||
c->due = system_time() + ticks_to_usecs(_ticks);
|
||||
|
||||
// notify timer about the change if necessary
|
||||
if (sTimeout > c->due)
|
||||
@@ -204,9 +203,9 @@ callout_reset(struct callout *c, int ticks, void (*func)(void *), void *arg)
|
||||
|
||||
|
||||
int
|
||||
callout_schedule(struct callout *callout, int ticks)
|
||||
callout_schedule(struct callout *callout, int _ticks)
|
||||
{
|
||||
return callout_reset(callout, ticks, callout->c_func, callout->c_arg);
|
||||
return callout_reset(callout, _ticks, callout->c_func, callout->c_arg);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,44 +1,14 @@
|
||||
/*
|
||||
* Copyright 2009, Colin Günther, [email protected]
|
||||
* All rights reserved. Distributed under the terms of the MIT License.
|
||||
* Copyright 2018, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include "device.h"
|
||||
|
||||
#include <OS.h>
|
||||
#include <compat/sys/kernel.h>
|
||||
|
||||
|
||||
int32 ticks;
|
||||
static timer sHardClockTimer;
|
||||
|
||||
|
||||
/*!
|
||||
* Implementation of FreeBSD's hardclock timer.
|
||||
*/
|
||||
static int32
|
||||
hardClock(timer* hardClockTimer)
|
||||
int32_t
|
||||
get_ticks()
|
||||
{
|
||||
atomic_add(&ticks, 1);
|
||||
return B_HANDLED_INTERRUPT;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
* Initialization of the hardclock timer which ticks according to hz defined in
|
||||
* compat/sys/kernel.h.
|
||||
*/
|
||||
status_t
|
||||
init_hard_clock()
|
||||
{
|
||||
ticks = 0;
|
||||
return add_timer(&sHardClockTimer, hardClock, ticks_to_usecs(1),
|
||||
B_PERIODIC_TIMER);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
uninit_hard_clock()
|
||||
{
|
||||
cancel_timer(&sHardClockTimer);
|
||||
return usecs_to_ticks(system_time());
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
void callout_init(struct callout *c, int mpsafe);
|
||||
void callout_init_mtx(struct callout *c, struct mtx *mutex, int flags);
|
||||
/* Time values are in ticks, see compat/sys/kernel.h for its definition */
|
||||
int callout_schedule(struct callout *c, int ticks);
|
||||
int callout_reset(struct callout *c, int ticks, void (*func)(void *), void *arg);
|
||||
int callout_schedule(struct callout *c, int _ticks);
|
||||
int callout_reset(struct callout *c, int _ticks, void (*func)(void *), void *arg);
|
||||
int callout_pending(struct callout *c);
|
||||
int callout_active(struct callout *c);
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2007-2009 Haiku Inc. All rights reserved.
|
||||
* Copyright 2007-2018, Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _FBSD_COMPAT_SYS_KERNEL_H_
|
||||
@@ -14,22 +14,22 @@
|
||||
#include <sys/queue.h>
|
||||
|
||||
|
||||
/*
|
||||
*
|
||||
* The rate at which FreeBSD can generate callouts (kind of timeout mechanism).
|
||||
/* The rate at which FreeBSD can generate callouts (kind of timeout mechanism).
|
||||
* For FreeBSD 8 this is typically 1000 times per second (100 for ARM).
|
||||
* This value is defined in a file called subr_param.c
|
||||
*
|
||||
* WHile Haiku can have a much higher granularity, it is not a good idea to have
|
||||
* While Haiku can have a much higher granularity, it is not a good idea to have
|
||||
* this since FreeBSD tries to do certain tasks based on ticks, for instance
|
||||
* autonegotiation and wlan scanning.
|
||||
* Suffixing LL prevents integer overflows during calculations.
|
||||
* as it defines a long long constant.*/
|
||||
* as it defines a long long constant. */
|
||||
#define hz 1000LL
|
||||
|
||||
#define ticks_to_usecs(t) (1000000*((bigtime_t)t) / hz)
|
||||
int32_t get_ticks();
|
||||
#define ticks (get_ticks())
|
||||
|
||||
extern int32 ticks;
|
||||
#define ticks_to_usecs(t) (1000000*((bigtime_t)t) / hz)
|
||||
#define usecs_to_ticks(t) (((bigtime_t)t*hz) / 1000000)
|
||||
|
||||
|
||||
typedef void (*system_init_func_t)(void *);
|
||||
|
||||
@@ -38,7 +38,7 @@ void taskqueue_block(struct taskqueue *queue);
|
||||
void taskqueue_unblock(struct taskqueue *queue);
|
||||
int taskqueue_enqueue(struct taskqueue *tq, struct task *task);
|
||||
int taskqueue_enqueue_timeout(struct taskqueue *queue,
|
||||
struct timeout_task *ttask, int ticks);
|
||||
struct timeout_task *ttask, int _ticks);
|
||||
int taskqueue_cancel(struct taskqueue *queue, struct task *task,
|
||||
u_int *pendp);
|
||||
int taskqueue_cancel_timeout(struct taskqueue *queue,
|
||||
|
||||
@@ -113,10 +113,6 @@ _fbsd_init_drivers(driver_t *drivers[])
|
||||
if (get_module(B_PCI_X86_MODULE_NAME, (module_info **)&gPCIx86) != B_OK)
|
||||
gPCIx86 = NULL;
|
||||
|
||||
status = init_hard_clock();
|
||||
if (status < B_OK)
|
||||
goto err1;
|
||||
|
||||
status = init_mutexes();
|
||||
if (status < B_OK)
|
||||
goto err2;
|
||||
@@ -207,8 +203,6 @@ err4:
|
||||
err3:
|
||||
uninit_mutexes();
|
||||
err2:
|
||||
uninit_hard_clock();
|
||||
err1:
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
if (gPCIx86 != NULL)
|
||||
put_module(B_PCI_X86_MODULE_NAME);
|
||||
@@ -236,7 +230,6 @@ _fbsd_uninit_drivers(driver_t *drivers[])
|
||||
uninit_callout();
|
||||
uninit_mbufs();
|
||||
uninit_mutexes();
|
||||
uninit_hard_clock();
|
||||
|
||||
put_module(B_PCI_MODULE_NAME);
|
||||
if (gPCIx86 != NULL)
|
||||
|
||||
@@ -345,7 +345,7 @@ taskqueue_timeout_func(void *arg)
|
||||
|
||||
int
|
||||
taskqueue_enqueue_timeout(struct taskqueue *queue,
|
||||
struct timeout_task *ttask, int ticks)
|
||||
struct timeout_task *ttask, int _ticks)
|
||||
{
|
||||
int res;
|
||||
cpu_status status;
|
||||
@@ -359,7 +359,7 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
|
||||
/* Do nothing */
|
||||
tq_unlock(queue, status);
|
||||
res = -1;
|
||||
} else if (ticks == 0) {
|
||||
} else if (_ticks == 0) {
|
||||
tq_unlock(queue, status);
|
||||
taskqueue_enqueue(queue, &ttask->t);
|
||||
} else {
|
||||
@@ -368,12 +368,12 @@ taskqueue_enqueue_timeout(struct taskqueue *queue,
|
||||
} else {
|
||||
queue->tq_callouts++;
|
||||
ttask->f |= DT_CALLOUT_ARMED;
|
||||
if (ticks < 0)
|
||||
ticks = -ticks; /* Ignore overflow. */
|
||||
if (_ticks < 0)
|
||||
_ticks = -_ticks; /* Ignore overflow. */
|
||||
}
|
||||
tq_unlock(queue, status);
|
||||
if (ticks > 0) {
|
||||
callout_reset(&ttask->c, ticks,
|
||||
if (_ticks > 0) {
|
||||
callout_reset(&ttask->c, _ticks,
|
||||
taskqueue_timeout_func, ttask);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user