Skip to content

Commit

Permalink
Merge pull request swiftlang#8 from dgrove-oss/linux-port-hdd-timers2
Browse files Browse the repository at this point in the history
Linux port hdd timers2
  • Loading branch information
MadCoder committed Dec 12, 2015
2 parents 8904f45 + 8b0e8f8 commit 6dbebd6
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 35 deletions.
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

0 comments on commit 6dbebd6

Please sign in to comment.