Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
57e1a9cd
Commit
57e1a9cd
authored
Nov 07, 2002
by
Davide Libenzi
Committed by
Linus Torvalds
Nov 07, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] The epoll saga continues ...
Proper wakeup code in ep_insert and ep_modify
parent
7ceefe99
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
32 additions
and
19 deletions
+32
-19
fs/eventpoll.c
fs/eventpoll.c
+32
-19
No files found.
fs/eventpoll.c
View file @
57e1a9cd
...
...
@@ -81,6 +81,10 @@
/* Maximum size of the hash in pages */
#define EP_MAX_HPAGES ((1 << EP_MAX_HASH_BITS) / EP_HENTRY_X_PAGE + 1)
/* Number of pages allocated for an "hbits" sized hash table */
#define EP_HASH_PAGES(hbits) ((int) ((1 << (hbits)) / EP_HENTRY_X_PAGE + \
((1 << (hbits)) % EP_HENTRY_X_PAGE ? 1: 0)))
/* Macro to allocate a "struct epitem" from the slab cache */
#define DPI_MEM_ALLOC() (struct epitem *) kmem_cache_alloc(dpi_cache, SLAB_KERNEL)
...
...
@@ -131,9 +135,6 @@ struct eventpoll {
/* Size of the hash */
unsigned
int
hashbits
;
/* Number of pages currently allocated for the hash */
int
nhpages
;
/* Pages for the "struct epitem" hash */
char
*
hpages
[
EP_MAX_HPAGES
];
};
...
...
@@ -261,9 +262,8 @@ static unsigned int ep_get_hash_bits(unsigned int hintsize)
{
unsigned
int
i
,
val
;
for
(
i
=
0
,
val
=
1
;
val
<
hintsize
&&
i
<
8
*
sizeof
(
int
);
i
++
,
val
<<=
1
);
return
i
<
EP_MIN_HASH_BITS
?
EP_MIN_HASH_BITS
:
(
i
>
EP_MAX_HASH_BITS
?
EP_MAX_HASH_BITS
:
i
);
for
(
i
=
0
,
val
=
1
;
val
<
hintsize
&&
i
<
EP_MAX_HASH_BITS
;
i
++
,
val
<<=
1
);
return
i
<
EP_MIN_HASH_BITS
?
EP_MIN_HASH_BITS
:
i
;
}
...
...
@@ -668,15 +668,13 @@ static int ep_init(struct eventpoll *ep, unsigned int hashbits)
INIT_LIST_HEAD
(
&
ep
->
rdllist
);
/* Hash allocation and setup */
hsize
=
1
<<
hashbits
;
ep
->
hashbits
=
hashbits
;
ep
->
nhpages
=
(
int
)
(
hsize
/
EP_HENTRY_X_PAGE
+
(
hsize
%
EP_HENTRY_X_PAGE
?
1
:
0
));
error
=
ep_alloc_pages
(
ep
->
hpages
,
ep
->
nhpages
);
error
=
ep_alloc_pages
(
ep
->
hpages
,
EP_HASH_PAGES
(
ep
->
hashbits
));
if
(
error
)
goto
eexit_1
;
/* Initialize hash buckets */
for
(
i
=
0
;
i
<
hsize
;
i
++
)
for
(
i
=
0
,
hsize
=
1
<<
hashbits
;
i
<
hsize
;
i
++
)
INIT_LIST_HEAD
(
ep_hash_entry
(
ep
,
i
));
return
0
;
...
...
@@ -728,7 +726,7 @@ static void ep_free(struct eventpoll *ep)
write_unlock_irqrestore
(
&
eplock
,
flags
);
/* Free hash pages */
ep_free_pages
(
ep
->
hpages
,
ep
->
nhpages
);
ep_free_pages
(
ep
->
hpages
,
EP_HASH_PAGES
(
ep
->
hashbits
)
);
}
...
...
@@ -844,8 +842,15 @@ static int ep_insert(struct eventpoll *ep, struct pollfd *pfd, struct file *tfil
revents
=
tfile
->
f_op
->
poll
(
tfile
,
&
pt
);
/* If the file is already "ready" we drop it inside the ready list */
if
((
revents
&
pfd
->
events
)
&&
!
EP_IS_LINKED
(
&
dpi
->
rdllink
))
list_add
(
&
dpi
->
rdllink
,
&
ep
->
rdllist
);
if
((
revents
&
pfd
->
events
)
&&
!
EP_IS_LINKED
(
&
dpi
->
rdllink
))
{
list_add_tail
(
&
dpi
->
rdllink
,
&
ep
->
rdllist
);
/* Notify waiting tasks that events are available */
if
(
waitqueue_active
(
&
ep
->
wq
))
wake_up
(
&
ep
->
wq
);
if
(
waitqueue_active
(
&
ep
->
poll_wait
))
wake_up
(
&
ep
->
poll_wait
);
}
write_unlock_irqrestore
(
&
ep
->
lock
,
flags
);
...
...
@@ -888,8 +893,16 @@ static int ep_modify(struct eventpoll *ep, struct epitem *dpi, unsigned int even
dpi
->
pfd
.
events
=
events
;
/* If the file is already "ready" we drop it inside the ready list */
if
((
revents
&
events
)
&&
EP_IS_LINKED
(
&
dpi
->
llink
)
&&
!
EP_IS_LINKED
(
&
dpi
->
rdllink
))
list_add
(
&
dpi
->
rdllink
,
&
ep
->
rdllist
);
if
((
revents
&
events
)
&&
EP_IS_LINKED
(
&
dpi
->
llink
)
&&
!
EP_IS_LINKED
(
&
dpi
->
rdllink
))
{
list_add_tail
(
&
dpi
->
rdllink
,
&
ep
->
rdllist
);
/* Notify waiting tasks that events are available */
if
(
waitqueue_active
(
&
ep
->
wq
))
wake_up
(
&
ep
->
wq
);
if
(
waitqueue_active
(
&
ep
->
poll_wait
))
wake_up
(
&
ep
->
poll_wait
);
}
write_unlock_irqrestore
(
&
ep
->
lock
,
flags
);
...
...
@@ -993,7 +1006,7 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync)
if
(
EP_IS_LINKED
(
&
dpi
->
rdllink
))
goto
is_linked
;
list_add
(
&
dpi
->
rdllink
,
&
ep
->
rdllist
);
list_add
_tail
(
&
dpi
->
rdllink
,
&
ep
->
rdllist
);
is_linked:
/*
...
...
@@ -1072,9 +1085,9 @@ static int ep_events_transfer(struct eventpoll *ep, struct pollfd *events, int m
EP_LIST_DEL
(
&
dpi
->
rdllink
);
/*
* If the item is not linked to the main has table this means that
* If the item is not linked to the main has
h
table this means that
* it's on the way to be removed and we don't want to send events
*
to
such file descriptor.
*
for
such file descriptor.
*/
if
(
!
EP_IS_LINKED
(
&
dpi
->
llink
))
continue
;
...
...
@@ -1125,7 +1138,7 @@ static int ep_events_transfer(struct eventpoll *ep, struct pollfd *events, int m
static
int
ep_poll
(
struct
eventpoll
*
ep
,
struct
pollfd
*
events
,
int
maxevents
,
int
timeout
)
{
int
res
=
0
,
eavail
;
int
res
,
eavail
;
unsigned
long
flags
;
long
jtimeout
;
wait_queue_t
wait
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment