Skip to content

Commit 53a8aa6

Browse files
committed
Merge branch 'linux-port-hdd' of github.ibm.com:ibmswift/swift-corelibs-libdispatch into linux-port-hdd
2 parents b02031c + cff30c4 commit 53a8aa6

File tree

2 files changed

+111
-13
lines changed

2 files changed

+111
-13
lines changed

os/linux_base.h

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#define __OS_LINUX_BASE__
2121

2222
// #include <sys/event.h>
23+
#include <sys/user.h>
2324

2425
// marker for hacks we have made to make progress
2526
#define __LINUX_PORT_HDD__ 1
@@ -76,6 +77,9 @@ struct voucher_offsets_s {
7677
};
7778

7879

80+
// Print a warning when an unported code path executes.
81+
#define LINUX_PORT_ERROR() do { printf("LINUX_PORT_ERROR_CALLED %s:%d: %s\n",__FILE__,__LINE__,__FUNCTION__); } while (0)
82+
7983
/*
8084
* Stub out defines for other missing types
8185
*/
@@ -91,19 +95,29 @@ struct kevent64_s {
9195
uint64_t ext[2]; /* filter-specific extensions */
9296
};
9397

98+
int kevent64(int kq, /*const*/ struct kevent64_s *changelist, int nchanges, struct kevent64_s *eventlist,
99+
int nevents, unsigned int flags, const struct timespec *timeout);
94100

95-
// PAGE_SIZE and SIZE_T_MAX should not be hardcoded like this here.
96-
#define PAGE_SIZE (4096)
101+
// SIZE_T_MAX should not be hardcoded like this here.
97102
#define SIZE_T_MAX (0x7fffffff)
98103

99104
// Define to 0 the NOTE_ values that are not present on Linux.
100105
// Revisit this...would it be better to ifdef out the uses instead??
101-
#define NOTE_VM_PRESSURE 0
102-
#define NOTE_ABSOLUTE 0
103-
#define NOTE_NSECONDS 0
104-
#define NOTE_LEEWAY 0
105-
#define NOTE_CRITICAL 0
106-
#define NOTE_BACKGROUND 0
106+
107+
// The following values are passed as part of the EVFILT_TIMER requests
108+
109+
#define NOTE_SECONDS 0x01
110+
#define NOTE_USECONDS 0x02
111+
#define NOTE_NSECONDS 0x04
112+
#define NOTE_ABSOLUTE 0x08
113+
#define NOTE_CRITICAL 0x10
114+
#define NOTE_BACKGROUND 0x20
115+
#define NOTE_LEEWAY 0x40
116+
117+
// need to catch the following usage if it happens ..
118+
// we simply return '0' as a value probably not correct
119+
120+
#define NOTE_VM_PRESSURE ({LINUX_PORT_ERROR(); 0;})
107121

108122
/*
109123
* Stub out misc linking and compilation attributes
@@ -135,8 +149,5 @@ struct kevent64_s {
135149
#define __OSX_AVAILABLE_BUT_DEPRECATED_MSG(a,b,c,d,msg) //
136150

137151

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

142153
#endif /* __OS_LINUX_BASE__ */

src/shims/linux_stubs.c

Lines changed: 89 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,96 @@ int sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
8484
LINUX_PORT_ERROR();
8585
}
8686

87-
int kevent64(int kq, const struct kevent *changelist, int nchanges, struct kevent *eventlist, int nevents,unsigned int flags, const struct timespec *timeout)
87+
88+
DISPATCH_NOINLINE
89+
static const char *
90+
_evfiltstr(short filt)
91+
{
92+
switch (filt) {
93+
#define _evfilt2(f) case (f): return #f
94+
_evfilt2(EVFILT_READ);
95+
_evfilt2(EVFILT_WRITE);
96+
_evfilt2(EVFILT_AIO);
97+
_evfilt2(EVFILT_VNODE);
98+
_evfilt2(EVFILT_PROC);
99+
_evfilt2(EVFILT_SIGNAL);
100+
_evfilt2(EVFILT_TIMER);
101+
#if HAVE_MACH
102+
_evfilt2(EVFILT_MACHPORT);
103+
_evfilt2(DISPATCH_EVFILT_MACH_NOTIFICATION);
104+
#endif
105+
_evfilt2(EVFILT_FS);
106+
_evfilt2(EVFILT_USER);
107+
#ifdef EVFILT_VM
108+
_evfilt2(EVFILT_VM);
109+
#endif
110+
#ifdef EVFILT_SOCK
111+
_evfilt2(EVFILT_SOCK);
112+
#endif
113+
#ifdef EVFILT_MEMORYSTATUS
114+
_evfilt2(EVFILT_MEMORYSTATUS);
115+
#endif
116+
117+
_evfilt2(DISPATCH_EVFILT_TIMER);
118+
_evfilt2(DISPATCH_EVFILT_CUSTOM_ADD);
119+
_evfilt2(DISPATCH_EVFILT_CUSTOM_OR);
120+
default:
121+
return "EVFILT_missing";
122+
}
123+
}
124+
125+
#if 0
126+
#define dbg_kevent64(fmt...) do { printf(fmt); } while(0)
127+
#define dbg_cond_kevent64(cond,fmt...) do { if (cond) printf(fmt); } while(0)
128+
#else
129+
#define dbg_kevent64(fmt...) do { } while(0)
130+
#define dbg_cond_kevent64(cond,fmt...) do { } while(0)
131+
#endif
132+
133+
#include <time.h>
134+
135+
int kevent64(int kq, /*const*/ struct kevent64_s *changelist, int nchanges, struct kevent64_s *eventlist,
136+
int nevents, unsigned int flags, const struct timespec *timeout)
88137
{
89-
return kevent(kq,changelist,nchanges,eventlist,nevents,timeout);
138+
// Documentation is not really clear. Instrument the code to make sure
139+
// we can do type conversions right now between kevent64 <-> kevent, where as
140+
// kevent64 uses the ext[2] extension. So far we only see these used in the EVFILT_TIMER.
141+
// right now we do this in the way into kevent, we also have to assert that
142+
// no more than 1 change or one event is passed until we get a better handle of the
143+
// usage pattern of this. (Hubertus Franke)
144+
145+
#if 1
146+
// lets put some checks in here to make sure we do it all correct
147+
// we can only convert kevent64_s -> kevent for a single entry since kevent64_s has ext[0:1] extension
148+
if ((nchanges > 1) || (nevents > 1))
149+
LINUX_PORT_ERROR();
150+
if (nchanges) {
151+
dbg_kevent64("kevent64(%s,%x,%x): cl.ext[0,1]=%lx:%ld %lx:%ld cl.data=%lx:%ld\n",
152+
_evfiltstr(changelist->filter), changelist->flags, changelist->fflags,
153+
changelist->ext[0], changelist->ext[0],
154+
changelist->ext[1], changelist->ext[1],
155+
changelist->data, changelist->data);
156+
if ((changelist->filter == EVFILT_TIMER) && (changelist->fflags & NOTE_ABSOLUTE)) {
157+
// NOTE_ABSOLUTE is not recognized by the current kevent we need to convert this
158+
// into a relative. Consider fiddling with creating relative events instead (didn't work
159+
// on first attempt). We also ignore the LEEWAY. Finally we must convert from
160+
// NSECS to MSECS (might have to expand to deal with OTHER NOTE_xSECS flags
161+
162+
changelist->data -= _dispatch_get_nanoseconds();
163+
//changelist->data -= time(NULL) * NSEC_PER_SEC;
164+
dbg_kevent64("kevent64(%s,%x) data=%lx:%ld\n",
165+
_evfiltstr(changelist->filter),changelist->fflags,
166+
changelist->data,changelist->data);
167+
changelist->data /= 1000000UL;
168+
if ((int64_t)(changelist->data) <= 0) changelist->data = 1; // for some reason time turns negative
169+
}
170+
}
171+
#endif
172+
// eventlist can not return more than 1 event type coersion doesn't work
173+
int rc = kevent(kq,(struct kevent*) changelist,nchanges,(struct kevent*) eventlist,nevents,timeout);
174+
if (rc > 1)
175+
LINUX_PORT_ERROR();
176+
return rc;
90177
}
91178

92179
/*

0 commit comments

Comments
 (0)