Speeding up wineserver (again)

Troy Rollo wine at troy.rollo.name
Mon Jul 7 21:27:52 CDT 2003

I've been looking at the various efforts over the years to speed up wineserver 
or eliminate it altogether (by substituting a kernel service). Certainly the 
current degree of reliance on a separate process that is scheduled according 
to the operating system's own priorities creates significant speed problems. 
Some of this migh be alleviated by boosting the priority of the wineserver 
process or by making it a real time task, but there are still some operations 
it appears to be performing some operations that result in a yield and hence 
subject it to another wait in the queue for at least one time slice.

Even if the wineserver itself could be sped up in this way, individual 
processes would stull be subjected to time waiting in the queue after they 
make a request of wineserver. The problem becomes more severe on a heavily 
loaded system.

The approaches suggested so far:

	Shared memory

		Suffers from reliability problems which may allow one
		process to put the system in an inconsistent state.

	Kernel module

		The only effort so far seemed to put way too much
		into the kernel, and was abandoned over two years

Other possible approaches that I haven't seen directly discussed on the 
wine-devel list:

	An exokernel using the x86 multiring capability

		Not portable to non-x86 architectures.

	Cross-process calls

		Also referred to under other names. This mechanism would
		allow one process to call into another process without
		giving up part of its time slice. Would require modifications
		to the kernel's scheduler and to standard kernel data
	        structures, hence would have to be considered "rude". It
		would have one advantage in that the interface
		differences between this mechanism and the current
		mechanism could be transparent.

Have I missed any?

Anyway, I'm thinking that perhaps the kernel module approach was the right 
basic approach, but that the particular attempt made was merely too broad. A 
better approach would be to define a set of kernel calls that could be used 
to implement all of the other stuff (and there are currently 176 types of 
wineserver request, so I haven't taken the time to see if I've covered them 
all yet) in an in-process library.

Transparency substitution for wineserver would, I guess, be achieved by having 
the kernel module and its supporting library implement the wineserver 
requests using the wineserver data structures, and perhaps having wineserver 
use a non-kernel version of these facilities.

The following are things I could see immediately would be part of the kernel 

	winekernel_attach_to_kernel(char const *kernid);

	winekernel_object winekernel_object_create(
					char const *name,
					void const *data,
					size_t size);

	winekernel_object winekernel_object_open(
					char const *name);

	int		winekernel_object_close(
					winekernel_object obj);

	int		winekernel_object_namesize(
					winekernel_object obj);

	int		winekernel_object_getname(
					winekernel_object obj,
					char *name,
					size_t bufsize);
	size_t	winekernel_object_size(
					winekernel_object obj);

	int		winekernel_object_getdata(
					winekernel_object obj,
					void *buffer,
					size_t bufsize);

	int		winekernel_object_setdata(
					winekernel_object obj,
					void *buffer,
					size_t bufsize,
					size_t offset);

	int		winekernel_object_lockobject(
					winekernel_object obj,
					int flags);

	int		winekernel_object_unlock(
					winekernel_object obj);

	int		winekernel_object_setacl(
					winekernel_object obj,
					wineserver_acl *acl);

	int		winekernel_object_attach_native_file(
					winekernel_object obj,
					int fd);

	int		winekernel_object_get_native_file(
					winekernel_object obj);

	int		winekernel_object_list(
					char *namespace,
					char *data,
					int	bytes,
					int	*bytesneeded,
					int	flags);

There would be other things that would be in the "nice to have" category too 
(I'm thinking specifically about path name translation being done in a way 
that requires less seeks through the file system).

The way I see this working is that Wine kernel objects are stored (strangely 
enough) in kernel memory. This effectively amounts to a shared memory 
approach but with the kernel module able to clean up after a misbehaving 
process. In the event that cleanups after a misbehaving process were to be 
too complex, there would still be room for a server process that does this, 
and the kernel could simply assign ownership of the objects from the bad 
process to the server process, which gets notified via another set of calls 
when it receives the objects. The object name would be of the form 
"namespace:name", so as to have:


A process could allow the kernel to assign the name within the namespace, so 
that, for example:

	obj = winekernel_object_create("window", windowdata, windowdata_size);
	winekernel_object_gername(obj, achHWND, 15);

The idea behind the "wine_attach_to_kernel" call would be to allow for the 
kernel to serve either multiple different users or multiple different Windows 
operating system types without the objects from all of them being 

More information about the wine-devel mailing list