Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-cw
Commits
b0750422
Commit
b0750422
authored
Sep 30, 2020
by
Piotr Caban
Committed by
Alexandre Julliard
Sep 30, 2020
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
winmm: Avoid allocations in timeSetEvent.
Signed-off-by:
Piotr Caban
<
piotr@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
39968ccd
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
55 additions
and
67 deletions
+55
-67
time.c
dlls/winmm/time.c
+55
-67
No files found.
dlls/winmm/time.c
View file @
b0750422
...
...
@@ -30,13 +30,11 @@
#include "winemm.h"
#include "wine/list.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
mmtime
);
typedef
struct
tagWINE_TIMERENTRY
{
struct
list
entry
;
UINT
wDelay
;
UINT
wResol
;
LPTIMECALLBACK
lpFunc
;
/* can be lots of things */
...
...
@@ -46,7 +44,8 @@ typedef struct tagWINE_TIMERENTRY {
DWORD
dwTriggerTime
;
}
WINE_TIMERENTRY
,
*
LPWINE_TIMERENTRY
;
static
struct
list
timer_list
=
LIST_INIT
(
timer_list
);
static
WINE_TIMERENTRY
timers
[
16
];
static
UINT
timers_created
;
static
CRITICAL_SECTION
TIME_cbcrst
;
static
CRITICAL_SECTION_DEBUG
critsect_debug
=
...
...
@@ -60,17 +59,6 @@ static CRITICAL_SECTION TIME_cbcrst = { &critsect_debug, -1, 0, 0, 0, 0 };
static
HANDLE
TIME_hMMTimer
;
static
CONDITION_VARIABLE
TIME_cv
;
/* link timer at the appropriate spot in the list */
static
inline
void
link_timer
(
WINE_TIMERENTRY
*
timer
)
{
WINE_TIMERENTRY
*
next
;
LIST_FOR_EACH_ENTRY
(
next
,
&
timer_list
,
WINE_TIMERENTRY
,
entry
)
if
((
int
)(
next
->
dwTriggerTime
-
timer
->
dwTriggerTime
)
>=
0
)
break
;
list_add_before
(
&
next
->
entry
,
&
timer
->
entry
);
}
/*
* Some observations on the behavior of winmm on Windows.
*
...
...
@@ -119,8 +107,8 @@ static inline void link_timer( WINE_TIMERENTRY *timer )
*/
static
int
TIME_MMSysTimeCallback
(
void
)
{
WINE_TIMERENTRY
*
timer
,
*
to_free
;
int
delta_time
;
WINE_TIMERENTRY
*
timer
,
copy
;
int
i
,
delta_time
;
/* since timeSetEvent() and timeKillEvent() can be called
* from 16 bit code, there are cases where win16 lock is
...
...
@@ -136,25 +124,30 @@ static int TIME_MMSysTimeCallback(void)
for
(;;)
{
struct
list
*
ptr
=
list_head
(
&
timer_list
);
if
(
!
ptr
)
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
timers
);
i
++
)
if
(
timers
[
i
].
wTimerID
)
break
;
if
(
i
==
ARRAY_SIZE
(
timers
))
return
-
1
;
timer
=
timers
+
i
;
for
(
i
++
;
i
<
ARRAY_SIZE
(
timers
);
i
++
)
{
delta_time
=
-
1
;
break
;
if
(
!
timers
[
i
].
wTimerID
)
continue
;
if
(
timers
[
i
].
dwTriggerTime
<
timer
->
dwTriggerTime
)
timer
=
timers
+
i
;
}
timer
=
LIST_ENTRY
(
ptr
,
WINE_TIMERENTRY
,
entry
);
delta_time
=
timer
->
dwTriggerTime
-
timeGetTime
();
if
(
delta_time
>
0
)
break
;
list_remove
(
&
timer
->
entry
);
if
(
timer
->
wFlags
&
TIME_PERIODIC
)
{
timer
->
dwTriggerTime
+=
timer
->
wDelay
;
link_timer
(
timer
);
/* restart it */
to_free
=
NULL
;
}
else
to_free
=
timer
;
else
{
copy
=
*
timer
;
timer
->
wTimerID
=
0
;
timer
=
&
copy
;
}
switch
(
timer
->
wFlags
&
(
TIME_CALLBACK_EVENT_SET
|
TIME_CALLBACK_EVENT_PULSE
))
{
...
...
@@ -181,7 +174,6 @@ static int TIME_MMSysTimeCallback(void)
}
break
;
}
HeapFree
(
GetProcessHeap
(),
0
,
to_free
);
}
return
delta_time
;
}
...
...
@@ -281,36 +273,37 @@ DWORD WINAPI timeGetTime(void)
MMRESULT
WINAPI
timeSetEvent
(
UINT
wDelay
,
UINT
wResol
,
LPTIMECALLBACK
lpFunc
,
DWORD_PTR
dwUser
,
UINT
wFlags
)
{
WORD
wNewID
=
0
;
LPWINE_TIMERENTRY
lpNewTimer
;
LPWINE_TIMERENTRY
lpTimer
;
WORD
new_id
=
0
;
int
i
;
TRACE
(
"(%u, %u, %p, %08lX, %04X);
\n
"
,
wDelay
,
wResol
,
lpFunc
,
dwUser
,
wFlags
);
if
(
wDelay
<
MMSYSTIME_MININTERVAL
||
wDelay
>
MMSYSTIME_MAXINTERVAL
)
return
0
;
lpNewTimer
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
WINE_TIMERENTRY
));
if
(
lpNewTimer
==
NULL
)
return
0
;
lpNewTimer
->
wDelay
=
wDelay
;
lpNewTimer
->
dwTriggerTime
=
timeGetTime
()
+
wDelay
;
EnterCriticalSection
(
&
WINMM_cs
);
/* FIXME - wResol is not respected, although it is not clear
that we could change our precision meaningfully */
lpNewTimer
->
wResol
=
wResol
;
lpNewTimer
->
lpFunc
=
lpFunc
;
lpNewTimer
->
dwUser
=
dwUser
;
lpNewTimer
->
wFlags
=
wFlags
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
timers
);
i
++
)
if
(
!
timers
[
i
].
wTimerID
)
break
;
if
(
i
==
ARRAY_SIZE
(
timers
))
{
LeaveCriticalSection
(
&
WINMM_cs
);
return
0
;
}
EnterCriticalSection
(
&
WINMM_cs
);
new_id
=
ARRAY_SIZE
(
timers
)
*
(
++
timers_created
)
+
i
;
if
(
!
new_id
)
new_id
=
ARRAY_SIZE
(
timers
)
*
(
++
timers_created
)
+
i
;
LIST_FOR_EACH_ENTRY
(
lpTimer
,
&
timer_list
,
WINE_TIMERENTRY
,
entry
)
wNewID
=
max
(
wNewID
,
lpTimer
->
wTimerID
)
;
timers
[
i
].
wDelay
=
wDelay
;
timers
[
i
].
dwTriggerTime
=
timeGetTime
()
+
wDelay
;
link_timer
(
lpNewTimer
);
lpNewTimer
->
wTimerID
=
wNewID
+
1
;
/* FIXME - wResol is not respected, although it is not clear
that we could change our precision meaningfully */
timers
[
i
].
wResol
=
wResol
;
timers
[
i
].
lpFunc
=
lpFunc
;
timers
[
i
].
dwUser
=
dwUser
;
timers
[
i
].
wFlags
=
wFlags
;
timers
[
i
].
wTimerID
=
new_id
;
TIME_MMTimeStart
();
...
...
@@ -319,9 +312,9 @@ MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc,
/* Wake the service thread in case there is work to be done */
WakeConditionVariable
(
&
TIME_cv
);
TRACE
(
"=> %u
\n
"
,
wNewID
+
1
);
TRACE
(
"=> %u
\n
"
,
new_id
);
return
wNewID
+
1
;
return
new_id
;
}
/**************************************************************************
...
...
@@ -329,35 +322,30 @@ MMRESULT WINAPI timeSetEvent(UINT wDelay, UINT wResol, LPTIMECALLBACK lpFunc,
*/
MMRESULT
WINAPI
timeKillEvent
(
UINT
wID
)
{
WINE_TIMERENTRY
*
lpSelf
=
NULL
,
*
lpT
imer
;
DWORD
wF
lags
;
WINE_TIMERENTRY
*
t
imer
;
WORD
f
lags
;
TRACE
(
"(%u)
\n
"
,
wID
);
EnterCriticalSection
(
&
WINMM_cs
);
/* remove WINE_TIMERENTRY from list */
LIST_FOR_EACH_ENTRY
(
lpTimer
,
&
timer_list
,
WINE_TIMERENTRY
,
entry
)
timer
=
&
timers
[
wID
%
ARRAY_SIZE
(
timers
)];
if
(
timer
->
wTimerID
!=
wID
)
{
if
(
wID
==
lpTimer
->
wTimerID
)
{
lpSelf
=
lpTimer
;
list_remove
(
&
lpTimer
->
entry
);
break
;
}
LeaveCriticalSection
(
&
WINMM_cs
);
WARN
(
"wID=%u is not a valid timer ID
\n
"
,
wID
);
return
TIMERR_NOCANDO
;
}
if
(
list_empty
(
&
timer_list
))
WakeConditionVariable
(
&
TIME_cv
);
timer
->
wTimerID
=
0
;
flags
=
timer
->
wFlags
;
LeaveCriticalSection
(
&
WINMM_cs
);
if
(
!
lpSelf
)
if
(
flags
&
TIME_KILL_SYNCHRONOUS
)
{
WARN
(
"wID=%u is not a valid timer ID
\n
"
,
wID
);
return
MMSYSERR_INVALPARAM
;
}
wFlags
=
lpSelf
->
wFlags
;
if
(
wFlags
&
TIME_KILL_SYNCHRONOUS
)
EnterCriticalSection
(
&
TIME_cbcrst
);
HeapFree
(
GetProcessHeap
(),
0
,
lpSelf
);
if
(
wFlags
&
TIME_KILL_SYNCHRONOUS
)
LeaveCriticalSection
(
&
TIME_cbcrst
);
}
WakeConditionVariable
(
&
TIME_cv
);
return
TIMERR_NOERROR
;
}
...
...
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