Hi,
I know I promised this over three weeks ago, but things have been very busy for me lately.
This email is slightly long. Please please please read through it. I need help to get wineboot working automatically (a blocking issue for 0.9), and I need someone who understands both the server and the loading order to comment.
This is the first part of the required change. Applying it at the moment does not make sense, as I am not yet sure that this is the right one (it may make more sense to point the env at the .exe.so file rather than the wrapper - more about that in a second).
I am, more or less, ready to give up. Someone suggested I look at the way caching the font metrics delays normal load. Well, I tried. I'm not sure I got it right, though.
If I understand correctly, the way to go for wineboot to run is this: wineboot, upon first run, will aquire a system wide named mutex that means "I am working on it". If the mutex exists, it will block on it. Once it got it it will immediatly release it and exit.
If the mutext doesn't exist at all, it will aquire it and do it's magic. Once done it will release it, but not delete it, and exit. All that is left to do is that all programs must load wineboot as part of the startup. It may require modifying it to be a DLL instead of an EXE, but so be it.
Can someone who understands the server, and the interaction between the server and normal apps comment on this scheme?
Also, how do I at all make each and every prog load wineboot.dll?
Shachar
Shachar Shemesh wine-devel@sun.consumer.org.il writes:
Can someone who understands the server, and the interaction between the server and normal apps comment on this scheme?
Also, how do I at all make each and every prog load wineboot.dll?
IMO you are on the wrong track here. We definitely do not want to do boot processing every time an app starts, our startup times are already pathetic enough. There are three cases where boot processing should happen:
1) When an app reboots the system with ExitWindows 2) When the user explicitly requests it 3) At login time when starting the Unix desktop
2) and 3) are external to Wine, and are the responsibility of the user and/or the packager to make sure the proper scripts are modified. So this leaves 1) which is basically a CreateProcess("wineboot") at the end of ExitWindows.
I don't think we need to worry much about delaying other apps either; in case 2) we may want to display a message when everything is done, but otherwise I wouldn't worry about it.
Alexandre Julliard wrote:
Shachar Shemesh wine-devel@sun.consumer.org.il writes:
Can someone who understands the server, and the interaction between the server and normal apps comment on this scheme?
Also, how do I at all make each and every prog load wineboot.dll?
IMO you are on the wrong track here. We definitely do not want to do boot processing every time an app starts, our startup times are already pathetic enough. There are three cases where boot processing should happen:
When an app reboots the system with ExitWindows
When the user explicitly requests it
At login time when starting the Unix desktop
and 3) are external to Wine, and are the responsibility of the user
and/or the packager to make sure the proper scripts are modified. So this leaves 1) which is basically a CreateProcess("wineboot") at the end of ExitWindows.
I am working on different command line options for the different scenarios. I'm having some difficulties with what to do with 2 (I know what 1 and 3 should do).
I don't think we need to worry much about delaying other apps either; in case 2) we may want to display a message when everything is done, but otherwise I wouldn't worry about it.
The synchronization problem is only related to the pending rename option. This is guarenteed handled by Windows before any Win32 process starts. As such, it may (and is actually quite likely) to have a post-boot process depend on the renames being complete before it can work. Anything that is run from wineboot itself is handled, but I'm worried about external utils.
Shachar
Hi,
I've some major trouble with wine's thread implementation. We're porting a soundprocessing application to linux/wine. (It will run as Win32 app under wine in the first step). Sadly the wine thread implementation and/or the sheduler does not get the priorities right. The mission critical sound task will not get as much attention as it needs.
We've tried some hacks to improve it (increasing linux kernel priorities using set_sheduler/set_priorities) but this doesn't really fix the problem. Then we tried to make it even more ugly by creating a own thread using the clone() system call. This fixed the timeslice problem but opens up other strange problems. (Random crashes here and there). Most likely due to missing lock issues or something like that.
I would appreciate any hints which could make things run more smoothly! Basically 2 ways are left to go:
1. Fix the wine sheduler to obey priorities 2. Fix the thread (locking?) issues
Thanks a lot for any information!
Regards, Florian
Florian Schirmer wrote:
Hi,
I've some major trouble with wine's thread implementation. We're porting a soundprocessing application to linux/wine. (It will run as Win32 app under wine in the first step). Sadly the wine thread implementation and/or the sheduler does not get the priorities right. The mission critical sound task will not get as much attention as it needs.
We've tried some hacks to improve it (increasing linux kernel priorities using set_sheduler/set_priorities) but this doesn't really fix the problem. Then we tried to make it even more ugly by creating a own thread using the clone() system call. This fixed the timeslice problem but opens up other strange problems. (Random crashes here and there). Most likely due to missing lock issues or something like that.
I would appreciate any hints which could make things run more smoothly! Basically 2 ways are left to go:
- Fix the wine sheduler to obey priorities
- Fix the thread (locking?) issues
Thanks a lot for any information!
I wouldn't go for fixing the thread... Wine internals need to know when a thread is started, so using clone "in its back" will inevitabely lead to what you've seen => crashes around (except if the thread running clone doesn't do any Win32 calls, which I doubt if you're porting your app) so, 1/ may be a better approach (which actually isn't implemented). And it should use information from the Win32 thread API.
A+
Hi,
GetFileVersionInfoSizeA does not behave as described in my API documentation. It is supposed to set the second param (handle) to zero. Current wine implementation does not - it even sets a non zero value futher down sometimes. So i suggest to apply the following patch. (If setting handle to offset has some [undocumented] meaning the second part of the patch should be ommited.)
Thanks! Comments?
Bye, Florian
--- wine-20030219/dlls/version/info.c-old Wed Aug 14 23:04:54 2002 +++ wine-20030219/dlls/version/info.c Sun Mar 9 17:51:14 2003 @@ -438,6 +438,8 @@ DWORD WINAPI GetFileVersionInfoSizeA( LP
TRACE("(%s,%p)\n", debugstr_a(filename), handle );
+ if ( handle ) *handle = 0; + len = VERSION_GetFileVersionInfo_PE(filename, handle, 0, NULL); /* 0xFFFFFFFF means: file exists, but VERSION_INFO not found */ if(len == 0xFFFFFFFF) @@ -467,8 +469,6 @@ DWORD WINAPI GetFileVersionInfoSizeA( LP offset, sizeof( buf ), buf ); if (!ret) return 0;
- if ( handle ) *handle = offset; - if ( VersionInfoIs16( buf ) ) vffi = (VS_FIXEDFILEINFO *)VersionInfo16_Value( (VS_VERSION_INFO_STRUCT16 *)buf ); else
"Florian" == Florian Schirmer jolt@tuxbox.org writes:
Florian> Hi, GetFileVersionInfoSizeA does not behave as described in my Florian> API documentation. It is supposed to set the second param Florian> (handle) to zero. Current wine implementation does not - it Florian> even sets a non zero value futher down sometimes. So i suggest Florian> to apply the following patch. (If setting handle to offset has Florian> some [undocumented] meaning the second part of the patch should Florian> be ommited.)
Florian> Thanks! Comments?
Supply a test case.
Thanks
Hi,
I would appreciate any hints which could make things run more smoothly! Basically 2 ways are left to go:
- Fix the wine sheduler to obey priorities
- Fix the thread (locking?) issues
Thanks a lot for any information!
I wouldn't go for fixing the thread... Wine internals need to know when a thread is started, so using clone "in its back" will inevitabely lead to what you've seen => crashes around (except if the thread running clone doesn't do any Win32 calls, which I doubt if you're porting your app)
so, 1/ may be a better approach (which actually isn't implemented). And it should use information from the Win32 thread API.
Thanks a lot for your reply. I've added some Enter/LeaveCriticalSections calls around the handler and it seems to make things much better (but still far from beeing perfect).
What prevents wine from distributing timeslices correctly? Even if i renice/boost linux kernel sheduler of the whole wine process(es) things go wrong a lot. The processing thread gets way to small amount of attention.
Do you have some hints on how to boost the processing thread a bit? I'm perfectly happy with an (even ugly) hack. I've tried to identify the wine sheduler, but was unsuccesful :( Maybe you can point me in to right direction (file, line #)?
Thanks a lot!
Regards, Florian
Hi,
Do you have some hints on how to boost the processing thread a bit? I'm perfectly happy with an (even ugly) hack. I've tried to identify the wine sheduler, but was unsuccesful :( Maybe you can point me in to right direction (file, line #)?
Actually, Wine does not have a scheduler as such (well, it has a scheduler for 16-bit tasks, but not for 32-bit processes/threads). Wine threads are just normal Linux tasks created with clone(). The usual Linux scheduling rules should apply ...
Bye, Ulrich
Hi,
Actually, Wine does not have a scheduler as such (well, it has a scheduler for 16-bit tasks, but not for 32-bit processes/threads). Wine threads are just normal Linux tasks created with clone(). The usual Linux scheduling rules should apply ...
Thanks for pointing this out. While digging through the "scheduler" i noticed that wine creates the threads in exactly the same way (using clone) as i did in wines back. So i was wondering what actually is different. To sched some light onto it, i replaced my clone() call with wines CreateThread call. And guess what: it works very well without any trouble.
I haven't looked deeper into what has caused this trouble, but i suspect some sleeping/waiting trouble. The new thread proc (for both the clone and the CreateThread thread) does nothing except registering an alsa async callback handler and then sleeping (using linux native nanosleep) all the time. The old thread handler (which works pretty well on win32) probably calls in some sort if message handling loop. Using the native win32 Sleep() call instead of linux native nanosleep will break things again. So wine is unable to waste time in the proper way ;-)
Thanks _a lot_ to all who helped me with my issues.
Regards, Florian
"Florian Schirmer" jolt@tuxbox.org writes:
I haven't looked deeper into what has caused this trouble, but i suspect some sleeping/waiting trouble. The new thread proc (for both the clone and the CreateThread thread) does nothing except registering an alsa async callback handler and then sleeping (using linux native nanosleep) all the time. The old thread handler (which works pretty well on win32) probably calls in some sort if message handling loop. Using the native win32 Sleep() call instead of linux native nanosleep will break things again. So wine is unable to waste time in the proper way ;-)
Yes, it's a known issue, our Sleep() wastes a bit too much CPU for short waits. Something like this may help:
Index: scheduler/synchro.c =================================================================== RCS file: /opt/cvs-commit/wine/scheduler/synchro.c,v retrieving revision 1.45 diff -u -r1.45 synchro.c --- scheduler/synchro.c 26 Aug 2002 21:53:26 -0000 1.45 +++ scheduler/synchro.c 13 Mar 2003 18:05:47 -0000 @@ -184,6 +184,7 @@ VOID WINAPI Sleep( DWORD timeout ) { WaitForMultipleObjectsEx( 0, NULL, FALSE, timeout, FALSE ); + if (timeout <= 1) sched_yield(); }
/******************************************************************************
Florian Schirmer a écrit:
What prevents wine from distributing timeslices correctly? Even if i renice/boost linux kernel sheduler of the whole wine process(es) things go wrong a lot. The processing thread gets way to small amount of attention.
If you boost all threads, they'll fight among themselves, although they should have more than normal Linux processes.
Do you have some hints on how to boost the processing thread a bit? I'm perfectly happy with an (even ugly) hack. I've tried to identify the wine sheduler, but was unsuccesful :( Maybe you can point me in to right direction (file, line #)?
The scheduler seems to be in wine/scheduler. Specific files include scheduler/process.c and thread.c. thread.c mostly calls the wineserver for priorities, so you could also check in the server what it does with that.
Most probably nothing is ever done with the Win32 priorities.
Vincent
Hi,
If you boost all threads, they'll fight among themselves, although they should have more than normal Linux processes.
The app does a great job balancing the thread priorities. (It runs pretty well on any Win32 OS). Increasing the priority of the complete wine system seems to make things a bit better. But there is nothing running beside the app (except wine and the X server).
The scheduler seems to be in wine/scheduler. Specific files include scheduler/process.c and thread.c. thread.c mostly calls the wineserver for priorities, so you could also check in the server what it does with that.
Thanks, i will dig around a bit.
Most probably nothing is ever done with the Win32 priorities.
Mhh doh. Maybe i should hack the sheduler a bit.
Thanks a lot for you reply!
Regards, Florian
tir, 2003-03-11 kl. 23:10 skrev Florian Schirmer:
The scheduler seems to be in wine/scheduler. Specific files include scheduler/process.c and thread.c. thread.c mostly calls the wineserver for priorities, so you could also check in the server what it does with that.
Thanks, i will dig around a bit.
Most probably nothing is ever done with the Win32 priorities.
Mhh doh. Maybe i should hack the sheduler a bit.
The Linux scheduler, you mean? Wine doesn't schedule threads on its own, Win32 threads are just normal Linux threads. I'm sure we'd have done something with the Win32 priorities a long time ago if we thought it would work. But Linux doesn't allow a non-root process to increase its scheduling priority (and of course people shouldn't run Wine as root), so it mostly seemed to just be an exercise in futility, and that's why I think nobody has bothered. And I don't expect this to improve...
But Linux doesn't allow a non-root process to increase its scheduling priority
It ought to let you reduce it though....
David
ons, 2003-03-12 kl. 09:45 skrev David Laight:
But Linux doesn't allow a non-root process to increase its scheduling priority
It ought to let you reduce it though....
Yeah, I believe it does, but I don't think it'll let you increase it back to the original level afterwards. Anyway, the problem with doing that is, if Wine would somehow reduce the priority of all "normal" priority thread, and let "high-priority" threads run at original priority, then Wine processes would be at a significant scheduling disadvantage relative to ordinary Linux processes, and this could be even worse than the status quo. It might make sense to do this for "low-priority" threads though, but very few apps would create those.
The Linux scheduler, you mean? Wine doesn't schedule threads on its own, Win32 threads are just normal Linux threads. I'm sure we'd have done something with the Win32 priorities a long time ago if we thought it would work. But Linux doesn't allow a non-root process to increase its scheduling priority (and of course people shouldn't run Wine as root), so it mostly seemed to just be an exercise in futility, and that's why I think nobody has bothered. And I don't expect this to improve...
Is this what the POSIX caps work lets you do, ie assign capabilities with a finer degree of control than just root vs non-root.
Anyway, if this guy needs control of priorities for his app to work, then perhaps he just needs to run Wine as root and implement the priority switching code. Sucks, but then the whole root vs everybody else needs rethinking or improving anyway imho.
It does, see the nice(1), renice (8) commands and get/setpriority(2).
would work. But Linux doesn't allow a non-root process to increase its scheduling priority (and of course people shouldn't run Wine as root), so it mostly seemed to just be an exercise in futility, and
that's
why I think nobody has bothered. And I don't expect this to
improve...
===== Sylvain Petreolle spetreolle@users.sourceforge.net Fight Spam ! EuroCauce: http://www.euro.cauce.org/en/index.html ICQ #170597259
"Don't think you are. Know you are." Morpheus, in "Matrix".
___________________________________________________________ Do You Yahoo!? -- Une adresse @yahoo.fr gratuite et en français ! Yahoo! Mail : http://fr.mail.yahoo.com
Sylvain Petreolle wrote:
It does, see the nice(1), renice (8) commands and get/setpriority(2).
would work. But Linux doesn't allow a non-root process to increase its scheduling priority (and of course people shouldn't run Wine as root), so it mostly seemed to just be an exercise in futility, and that's why I think nobody has bothered. And I don't expect this toimprove...
Hmmm ... it seems to me that's exactly what they say: From the renice man page: Users other than the super-user may only alter the priority of processes they own, and can only monotonically increase their ``nice value'' within the range 0 to PRIO_MAX (20). (This prevents overriding administrative fiats.) The super-user may alter the priority of any process and set the priority to any value in the range PRIO_MIN (-20) to PRIO_MAX. BUGS Non super-users can not increase scheduling priorities of their own pro cesses, even if they were the ones that decreased the priorities in the first place. From the setpriority man page: The setpriority call sets the priorities of all of the specified processes to the specified value. Only the super-user may lower priorities.
Do yours say anything other? David
tor, 2003-03-13 kl. 08:38 skrev Sylvain Petreolle:
It does, see the nice(1), renice (8) commands and get/setpriority(2).
Yes, they all support what I'm saying: a non-root process cannot increase its scheduling priority (in the common meaning of "priority", not the inversed sense that renice and setpriority use, of course, if that wasn't obvious).