Proceedings of the FREENIX Track: 2004 USENIX Annual Technical Conference
Total Page:16
File Type:pdf, Size:1020Kb
USENIX Association Proceedings of the FREENIX Track: 2004 USENIX Annual Technical Conference Boston, MA, USA June 27–July 2, 2004 © 2004 by The USENIX Association All Rights Reserved For more information about the USENIX Association: Phone: 1 510 528 8649 FAX: 1 510 548 5738 Email: [email protected] WWW: http://www.usenix.org Rights to individual papers remain with the author or the author's employer. Permission is granted for noncommercial reproduction of the work for educational or research purposes. This copyright notice must be included in the reproduced paper. USENIX acknowledges all trademarks herein. How Xlib is Implemented (And What We're Doing About It) Jamey Sharp Computer Science Department Portland State University Portland, OR USA 97207–0751 [email protected] http://xcb.freedesktop.org Abstract side implementation of the X protocol, with goals of im- proving the usability of X in several cases: The X Window System is the de facto standard graph- • Resource-constrained environments, such as PDAs. ical environment for Linux and Unix hosts, and is usable • Developers wanting to understand how X works. on nearly any class of computer one could find today. Its • Developers implementing X protocol extensions. success is partially due to its flexible, extensible design. • Users desiring better-performing applications. Unfortunately, as research proceeds on cutting-edge window system functionality, the brittleness of the un- Xlib spans more than 400 source files, contains more derlying software is a critical impediment to progress. than 150,000 lines of code, and compiles to a roughly Xlib, the client-side implementation of the network pro- 750kB shared library on Linux/i386. On a typical Linux tocol that underlies X, is one source of these issues. system, this puts Xlib among the top libraries as mea- Many developers working on new features in the X pro- sured by code size. tocol are discovering that Xlib requires changes to sup- This paper has several major parts: a tour of Xlib, port these features, but Xlib makes those changes diffi- an explanation of several current efforts to improve X, cult. For more than 15 years, new features have been some observations on software engineering, and a brief added to Xlib by accretion, rather than with careful de- glimpse at the future. sign. We discuss the implementation of Xlib and analyze 2 The Architecture of Xlib some specific difficulties in it that cause problems in un- As we are not aware of a comprehensive tour of the Xlib derstanding and maintaining this code base. We also source, we present one here. present our current work on migrating the X Window Xlib stores more than a kilobyte of data about each System to a more maintainable, carefully designed ar- X server connection in a structure named a Display. chitecture. This includes • 1 Introduction The file descriptor and other information about the transport. At the core of the X Window System [SG86] is a net- • Other file descriptors to monitor for new data. work protocol, allowing any number of X applications • An assortment of values cached from the server. running on far-flung machines to interact with a single • Pointers used for internal memory management. keyboard, mouse, and monitor. Nearly all applications • Function pointers to hooks. currently use Xlib [SGFR92], a C library dating to the The hooks in Xlib allow extensions and applications to mid-1980s, to interact with the X protocol. modify the way Xlib handles Software developers have collectively learned a lot • about the engineering of software in the decades since Thread synchronization. • X was created. This fact explains some, though not all, Conversion between wire protocol and C structures. • of the difficulties that users and developers experience XID allocation. • when working with X. (Other issues are explained later Management of graphics contexts and server fonts. • in this paper.) Our previous work on a new X-protocol C Buffer flushes. • Binding [MS01] and subsequently an Xlib Compatibil- Connection close. ity Layer [SM02] were efforts to apply current best prac- When an X client successfully establishes a connec- tices in software engineering to the core of the client- tion to a server, the server sends several hundred bytes cut buffers gc image icccm i18n Much of the code in this layer comes from xtrans, a xom module comprising several .c and .h files. Code that resource db cms xkb utility xlc uses xtrans instantiates it in one of several variants by defining an appropriate C preprocessor macro before in- xim protocol cluding not just Xtrans.h, but also transport.c. core protocol events Available variants are X11, XSERV, Xim, FS, Font, Ice, transport region TEST, and LBXPROXY: while there are occasional sub- Figure 1: Notional Xlib components: arrows indicate tle differences, these variants differ mostly in symbol “using” relationships names. Xlib uses two variants of xtrans, X11Trans and Xim- Trans, meaning that all of the code in xtrans is linked of information about the capabilities of the display. Xlib into Xlib twice. The first variant is used in the transport copies some of that information into the Display; the rest layer, while the second is used by X input methods. We is kept in other structures pointed to by the Display. focus on the first of these here. Once connection setup is complete, requests from the Nothing in the extension libraries and applications client and responses from the server are the fundamen- that we have tested uses X11Trans directly. Within Xlib, tal elements of the X protocol. Requests always have calls to X11Trans are confined to four source files: Xlib- a “major opcode” identifying the kind of request, and a Int.c, OpenDis.c, ConnDis.c, and ClDisplay.c. As a re- length field that measures the number of four-byte words sult, rewriting Xlib to eliminate references to X11Trans needed to contain the entire packet. Responses come in is a relatively straightforward task. three forms: replies, events, and errors. Replies and er- rors are sent in response to requests, while events are 2.1.2 Protocol Layer sent spontaneously. On a Cray supercomputer, memory is not addressable in Only some request types call for a reply, but for any single-byte increments: in fact, it is addressable only in of those requests, a reply is always sent, unless an er- 64-bit increments. In X requests and responses, how- ror is sent instead. Errors can also occur for other re- ever, 32-bit values are aligned to 32-bit boundaries, 16- quests. Since X has a network-transparent protocol, it bit values to 16-bit boundaries, and so on. On a Cray, may be run on high-latency connections such as dial-up then, accessing individual components of a request or or DSL Internet links, and on these links replies take response is inefficient. long enough to arrive that the delay may have a notice- Xlib is designed to unpack the wire protocol data from able effect on application performance. In analyzing this responses into structures that may be efficiently accessed aspect of X performance, we speak of round-trip latency, by the host, and to similarly pack data into requests. and look for techniques to avoid or hide it [PG03]. Many parts of the protocol are represented by a pair Xlib was originally written without much concern for of structures in Xlib, namely the wire protocol struc- type-safety, but with great care to minimize the number ture and the host structure. By convention, the names of of function calls. As a result, the C preprocessor gets wire structures are of the form xIDReq for requests and heavy use when compiling Xlib. Many of the most com- xIDReply for replies, with various IDs, and in general monly executed statements in Xlib are macros. components of these structures correspond only to argu- 2.1 Xlib Layers ments to functions. The core event wire type is xEvent and corresponds to host structures named XIDEvent. As shown in Figure 1, Xlib can be thought of as having The core error wire type is xError, and corresponds to several distinct layers and components. An analysis of XErrorEvent. the size of these notional components is in Section 6.2. For all of the wire protocol structures, C preprocessor Unfortunately, within the code the boundaries are not symbols with names like sz xEvent are defined equal as clear as is suggested by the figure. In fact, we are to the number of bytes that the structure occupies on the not aware of any previous efforts to describe Xlib in this wire. Request structures also have their opcode (major if manner. However, these boundaries will be useful in our core, minor if extension) in #defines. Structures have analysis of Xlib, and correspond to the vocabulary com- fixed-length parts, but no variable-length representation. monly used in conversation among Xlib developers. When Xlib accesses a Display, perhaps to construct a request or process a response, it must protect the Dis- 2.1.1 Transport Layer play against simultaneous accesses by other threads. The The transport layer is responsible for conveying requests LockDisplay and UnlockDisplay macros are provided and responses between the X client and server. This for this purpose. All access to a Display must be brack- layer is independent of the semantics of those packets. eted by a LockDisplay and UnlockDisplay pair. To deliver a request to the server, Xlib must allocate GC are truly different on the client than on the server. both a sequence number and a block of memory to con- The FlushGC macro hides these details. struct the request in. Both of these allocations are han- It is frequently convenient to have a standardized set dled by the GetReq macro or its variants: GetResReq, of strings for inter-client communications, but prefer- GetEmptyReq, and GetReqExtra.