Skip to content

Linux port hdd timers2 #8

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Dec 12, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 27 additions & 22 deletions os/linux_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
#define __OS_LINUX_BASE__

// #include <sys/event.h>
#include <sys/user.h>

// marker for hacks we have made to make progress
#define __LINUX_PORT_HDD__ 1
Expand Down Expand Up @@ -76,34 +77,41 @@ struct voucher_offsets_s {
};


// Print a warning when an unported code path executes.
#define LINUX_PORT_ERROR() do { printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",__FILE__,__LINE__,__FUNCTION__); } while (0)

/*
* Stub out defines for other missing types
*/

// Pulled from OS X man page for kevent
struct kevent64_s {
uint64_t ident; /* identifier for this event */
int16_t filter; /* filter for event */
uint16_t flags; /* general flags */
uint32_t fflags; /* filter-specific flags */
int64_t data; /* filter-specific data */
uint64_t udata; /* opaque user data identifier */
uint64_t ext[2]; /* filter-specific extensions */
};

#if __linux__
// we fall back to use kevent
#define kevent64_s kevent
#define kevent64(kq,cl,nc,el,ne,f,to) kevent(kq,cl,nc,el,ne,to)
#endif

// PAGE_SIZE and SIZE_T_MAX should not be hardcoded like this here.
#define PAGE_SIZE (4096)
// SIZE_T_MAX should not be hardcoded like this here.
#define SIZE_T_MAX (0x7fffffff)

// Define to 0 the NOTE_ values that are not present on Linux.
// Revisit this...would it be better to ifdef out the uses instead??
#define NOTE_VM_PRESSURE 0
#define NOTE_ABSOLUTE 0
#define NOTE_NSECONDS 0
#define NOTE_LEEWAY 0
#define NOTE_CRITICAL 0
#define NOTE_BACKGROUND 0

// The following values are passed as part of the EVFILT_TIMER requests

#define IGNORE_KEVENT64_EXT /* will force the kevent64_s.ext[] to not be used -> leeway ignored */

#define NOTE_SECONDS 0x01
#define NOTE_USECONDS 0x02
#define NOTE_NSECONDS 0x04
#define NOTE_ABSOLUTE 0x08
#define NOTE_CRITICAL 0x10
#define NOTE_BACKGROUND 0x20
#define NOTE_LEEWAY 0x40

// need to catch the following usage if it happens ..
// we simply return '0' as a value probably not correct

#define NOTE_VM_PRESSURE ({LINUX_PORT_ERROR(); 0;})

/*
* Stub out misc linking and compilation attributes
Expand Down Expand Up @@ -135,8 +143,5 @@ struct kevent64_s {
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(a,b,c,d,msg) //


// Print a warning when an unported code path executes.
#define LINUX_PORT_ERROR() do { printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",__FILE__,__LINE__,__FUNCTION__); } while (0)


#endif /* __OS_LINUX_BASE__ */
5 changes: 0 additions & 5 deletions src/shims/linux_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,6 @@ int sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
LINUX_PORT_ERROR();
}

int kevent64(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents,unsigned int flags, const struct timespec *timeout)
{
return kevent(kq,changelist,nchanges,eventlist,nevents,timeout);
}

/*
* Stubbed out static data
*/
Expand Down
50 changes: 42 additions & 8 deletions src/source.c
Original file line number Diff line number Diff line change
Expand Up @@ -1858,6 +1858,47 @@ _dispatch_timers_get_delay(uint64_t nows[], struct dispatch_timer_s timer[],
return ridx;
}


#ifdef __linux__
// in linux we map the _dispatch_kevent_qos_s to struct kevent instead
// of struct kevent64. We loose the kevent.ext[] members and the time
// out is based on relavite msec based time vs. absolute nsec based time.
// For now we make the adjustments right here until the solution
// to either extend libkqueue with a proper kevent64 API or removing kevent
// all together and move to a lower API (e.g. epoll or kernel_module.
// Also leeway is ignored.

static void
_dispatch_kevent_timer_set_delay(_dispatch_kevent_qos_s *ke, uint64_t delay,
uint64_t leeway, uint64_t nows[])
{
// call to return nows[]
_dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL);
// adjust nsec based delay to msec based and ignore leeway
delay /= 1000000L;
if ((int64_t)(delay) <= 0) {
delay = 1; // if value <= 0 the dispatch will stop
}
ke->data = (int64_t)delay;
}

#else

static void
_dispatch_kevent_timer_set_delay(_dispatch_kevent_qos_s *ke, uint64_t delay,
uint64_t leeway, uint64_t nows[])
{
delay += _dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL);
if (slowpath(_dispatch_timers_force_max_leeway)) {
ke->data = (int64_t)(delay + leeway);
ke->ext[1] = 0;
} else {
ke->data = (int64_t)delay;
ke->ext[1] = leeway;
}
}
#endif

static bool
_dispatch_timers_program2(uint64_t nows[], _dispatch_kevent_qos_s *ke,
unsigned int qos)
Expand All @@ -1881,14 +1922,7 @@ _dispatch_timers_program2(uint64_t nows[], _dispatch_kevent_qos_s *ke,
_dispatch_trace_next_timer_set(
TAILQ_FIRST(&_dispatch_kevent_timer[tidx].dk_sources), qos);
_dispatch_trace_next_timer_program(delay, qos);
delay += _dispatch_source_timer_now(nows, DISPATCH_TIMER_KIND_WALL);
if (slowpath(_dispatch_timers_force_max_leeway)) {
ke->data = (int64_t)(delay + leeway);
ke->ext[1] = 0;
} else {
ke->data = (int64_t)delay;
ke->ext[1] = leeway;
}
_dispatch_kevent_timer_set_delay(ke, delay, leeway, nows);
ke->flags |= EV_ADD|EV_ENABLE;
ke->flags &= ~EV_DELETE;
}
Expand Down