Hello all,
For the past week or so I've been getting to know Wine and trying to improve/fix the FreeBSD version. I've progressed somewhat since then, though there are still quite a few open issues.
One of the problems on FreeBSD is that Wine is loaded at 0x7bf00000. FreeBSD's mmap preserves some space for the data segment (about 512Mb by default) and every future call to mmap with NULL for the addr argument maps memory after that. This is the reason that win98 mode doesn't work, since the shared heap at 0x80000000 isn't available and everything that gets dlopen'ed for instance is located beyond the 2G limit which some programs may not like.
So I was thinking of moving Wine to 0x20000000. That would be the easiest solution by far, but, are there any potential problems with that?
Tijl Coosemans tijl@ulyssis.org writes:
So I was thinking of moving Wine to 0x20000000. That would be the easiest solution by far, but, are there any potential problems with that?
Yes, that's too low, apps can expect that address to be free. If you can't change the 512Mb thing then you should use something around 0x50000000, but really the 0x70000000 range would be preferable.
On Monday 31 July 2006 16:22, Alexandre Julliard wrote:
Tijl Coosemans tijl@ulyssis.org writes:
So I was thinking of moving Wine to 0x20000000. That would be the easiest solution by far, but, are there any potential problems with that?
Yes, that's too low, apps can expect that address to be free. If you can't change the 512Mb thing then you should use something around 0x50000000, but really the 0x70000000 range would be preferable.
I can lower the 512Mb with setrlimit and RLIMIT_DATA, but that would have to happen inside the preloader (using a direct syscall I suppose), which currently isn't used on FreeBSD and probably doesn't even work. So I'll add that to my todo list and use something in the 0x50000000 range for now.
On Monday 31 July 2006 18:15, Tijl Coosemans wrote:
On Monday 31 July 2006 16:22, Alexandre Julliard wrote:
Tijl Coosemans tijl@ulyssis.org writes:
So I was thinking of moving Wine to 0x20000000. That would be the easiest solution by far, but, are there any potential problems with that?
Yes, that's too low, apps can expect that address to be free. If you can't change the 512Mb thing then you should use something around 0x50000000, but really the 0x70000000 range would be preferable.
I can lower the 512Mb with setrlimit and RLIMIT_DATA, but that would have to happen inside the preloader (using a direct syscall I suppose), which currently isn't used on FreeBSD and probably doesn't even work. So I'll add that to my todo list and use something in the 0x50000000 range for now.
It turns out I don't need the preloader for that...
Currently I lower RLIMIT_DATA to 0x18000000 (384Mb) in wine-glibc and locate wine-pthread at 0x64000000. Is this an acceptable location?
There has to be enough room after wine-pthread + data segment for every lib and dlopen'ed object. Moreover, the data segment can't be too small because it's the malloc heap and the limit is inherited by the wineserver process. So this is a bit of a balancing act.
Tijl Coosemans tijl@ulyssis.org writes:
Currently I lower RLIMIT_DATA to 0x18000000 (384Mb) in wine-glibc and locate wine-pthread at 0x64000000. Is this an acceptable location?
There has to be enough room after wine-pthread + data segment for every lib and dlopen'ed object. Moreover, the data segment can't be too small because it's the malloc heap and the limit is inherited by the wineserver process. So this is a bit of a balancing act.
It seems it would be preferable to set a much lower limit and raise it again before starting wineserver. Otherwise it creates a big range of memory that will be inaccessible to Windows apps, and force us to relocate pretty much all native dlls.
On Tuesday 08 August 2006 20:05, Alexandre Julliard wrote:
Tijl Coosemans tijl@ulyssis.org writes:
Currently I lower RLIMIT_DATA to 0x18000000 (384Mb) in wine-glibc and locate wine-pthread at 0x64000000. Is this an acceptable location?
There has to be enough room after wine-pthread + data segment for every lib and dlopen'ed object. Moreover, the data segment can't be too small because it's the malloc heap and the limit is inherited by the wineserver process. So this is a bit of a balancing act.
It seems it would be preferable to set a much lower limit and raise it again before starting wineserver. Otherwise it creates a big range of memory that will be inaccessible to Windows apps, and force us to relocate pretty much all native dlls.
Only the super-user can increase the max limit. Other users can only decrease it. And all those unix shared libs (x11, etc.) need heap space as well. I don't know how much they all need. Maybe a 128Mb heap would be sufficient? That would bring us to 0x74000000.
The other solution I guess would be to add a malloc implementation to libwine that overrides libc malloc. Maybe there are other platforms with older brk(2) style malloc implementation that could benefit from this as well? FreeBSD 7.0 has a more modern brk+mmap style malloc btw, so evetually this problem will disappear.
Tijl Coosemans tijl@ulyssis.org writes:
Only the super-user can increase the max limit. Other users can only decrease it. And all those unix shared libs (x11, etc.) need heap space as well. I don't know how much they all need. Maybe a 128Mb heap would be sufficient? That would bring us to 0x74000000.
Do you need to set the max limit? Isn't the current limit sufficient?
On Tuesday 08 August 2006 23:28, Alexandre Julliard wrote:
Tijl Coosemans tijl@ulyssis.org writes:
Only the super-user can increase the max limit. Other users can only decrease it. And all those unix shared libs (x11, etc.) need heap space as well. I don't know how much they all need. Maybe a 128Mb heap would be sufficient? That would bring us to 0x74000000.
Do you need to set the max limit? Isn't the current limit sufficient?
No, it's the max limit. The FreeBSD kernel code is pretty clear on that:
if (addr == 0 || (addr >= round_page((vm_offset_t)vms->vm_taddr) && addr < round_page((vm_offset_t)vms->vm_daddr + lim_max(td->td_proc, RLIMIT_DATA))))
addr = round_page((vm_offset_t)vms->vm_daddr + lim_max(td->td_proc, RLIMIT_DATA));
So, when the addr argument to mmap is NULL or somewhere in the text segment or maximum possible data segment it is pushed back to after the data segment, which of course works quite well for any normal unix program.
Anyway, the situation is different in FreeBSD 7.0, so I need to think this over some more and do some more testing.