a configurable multimedia middleware platform

15
Experience demonstrates the benefits and feasibility of supporting multimedia applications in distributed middleware architectures. However, deployment of multimedia-capable middleware platforms has not yet occurred on a large scale. This article describes designing such a platform and its attempts to maximize performance, predictability, and configurability in a standard workstation operating-system environment. E xperience indicates both the benefits and feasibility of supporting multime- dia applications in distributed middle- ware architectures such as the Object Management Group’s (OMG) Corba (Common Object Request Broker Architecture). 1 The poten- tial benefits of such support to application devel- opers include provision of high-level programming abstrac- tions for multimedia communications, includ- ing quality-of-service (QoS) specification and management, and seamless integration of multimedia with con- ventional distributed interactions. In addition, the research community has demon- strated the feasibility of such support through implementation of a number of Corba-based, multimedia-capable, experimental middleware platforms (discussed later). 2-5 Regardless, the large-scale deployment of such platforms seems unlikely in the short term. One major obstacle to deployment is the lack of stan- dardization of appropriate programming abstrac- tions. Despite guidelines available in the International Standardization Organization’s (ISO) Reference Model for Open Distributed Processing, the OMG has not yet seriously addressed the issue. The OMG’s response to demands for multimedia support in Corba (mainly from the telecommuni- cations community) has been the Telecom SIG’s “Control and Management of Audio/Video Streams” standard. 1 In my view, this represents a short-term solution to the problem because it doesn’t treat continuous media as first-class data types. 6 In the long run, I believe a more integrated approach to multimedia support will be required. The other major obstacle lies in the engineering of multimedia middleware platforms. How best to structure middleware to achieve optimal QoS man- agement remains poorly understood, particularly in terms of performance, predictability (in terms of timeliness), and configurability. 6 It helps to distinguish static and dynamic aspects of QoS management. 7 Static aspects involve QoS specification, mapping, negotiation, and resource allocation at connection setup time. Dynamic aspects concern managing allocated resources at data transfer time to ensure continu- ous maintenance of required QoS levels. This article focuses primarily on dynamic QoS management issues. In particular, I describe low- level concurrency and communications mecha- nisms designed to maximize performance and predictability in multimedia middleware. I imple- mented these mechanisms in a multimedia mid- dleware platform called GOPI (Generic Object Platform Infrastructure). GOPI attempts to deliv- er (as best it can) performance and predictability in a configurable manner in a standard operating system environment. I also designed it for back- ward compatibility with Corba. System support for multimedia middleware Modern network-capable operating systems provide a system call interface rich in functional- ity but difficult to use and prone to error. Multimedia middleware therefore builds higher level abstractions on top of the operating system- level application programmer’s interface (API) to ease the application developer’s task. The key challenge involves providing useful abstractions without compromising performance and pre- dictability. This requires careful use of the operat- ing system-level facilities. I’ll discuss the ways in which GOPI addresses this challenge later. First, I briefly review the facilities typically found in mod- ern operating systems. From a middleware implementation perspec- tive, the most important system services fall under the headings of concurrency, communications, and event (or signal) handling. In addition, mul- timedia middleware heavily exploits calls to man- age memory resources and optimized local 62 1070-986X/99/$10.00 © 1999 IEEE A Configurable Multimedia Middleware Platform Geoff Coulson Lancaster University Feature Article .

Upload: g

Post on 13-Mar-2017

214 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: A configurable multimedia middleware platform

Experiencedemonstrates thebenefits andfeasibility ofsupportingmultimediaapplications indistributedmiddlewarearchitectures.However,deployment ofmultimedia-capablemiddlewareplatforms has not yetoccurred on a largescale. This articledescribes designingsuch a platform andits attempts tomaximizeperformance,predictability, andconfigurability in astandard workstationoperating-systemenvironment.

Experience indicates both the benefitsand feasibility of supporting multime-dia applications in distributed middle-ware architectures such as the Object

Management Group’s (OMG) Corba (CommonObject Request Broker Architecture).1 The poten-tial benefits of such support to application devel-opers include

❚ provision of high-level programming abstrac-tions for multimedia communications, includ-ing quality-of-service (QoS) specification andmanagement, and

❚ seamless integration of multimedia with con-ventional distributed interactions.

In addition, the research community has demon-strated the feasibility of such support throughimplementation of a number of Corba-based,multimedia-capable, experimental middlewareplatforms (discussed later).2-5

Regardless, the large-scale deployment of suchplatforms seems unlikely in the short term. Onemajor obstacle to deployment is the lack of stan-dardization of appropriate programming abstrac-tions. Despite guidelines available in theInternational Standardization Organization’s (ISO)Reference Model for Open Distributed Processing,the OMG has not yet seriously addressed the issue.The OMG’s response to demands for multimediasupport in Corba (mainly from the telecommuni-cations community) has been the Telecom SIG’s

“Control and Management of Audio/VideoStreams” standard.1 In my view, this represents ashort-term solution to the problem because itdoesn’t treat continuous media as first-class datatypes.6 In the long run, I believe a more integratedapproach to multimedia support will be required.The other major obstacle lies in the engineering ofmultimedia middleware platforms. How best tostructure middleware to achieve optimal QoS man-agement remains poorly understood, particularlyin terms of performance, predictability (in termsof timeliness), and configurability.6

It helps to distinguish static and dynamicaspects of QoS management.7 Static aspectsinvolve QoS specification, mapping, negotiation,and resource allocation at connection setup time.Dynamic aspects concern managing allocatedresources at data transfer time to ensure continu-ous maintenance of required QoS levels.

This article focuses primarily on dynamic QoSmanagement issues. In particular, I describe low-level concurrency and communications mecha-nisms designed to maximize performance andpredictability in multimedia middleware. I imple-mented these mechanisms in a multimedia mid-dleware platform called GOPI (Generic ObjectPlatform Infrastructure). GOPI attempts to deliv-er (as best it can) performance and predictabilityin a configurable manner in a standard operatingsystem environment. I also designed it for back-ward compatibility with Corba.

System support for multimediamiddleware

Modern network-capable operating systemsprovide a system call interface rich in functional-ity but difficult to use and prone to error.Multimedia middleware therefore builds higherlevel abstractions on top of the operating system-level application programmer’s interface (API) toease the application developer’s task. The keychallenge involves providing useful abstractionswithout compromising performance and pre-dictability. This requires careful use of the operat-ing system-level facilities. I’ll discuss the ways inwhich GOPI addresses this challenge later. First, Ibriefly review the facilities typically found in mod-ern operating systems.

From a middleware implementation perspec-tive, the most important system services fall underthe headings of concurrency, communications,and event (or signal) handling. In addition, mul-timedia middleware heavily exploits calls to man-age memory resources and optimized local

62 1070-986X/99/$10.00 © 1999 IEEE

A ConfigurableMultimediaMiddlewarePlatform

Geoff CoulsonLancaster University

Feature Article

.

Page 2: A configurable multimedia middleware platform

interprocess communications (IPC) services suchas shared memory or FIFOs.

The main concurrency-related services arethose associated with kernel threads (threads sup-ported natively by the operating system). Theseinclude calls to create kernel threads, synchro-nization calls on mutexes and semaphores, andthread-safe libraries (libraries whose non-reentrantroutines are implicitly protected with mutexes).In addition, system designers often provide prim-itive facilities to support user-level threads (threadssupported in a user-level library outside the oper-ating system). In SunOS 5.5, for example, themakecontext() and swapcontext() calls allowa user-level thread library to manage the CPU stateof user-level threads. Machine instructions suchas test-and-set or compare-and-swap also proveuseful as a building block for synchronizationprimitives in user-level thread packages.

Communications center on the socket abstrac-tion. All modern operating systems have calls tocreate network sockets, to bind them to address-es, and to write and read data on them in either ablocking or nonblocking fashion. In addition, ascatter/gather I/O facility (often but not alwaysprovided) permits writing or reading structureddata to or from a socket in a single call when thedata resides in noncontiguous memory. Finally,system designers usually provide an I/O multi-plexing call to determine which sockets canaccept I/O or to block (with an optional timeout)until one or more sockets are ready.

Event-handling services inform user software ofasynchronous events in the operating system, suchas alarm expiration, periodic timing signals, or I/Oavailability on sockets. Event-masking calls protectcritical user-level sections from interruption byasynchronous events. Although notoriouslyobtuse, event semantics provide a potentially use-ful service because they let the middleware learnof events in a (relatively) timely fashion withoutthe overhead of polling with system calls.

GOPI’s structureAt the coarsest level of granularity GOPI sepa-

rates into two subsystems, both realized as run-time libraries linked with applications: the APIpersonality and the GOPI core. The API personal-ity presents GOPI core services to the applicationin terms of some standard interface such as Corba,with appropriate extensions for the multimediafunctionality. Since the API personality does notsignificantly affect performance and predictabili-ty, I don’t consider it further in this article; see

elsewhere2 for more details. The core services pre-sent the following low-level API (http://www.comp.lancs.ac.uk/computing/users/geoff/GOPI/index.html):

❚ Calls to manage location-independent commu-nication endpoints, called irefs, and to bindthese (using first- or third-party binding) accord-ing to a specified QoS, using a stack of user-selected application-specific protocols (ASPs).

❚ Calls to send and receive data in bothrequest/reply and streaming mode, on boundirefs; the API optionally uses upcalls of appli-cation-defined handlers to obtain and deliverdata in addition to the traditional downcall-based style of call.

❚ Calls to create and manage threads in associa-tion with application scheduler contexts(ASCs); calls to create and manage semaphoresand timers; and calls to create and managebuffers and communicate them betweenthreads in the same address space via channels.

I implemented the GOPI core as a set of inde-pendent modules: base, a collection of generallyuseful foundation programming classes; thread, a

63

January–M

arch 1999

.

Glossary of TermsAPI application programmer’s interfaceASC application scheduler contextASP application specific protocolCorba Common Object Request Broker ArchitectureDimma APM Ltd. project addressing multimedia support in distributed

object platormsFIFO first in, first out bufferGOPI Generic Object Platform InfrastructureIIOP Internet inter-ORB protocolIP Internet protocolIPC interprocess communicationsISO International Standardization OrganizationMPEG Moving Pictures Experts Groupmutex locking primitive implementing mutual exclusionOMG Object Management GroupQoS quality-of-serviceRetina European Commision-funded project to design a Corba platform

featuring streams and QoS extensionsTAO Corba 2.0-compliant platform running on real-time operating

systemsTCP transport control protocolUDP user datagram protocol

Page 3: A configurable multimedia middleware platform

“real-time” concurrency package; msg, a “real-time” interthread message-passing and bufferpackage; comm, an architecture for accommodat-ing ASPs; and bind, a module supporting irefs,plus a binding, or connection management, pro-tocol with QoS negotiation capabilities. Eachmodule constitutes a separate library with mini-mal dependencies. For example, the thread mod-ule works as a stand-alone package, and youcould replace the bind module without affectingthe comm module.

Written mainly in C, GOPI runs on a variety ofUnix platforms. The core consists of approxi-mately 12,000 lines of code. A detailed descriptionof the system including the API and the function-ality of the various modules appears elsewhere.2

ConcurrencyNext I’ll consider the elements supporting con-

currency in GOPI.

API overviewThe following call—provided by the core GOPI

API—creates threads:

int thread_create(Func f, int arg,

ASC scheduler, CharSeq *params);

The f argument specifies a function for thenewly created thread to execute, and the argargument specifies a parameter to pass to thisfunction. The remaining arguments let the callerselect an ASC for the thread and assign per-ASCscheduling parameters (such as priority, deadline,and period). Calling an ASC-specific routine pre-specifies the scheduling parameters by mar-shalling ASC-specific parameters p1, p2, ..., pn into aCharSeq (character sequence) data structure:

void <ascname>_buildparams(CharSeq

*params, <p1>, <p2>, ..., <pn>);

Another call modifies the current thread’s ASCand scheduling parameters:

bool thread_change(ASC newscheduler,

CharSeq *newparams);

For synchronization, the threads module pro-vides semaphores and associated thread_P()and thread_V() operations. A timeout variant ofthe thread_P() operation (similar to the Posixcond_timedwait() service) assists in controllingtemporal behavior:

bool thread_P_timeout(SemId sem,

long uS);

This returns FALSE if the return resulted from atimeout and TRUE if the return occurred as a con-sequence of a thread_V() operation invoked byanother thread. The call thread_yield() explic-itly yields the CPU and causes a context switch.The thread_exit() call destroys the callingthread.

The thread module additionally supports anarbitrary number of per-thread timers. The call toset a timer follows:

int thread_timerset(Function

timerfunc, long uS);

This call invokes the function timerfunc, inthe context of the calling thread, after uSmicroseconds have elapsed. The system returnsthe timer’s identifier as a reference to pass to relat-ed calls that stop the timer or read its elapsedtime.

Threads and virtual processorsInternally, GOPI uses a two-level concurrency

architecture that multiplexes user-level threads ontop of kernel threads. I call kernel threads virtualprocessors in the GOPI context. Virtual processorsspend their lives in an endless loop, repeatedlytaking a user-level thread context from an ASCand executing it until it either yields or is pre-empted (see below). The number of virtual proces-sors per capsule potentially affects performanceand predictability (again, see below), but not thedegree of user-thread concurrency available toGOPI or its applications. In particular, a capsulewith a single virtual processor can support an arbi-trary number of user-level threads.

I had two motives for supporting user-levelthreads: cheap context switches mean you can usehigh levels of concurrency, and the choice ofscheduling policy is not restricted to whatever theoperating system provides. The motive for usingvirtual processors arises from intraprocess paral-lelism on multiprocessors and more flexiblescheduling options.

You can configure the thread module (actual-ly, each ASC) according to one of the followingoptions:

❚ No preemption. A thread only yields to anotherthread either explicitly or when the threadblocks.

64

IEEE

Mul

tiM

edia

.

Page 4: A configurable multimedia middleware platform

❚ Preemption. Asynchronous events delivered tothe thread module by the operating system canpreempt threads.

You can alter the configuration dynamically atruntime. An option also exists to timeslicethreads. I simply built this on top of the preemp-tion option using a periodic alarm event that callsthread_yield() on each invocation.

ASCsA user-level thread implementation has the sig-

nificant benefit of considerable flexibility inscheduling, permitting easy implementation of awide range of scheduling policies (such as priori-ty based, rate monotonic, earliest deadline first,least laxity first, and so forth8). The GOPI threadmodule provides a framework of ASCs for imple-menting scheduling policies.

Each ASC supports the following interface:

int asc_init(void);

bool asc_admit(Thread t, CharSeq

*params);

Thread *asc_expel(int thread_id);

void asc_deschedule(Thread t);

Thread *asc_schedule(void);

Not directly accessible to the user, these ASCoperations respond exclusively to code internal tothe thread module. The user can create and installnew ASCs and create threads managed byinstalled ASCs. ASCs can be installed dynamical-ly at any time, and multiple instances of the sametype of ASC can operate simultaneously.

Each ASC instance encapsulates a schedulingpolicy, a run queue, and one or more virtualprocessors. The asc_init() command createsthe run queue and virtual-processor resourceswhen called at ASC installation time. It creates vir-tual processors with the preemption, no preemp-tion, or timeslicing options already described. Theasc_admit() call tests a thread creation requestfor admission and, if the admission test suceeds,registers the given thread context with the ASC(which will place the thread on its run queue).

The params argument passed to asc_admit()is the same params argument the user originallypassed to thread_create(). This argumentremains completely opaque to the thread moduleand only the ASC can interpret it. Theasc_expel() call removes a thread from an ASC;the thread_exit() and thread_change() rou-tines use it as described later.

Virtual processors executing the thread module’scontext-switch code (inside thread_yield()) callasc_schedule() and asc_deschedule(). Thiscode determines the calling virtual processor’s“home” ASC and calls asc_deschedule() on theappropriate ASC, passing the user thread context ofthe currently executing thread as an argument.Internally, asc_deschedule() updates anydynamic scheduling state associated with thedescheduled thread (for example, deadlines) andstores the descriptor on its private run queue. Thethread_yield() code then calls asc_sched-ule(), which returns the user thread context thatthe ASC’s policy has determined should run next.Finally, thread_yield() switches context to thisnewly selected thread.

The thread_change() routine attempts tomigrate the current thread into a newly specifiedASC by first removing it from its current ASCusing asc_expel(). It then calls asc_admit()on the new ASC using the scheduling parametersprovided. thread_change() succeeds or failsdepending on the outcome of this call. The callerof thread_change() may also specify the sameASC, but with new scheduling parameters.

Locking issuesIn any concurrent system, the implementation

of locking proves crucial in maximizing perfor-mance and predictability. Maximum performancecomes from minimizing the inherent overhead ofthe locking operations and appropriately tradingoff the number and length of critical sections.Similarly, both maximum performance and pre-dictability result from minimizing the number ofcontext switches incurred. In GOPI, the degreeand type of locking, and thus the overheadinvolved, are configurable depending on whetheror not any currently installed ASC has the pre-emption option enabled and whether just one ormultiple virtual processors currently exist. GOPIimplements three levels of locking as follows.

The first level of locking ensures that libc andother library calls are atomic in the face of pre-emption. Therefore, this level of locking isn’trequired unless some ASC has configured the pre-emption option (the rest of this paragraphassumes the preemption option). A configurationwith more than one virtual processor furtherrequires appropriate multithread-safe versions ofthe standard libraries; these include their owninternal, virtual processor-level locking based onoperating system-level mutexes. For a configura-tion with only a single virtual processor, howev-

65

January–M

arch 1999

.

Page 5: A configurable multimedia middleware platform

er, a more efficient solution suffices. In such a sit-uation, concurrency problems can only arise if thethread module preempts a thread while executinginside a standard library routine. Preventing suchproblems in the single-virtual-processor case justrequires a simple Boolean flag; a thread making alibrary call sets this flag on entry and clears it onexit. Asynchronous event handlers can thendecide whether to evoke a preemption (by callingthread_yield()) on the basis of the flag’s value.Note that this solution doesn’t need to use oper-ating system-level signal masking calls. This pro-vides an important benefit, as these calls carrysignificant overhead in frequently executed sec-tions of code.

The second level of locking in the thread mod-ule concerns protecting the thread module’s andASCs’ data structures (such as run queues andsemaphore queues) in the face of preemption. Aconfiguration of more than one virtual processorrequires an operating system-level mutex to pro-tect these data structures from operating system-level preemptions. Again, however, the far moreefficient flag-based solution already described suf-fices in the special case of a single-virtual-proces-sor configuration.

The third level of locking concerns protectinghigher level GOPI modules and applications. At thislevel, of course, the thread module’s semaphoreimplementation becomes available to implementlocking. Each GOPI module attempts to maximizeconcurrency through the use of multiple, per-resource critical sections as opposed to single, per-module locks. Performance, as well as predictability,is further enhanced in that thread_P() doesn’tcause a context switch unless it blocks, andthread_V() doesn’t cause a context switch unlessother threads block on the semaphore.

Event handling frameworkThe thread module employs a generic and

extensible framework for operating-system-levelevent handling that’s closely integrated with thelocking scheme. The framework’s objective targetshandling events with minimum latency whilemaintaining low locking overhead. For each typeof event handled, the framework user provides

❚ the address of a Boolean event flag variable,

❚ the address of an operating-system-level eventhandler (such as a Unix signal-handler routine)that, among other things, sets the event flag,and

❚ the address of a callback routine conditionallycalled from the thread module’s context-switchcode depending on the state of the associatedevent flag.

In operation, triggering an event (the operat-ing system calls the event handler) prompts theevent handler to first set the associated event flag.Its subsequent action then depends on whetherthe ASC associated with the interrupted virtualprocessor is configured for preemption and, if so,on the state of the level one and level two locks.If the no-preemption option is selected or if oneor both of these locks are set, the handler simplyreturns. The callback routine will be invoked laterby the thread module’s context-switch code whenthe latter inspects the event flag and notices thatit’s set. If, however, the preemption option isselected and both locks are clear, the event han-dler itself calls thread_yield() before returning.This causes execution to immediately enter thecontext-switch code (thus preempting the cur-rently executing thread) and directly results ininvoking the callback. In either case, the callbackis invoked with the minimum latency possiblegiven the circumstances (immediately in the caseof preemption or as soon as the context-switchcode notices that the flag is set on the next con-text switch in the case of nonpreemption).

A further issue to consider is the possibility ofa race condition between the setting of an eventflag in the event handler and the reading andclearing of the flag by the context-switch code.Without any preventive measures, events mightbe missed if the event handler set the flag (that is,a new event came in) between the context-switchcode detecting that the flag was set and it clearingthe flag prior to invoking the callback routine. Toprevent this potential pathology, the context-switch code uses a test-and-set instruction to readand clear the flag in a single atomic action.

One prominent user of the event handlingframework, the timer implementation code,multiplexes virtual timers using a delta queuescheme, on top of (assuming a Unix environ-ment) the SIGALRM event. On each invocation ofthe timer callback routine, the callback fires ripetimers and also resets the operating system alarmsignal according to the firing time of the nextalarm in its queue. These timers form the basis ofthe timed semaphores and also of message-pass-ing routines in the msg module, which featuretimeout options.

Other clients of the event-handling framework

66

IEEE

Mul

tiM

edia

.

Page 6: A configurable multimedia middleware platform

include the periodic alarm handler, which usesthe framework to implement timeslicing (a pre-emption takes place on each periodic alarm), andthe comm module, which uses it to monitor I/Oavailability. In the Unix environment, the peri-odic alarm handler uses the SIGVTALRM signal,and the comm module uses the SIGPOLL signal.

CommunicationsCommunications in GOPI involves multiple

elements. We’ll look at them next, from the APIoverview to the details of buffer management.

API overviewThe primary abstraction employed by the com-

munications system from the API user’s point ofview is the iref—a location-independent commu-nication endpoint. The following call creates irefs:

Iref *bind_irefcreate(FlowType

cust_flowtype, FlowType

prov_flowtype, Function h, Aspname

asp, CharSeq *qos);

The two FlowType arguments refer to thedirectionality (stream or request/reply) of the irefin each of its two roles, customer and provider (seebelow). The h argument specifies a handler: a Cfunction pointer upcalled when data arrives at orleaves an iref. Handlers are typically written to callstub or skeleton code provided by the API person-ality. Data pass to or from handlers in buffers. Theasp and qos arguments respectively select andconfigure an ASP stack associated with this iref insubsequent bindings.

Irefs are bound (connected) using the follow-ing call:

Iref *bind_bindreq(Iref *cust, Iref

*prov, CharSeq *qos);

This call binds iref cust to iref prov (the call worksregardless of the irefs’ location) using the ASP asso-ciated with prov at creation time. bind_

bindreq() works by invoking a generic bindingprotocol that negotiates a mutually acceptable QoSfor the binding. If a non-null qos argument isgiven, then this is used as the target QoS; other-wise, the default QoS associated with prov at cre-ation time is used. bind_bindreq() returns an irefon which invocations can be made to control thenewly created binding (for example, start, stop,renegotiate QoS, and destroy). These control invo-cations result from the following routine:

int bind_invoke(Iref *iref, int

operation, Buffer *args);

A general-purpose service, bind_invoke()uses the OMG’s Internet Inter-ORB Protocol(IIOP)1 to invoke an iref without requiring a priorexplicit binding. To renegotiate the QoS of abinding requires calling bind_invoke()with thefollowing arguments: the control iref returnedfrom bind_bindreq(), an int constant RENEG,and a buffer into which a new target QoS hasbeen marshalled from an ASP-specific CharSeqspecification.

You can see that ASPs play a role in the com-munications module very similar to that of ASCsin the thread module; both provide application-specific behavior and are configured and reconfig-ured using specifications defined according to theirown schema. As with ASCs, per-ASP routines mar-shall QoS parameters into CharSeqs for passing tobind_irefcreate() and bind_bindreq().Besides configuring ASP behavior, QoS specifica-tions determine the requested binding’s resourcerequirement (transport sockets, threads, andbuffers). Furthermore, ASPs are often written interms of other ASPs that provide a lower level ser-vice. In such cases, the QoS specification deter-mines the lower level ASPs selected and their QoSparameters. This process, recursively applied, leadsto an arbitrarily deep protocol stack, the form ofwhich is a function of the QoS specification passedto the top-level ASP.

ASPsThe comm module—a multilevel protocol

framework—enables building bindings fromstacks of ASPs in turn stacked on top of transportprotocols. (The current implementation makesTCP/IP, UDP/IP, and Unix FIFOs available). Todate, I have implemented ASPs for IIOP, adaptiveaudio, and intercapsule shared memory commu-nication.2 Each ASP supports the following inter-face (slightly simplified):

int asp_listen(Profile *pf, FlowType

flowtype);

int asp_connect(Profile *pf, FlowType

flowtype);

int asp_accept(Profile *pf, int

listening_sap);

int asp_relisten(int sap, Profile

*pf);

int asp_reconnect(int sap, Profile

*pf);

67

January–M

arch 1999

.

Page 7: A configurable multimedia middleware platform

int asp_reaccept(int sap, Profile

*pf);

int asp_close(int sap);

int asp_hdrsize(int sap);

int asp_flipqos(CharSeq *cs_qos);

int asp_send(int sap, Buffer *buf);

int asp_receive(int sap, Buffer

**outbuf);

int asp_call(int sap, Buffer *inbuf,

Buffer **outbuf);

The binding protocol (see Figure 1) usesasp_listen(), asp_connect(), andasp_accept()to establish a mutually acceptablelevel of QoS between the customer and providerusing the specified ASP. In the first instance, the tar-get QoS from bind_bindreq() passes (in a Profiledata type, which also contains addressing informa-tion) to asp_listen() at the customer side.asp_listen() tentatively allocates resources basedon the given Profile and returns a local identifierfor the binding that will later go to asp_accept().asp_listen()may also modify the QoS informa-tion in its Profile argument if it would like to pro-pose a different QoS from the initial target. Thebinding protocol then sends this (possibly modi-fied) Profile to its peer, which passes it to theprovider’s asp_connect() routine. This workssimilarly to asp_listen(), again returning a localidentifier and a possibly modified Profile. Finally,this Profile passes to asp_accept() back at thecustomer side, which makes the final decision as tothe binding’s viability.

asp_relisten(), asp_reconnect(), andasp_reaccept() operate similarly to asp_lis-ten(), asp_connect(), and asp_accept(), butwhen the binding protocol is invoked on a cur-rent binding to renegotiate its QoS. As with theinitial binding procedure, the ASP involved entire-ly determines the semantics of renegotiation. Forexample, some ASPs may ignore renegotiationrequests, while others may only renegotiate if thebinding is currently in a stopped state.

The remaining ASP routines are conceptually

straightforward. asp_close() destroys an exist-ing binding, asp_hdrsize() returns the size ofheader used by this ASP, and asp_flipqos()reverses the byte ordering of words in a QoS spec-ification when a CharSeq QoS specificationarrives from an opposite-end machine. Finally,the ASP supports the data transfer operationsasp_send(), asp_receive(), and asp_call().ASP implementations can assume that their datatransfer operations are only called when theunderlying system can accept or deliver data. Forexample, when an ASP’s receive() entry pointis called, it knows data awaits reading from theASP or transport protocol below it without block-ing. In general, programmers write ASPs for use inboth request/reply or streaming mode interac-tions; the bind module chooses the interactionstyle (as determined by the FlowType argumentpassed to asp_listen() and asp_connect()).Full details of the ASP architecture and its rela-tionship to the bind module appear elsewhere.2

Maximizing performance in a middleware-based communications system requires involvingas few context switches, locking operations, andcopy operations as possible. Maximizing pre-dictability further requires isolating bindings fromeach other to the extent possible. To help achieveboth these ends, the GOPI design employs non-multiplexed bindings, each with its own operat-ing sytem-level socket, its own thread, and its ownstate in each ASP (all allocated during binding pro-tocol execution). Nonmultiplexed bindings elim-inate the QoS crosstalk incurred when bindingswith different QoS requirements are multiplexedonto some common layer.

You can configure each binding in the commmodule according to one of the following options:

❚ I/O polling (the default option), in which thesentinel thread (that is, a distinguished threadthat runs when no other thread is runnable)explicitly checks I/O availability every so oftenby means of an operating system primitivesuch as Unix’s poll(), or

❚ I/O notification, in which the thread module’sevent handling framework lets the operatingsystem asynchronously inform the commmodule of I/O availability on the binding assoon as it happens.

The I/O notification option provides maximal-ly timely responsiveness to incoming packetsfrom the network—particularly if the thread mod-

68

IEEE

Mul

tiM

edia

.

QoS4

QoS2 QoS3

QoS1

Listen Accept ConnectCustomer ASP

Customer ASP

Provider ASP

Provider ASP

Figure 1. The binding

protocol.

Page 8: A configurable multimedia middleware platform

ule’s preemption option is selected. The I/Opolling option, on the other hand, avoids theoverhead of event handling (both options requirepoll(), as will become clear below) and thus mayprove more efficient in a capsule with few threadsand little else to do other than receive packetsfrom the network.

The I/O data pathAt the bottom level of the communications

module lies a routine called io_handler().When configuring bindings for I/O notification,io_handler() serves as the callback routine inthe thread module’s event handling framework.Thus it’s called as soon as the operating systemnotifies its associated event (for example, SIG-POLL, assuming a Unix environment). On theother hand, selecting the I/O polling optionrequires calling io_handler() explicitly. Thisopens up a range of possibilities as to how oftenand under what circumstances to actually callio_handler(). The current implementation callsit from the sentinel thread referred to above.

When io_handler() executes, it first calls thepoll() system call (or equivalent) to determinewhich currently open sockets await I/O. io_han-dler() then sends a notification message, usingthe services of the msg module, to the per-bind-ing thread associated with each ready socket. Onreceiving this message, the per-binding threadscall their associated ASP stacks to read/write datafrom/to the network as appropriate. A per-bind-ing masking scheme employed in the receivedirection prevents notifying per-binding threadsmore than once for the same incoming packet.Messages go to per-binding threads only if themask remains clear. If the mask is clear, io_han-dler() sets it on sending a message, and the per-binding thread clears it when the correspondingpacket has arrived.

Note that, because each binding has its ownthread, the thread’s associated ASC (whose sched-uling decisions are, in turn, controlled by indi-vidual bindings’ QoS specifications) determinesthe time and order in which bindings actually getto read/write from/to the network. This meansthat GOPI avoids processing low-urgency mes-sages in favor of high-urgency messages. It alsomeans GOPI avoids situations in which the steadyflow of packets on one or more stream bindingsindefinitely delays one-shot control messages(such as video stop/start). This pathology com-monly afflicts many existing ORBs when used tosupport multimedia applications.

I/O notification issuesThe previous description of the I/O data path

omitted certain issues arising from I/O notifica-tion. The often complex semantics of event-driven I/O in operating systems require carefuldesign to exploit effectively.

First, events such as Unix’s SIGPOLL do notcarry any information about which sockets areready for I/O given multiple open sockets.Therefore, the middleware must explicitly issue apoll() call following receipt of the event toobtain this information. (GOPI calls io_han-dler(), which in turn calls poll().) This impliesthe overhead of an event, a poll() call and aread/write for each network packet received viathe I/O notification option.

Second, in many systems the middlewareshould not assume that each packet arrival gener-ates exactly one event. On the one hand, when anumber of packets addressed to different socketsall arrive from the network at around the sametime, their arrival might evoke only a single event.On the other hand, many operating systems onlygenerate an event for incoming data when thestate of one or more sockets changes from “nodata available on this socket” to “some data avail-able on this socket.” Hence, while the middlewareprepares to read a packet following notification ofits arrival by an event, another packet can arrivethat does not evoke an event (because the condi-tion “some data available on this socket” stillholds). This means that relying exclusively onevents to signal arriving packets may result inpackets received at the operating-system levelgoing unperceived and thus unreceived at themiddleware level.

GOPI adopts the default solution of receivinga single packet for each event and additionallyrelying on a subsequent io_handler() call todetect any further packets that arrived withoutevoking an event. A subsequent io_handler()call occurs sooner or later—guaranteed—eitherbecause a further event occurs when a packetarrives on some other socket or because the sen-tinel thread will eventually run and issue anio_handler() call.

GOPI includes two additional possibilities. Thefirst configures the system to always issue anexplicit io_handler() call after reading eachpacket. This buys possibly improved predictabili-ty in receiving unperceived packets at the expenseof a not inconsiderable performance hit. The sec-ond designs ASPs to read not just a single packet,but as many packets as the binding has buffer

69

January–M

arch 1999

.

Page 9: A configurable multimedia middleware platform

space available. A nonblocking read means thatthe call returns immediately despite the numberof packets actually available. This scheme looksattractive in that a single system call can receivepossibly multiple packets. However, it works onlywhere the ASP knows in advance the size ofexpected packets. Assuming noncontiguousbuffers, the byte offsets of the unperceived pack-ets—as required by a scatter/gather mode read—cannot otherwise be known at the time the readis issued.

Buffer managementBuffers in GOPI are allocated from preallocated

pools of memory owned by the msg module. A“buddy system” allocation scheme9 efficiently allo-cates and deallocates power-of-two sized buffers. Auser-level buffer manager has the benefit that youcan tune its performance according to expectedusage patterns. In addition, it avoids the overheadof frequent malloc() calls, which become partic-ularly expensive when using operating system-level locking in a multiple-virtual-processorenvironment. Buffers pass by reference betweenASPs in a stacked binding; no copying occurs.

GOPI requires that all ASPs use fixed-size pack-et headers. Before allocating a buffer, anasp_hdrsize() call takes place on the top-levelASP in a binding to determine the required head-er size for the whole stack. (This call propagatesdown to lower level ASPs to obtain the total head-er-size requirement.) Buffers have an associated“current header pointer” that ASPs “push” and“pop” as the buffer passes up and down the stack.

The calls to allocate buffers, together with theirheaders, and to free buffers follow:

Buffer *msg_bufget(int hdrsize, int

size);

void msg_bufput(Buffer *b);

Buffer *msg_bufmake(int hdrsize,

char *header, int size, char

*data);

void msg_bufgetfrags(Buffer

*origbuffer, int fragsize, char

*fraghdr,int fraghdrsize; Buffer

*frags[], int *numfrags);

msg_bufget() allocates a buffer of size sizefrom the buffer pool. If a nonzero hdrsize argu-ment goes to msg_bufget(), a header area of sizehdrsize is additionally allocated contiguouslywith the start of the buffer’s data area. msg_buf-put() decrements the given buffer’s reference

count and deallocates the buffer if the referencecount has become zero. msg_bufmake() differsfrom msg_bufget() in that

❚ the caller (in the data argument) supplies thebuffer’s data area rather than taking it from thebuffer pool, and

❚ given a null header, then a header area of sizehdrsize is taken from the buffer pool, other-wise the given memory serves as a header.

msg_bufmake() proves useful in situations whereASPs manage a device such as an audio card or anarea of frame buffer mapped to an address in theuser virtual address space. In such a case, a bufferbuilt using this address would permitreceiving/sending data straight from/to the devicewithout incurring any copy overhead.

msg_bufgetfrags() performs logical frag-mentation on buffers. The call takes a buffer tofragment and returns an array of new buffers, eachof which points into the original buffer’s data areaat an appropriate offset. fraghdrsize specifiesthe fragment header size, and numfrags returnsthe number of fragments produced. Given a non-null fraghdr argument, this same piece of mem-ory serves as the header for all the fragments.Otherwise, a new area of pool memory is allocatedfor each fragment header.

To prevent deallocation of the original bufferbefore deallocation of all the fragments, num-frags increments the original buffer’s referencecount. Also, the fragment buffers keep a referenceto it so that they can decrement its referencecount when they are deallocated. msg_bufget-frags() is implemented in terms of msg_buf-make(). The data argument to msg_bufmake()consists of some address within the originalbuffer’s data area, and the header-related argu-ments depend on the value of fraghdr.

Ideally, an ASP stack design will mandate per-forming fragmentation only once, by the bottomlevel ASP that interfaces directly with the trans-port layer. In such cases a technique called headerborrowing offers an alternative to fragmenting withmsg_bufgetfrags(). In header borrowing, frag-ment headers are written into header-sized piecesof memory within the packet buffer’s data area sothat the headers are contiguous with their pay-loads. For the first fragment of a packet, the ASPuses the header area specified in the originalmsg_bufget() call. For the remaining fragments,the ASP saves into temporary storage the header-

70

IEEE

Mul

tiM

edia

.

Page 10: A configurable multimedia middleware platform

sized piece of data directly in front of the frag-ment and uses this memory for the fragment’sheader. Following transmission of each fragment,the borrowed memory is restored. (A similarscheme in the reverse direction handles defrag-mentation.) The relative costs of using header borrowing and msg_bufgetfrags()-based frag-mentation follow:

❚ Header borrowing involves two copy opera-tions of a header-sized piece of memory perfragment. Scatter/gather I/O isn’t required, asthe headers and payloads remain contiguous.

❚ msg_bufgetfrags() involves allocatingmemory for fragment buffer structs, headers,and scatter/gather data structures, and assign-ing the associated pointers.

The trade-off will likely favor header borrowingwith relatively small headers and relatively manyfragments.

Finally, when implementing ASPs having time-liness as a prime requirement, it’s advisable to usefixed-size packets so that you can employ thescheme described for maximizing the I/O notifi-cation’s timeliness. Using fragmentation, thisimplies that each packet’s final fragment shouldbe padded with garbage data to make it the samesize as all the others. (To ensure space for thisgarbage data, overallocate the buffer to a multipleof the fragment size.)

Such a policy’s effectiveness depends heavilyon the fragment size chosen. Large fragmentswork well in that many packets won’t need frag-menting, but not so well in that the last fragmentmay contain a lot of garbage data. Most ASPsdeveloped so far employ the approach of lettingthe user set the fragmentation size as a QoS para-meter. This assumes that the user has prior knowl-edge of likely packet size distribution and can thusmake an informed trade-off.

Performance evaluationThis section describes experiments evaluating

the GOPI platform’s performance, specifically theextent to which GOPI can perform well despiteoffering high-level abstractions and a high degreeof configurability. I did not design the experi-ments to evaluate the configurability propertiesthemselves. These are more appropriately evalu-ated through API personalities and applicationsthat exploit the platform’s configurability inmeaningful ways—an issue for future work.

Furthermore, the experiments do not explicitlyevaluate predictability because predictability isprimarily a function of specific policies and onlysecondarily a function of the middleware archi-tecture itself.

ThreadsI wrote a simple program to evaluate the user-

level thread package’s performance. The programcreates two threads, each of which execute a tightloop containing nothing but a yield call. Eachthread loops 500,000 times. I ran two versions ofthis program on a Sparcserver-1000 runningSunOS 5.5. One program uses GOPI threads,thread_yield(), and a simple, single-virtual-processor ASC that implements priority-basedscheduling with earliest-deadline-first schedulingwithin priority bands. The other program usesSunOS detached processor-scoped threads (userthreads), the SunOS thr_yield() call, and Sun’sSCHED_OTHER scheduling policy (a priority-based policy).

The results, shown in Table 1, show a speedupfor GOPI threads of 24.706/12.095 = 2.04 overSunOS 5.5 user-level threads.

Buffer managementI wrote a simple program to evaluate the user-

level buffer management scheme’s performance.The program repeatedly allocates and deallocatesbuffers over 1,000,000 iterations. The size of eachallocated buffer comes from a pseudorandomsequence. One version of the program uses GOPI’smsg_bufget() and msg_bufput() and the otheruses the Unix malloc() and free() calls. Bothversions used the same pseudorandom sequenceof buffer sizes.

The results, shown in Table 2, show a speedup

71

January–M

arch 1999

.

Table 1. Relative performance of GOPI and

SunOS threads.

GOPI threads 12.1 seconds

SunOS threads 24.7 seconds

Table 2. Relative performance of

msg_bufget() and malloc().

msg_bufget(), msg_bufput() 2.159 seconds

malloc(), free() 5.352 seconds

Page 11: A configurable multimedia middleware platform

for the GOPI buffer management scheme of5.352/2.159 = 2.48 over malloc() and free().This occurs despite the fact that the GOPI buffermanagement routines allocate and initialize aBuffer struct (allocated from a separate dedicatedpool) in addition to simply allocating memory.

End-to-end communicationsTo evaluate the end-to-end performance of the

GOPI communications architecture, I carried outtwo experiments: one to measure performance rel-ative to comparable systems and the other to eval-uate the scalability of the nonmultiplexedcommunications architecture.

The first experiment compared GOPI to a min-imal baseline Berkeley sockets program and to acommercial ORB, Chorus Systems’ Cool-ORB 4.1.In fact, I used two Berkeley sockets programs—onewith a null poll() system call inserted beforeeach read and another without the poll()—andtwo GOPI programs—one configured to use I/Opolling and the other, I/O notification. To obtain afair comparison with the GOPI core, I modified theCool-ORB program to avoid marshalling overhead.

I configured all five test programs as client-serv-er pairs in which the client made repeatedrequest/reply calls on the server. TCP served as theunderlying transport protocol for all the test pro-grams, none of which touched the datasent/received in any way. Both the clients andservers ran on the same machine to minimize theeffects of load fluctuation.

Table 3 shows the number of round-trip serverinvocations measured per second for each pro-gram (averaged over 1,000,000 calls). The tablegives figures for three packet sizes: small, medium,and large. The GOPI versus Sockets Overhead fig-

ures give the percentage overhead incurred byGOPI (with the I/O polling configuration) versusthe minimal socket program (with poll()). Itseems reasonable to use the socket program withpoll() rather than the simplest and fastest sock-et program as a baseline reference for this perfor-mance comparison because all user-levelmultithreaded systems are inevitably required touse I/O polling of some kind.

Clearly, GOPI’s performance compares veryfavorably with that of Cool-ORB. It also—asexpected—performs worse than the baseline sock-ets program, although the overhead is probablynot unacceptable when using larger sized packets(particularly as large packets are the norm for mul-timedia data).

In comparing GOPI with the sockets program,observe that GOPI carries the following over-heads: thread context switching and messagepassing, buffer (de)allocation, ASP layer executionand header processing, and multiplexing/demul-tiplexing to/from irefs. Also note that I made noserious attempt to optimize GOPI. The I/O notifi-cation performance, as expected, proved inferiorto I/O polling due to the additional overhead ofevent handling. However, I/O notification inGOPI still easily outperformed Cool-ORB and hasthe additional benefit of increased timeliness andpredictability.

The second experiment evaluated the scalabil-ity of GOPI’s nonmultiplexed communicationsarchitecture. I wrote a GOPI program that estab-lished varying numbers of bindings to transmit agiven total number of packets. The two parts ofthe program again ran on the same machine. Iused packet sizes of 1,024 bytes over a streambinding using the shared memory ASP. (I did thisto avoid either packet loss, possible with aUDP/IP-based ASP, or slow start/buffering effects,possible with TCP/IP- and FIFO-based ASPs.) Thebinding ran as fast as the system would allow. Imeasured the time to receive 160,000 packets atthe receiver (multiple averaged runs obtained thegiven figures).

The results in Table 4 showed an increase inperformance for more than one binding over thesingle binding case. This counterintuitive resultprobably happens because fewer than one poll()call per receive occurs with multiple receivingbindings in place (poll() reports more than onesocket with data waiting). There was then littleappreciable difference in overall throughput for n = 2 and n = 8 bindings. This result provides evi-dence that GOPI’s improved QoS predictability

72

IEEE

Mul

tiM

edia

.

Table 3. End-to-end round trips per second.

Packet Size (bytes) 1 1,024 8,192Socket (no poll()) 1,015 861 484

Socket (with poll()) 999 839 442

GOPI (I/O polling) 743 734 402

GOPI (I/O notification) 664 522 350

GOPI versus Sockets Overhead 25 percent 12 percent 9 percent

Cool-ORB 464 420 260

Table 4. Stream performance with varying numbers of bindings (in seconds).

Number of bindings 1 2 4 8

Time for 160,000 packets 15.99s 8.55s 7.97s 7.52s

Page 12: A configurable multimedia middleware platform

(achieved through nonmultiplexing) doesn’tcome at the expense of an unacceptable degrada-tion in performance.

ASP stacking overheadI performed a final experiment to assess the

ASP stacking framework’s overhead using as thebaseline the I/O polling configuration. To assessthe ASP stacking’s overhead, I wrote a minimalASP that could configure multiple instances ofitself in a stack, with the actual number ofinstances determined by a QoS parameter. I con-figured varying numbers of instances of this ASPabove the baseline configuration. In terms of over-head, each instance contributed only a four-byteheader and the minimum possible amount of processing.

The results in Table 5 show an acceptable over-head for relatively small numbers of stacked ASPs.Implementing stacks composed of large numbersof fine-grained micro-protocols would requireoptimization, however.

Implications for the operating systemDespite GOPI’s main goal of operating in a

standard operating-system environment, myexperience suggests that a few localized and rela-tively straightforward modifications to the oper-ating system could considerably enhance theperformance and predictability of multimediamiddleware. The first such modification, and thesimplest to effect, would be to reimplement keyinformational system calls, making the informa-tion available to the middleware without the over-head of a system call. Examples include the Unixcalls gettimeofday(), used to read the systemclock, and pthread_self(), used to obtain a vir-tual processor’s id. Such calls could be reimple-mented by mapping operating-system virtualmemory areas—to be written by the operating sys-tem and read by the application—into applicationaddress spaces.

The second suggested modification would pro-vide per-socket I/O readiness information with theSIGPOLL signal, probably as an extension of theexisting siginfo mechanism. The availability ofsuch information would eliminate the need for apoll() call after each signal and would thus con-siderably reduce the I/O notification overhead.

Note that I don’t recommend changing thesemantics of SIGPOLL so that each packet arrivalgenerates a SIGPOLL. Although the fact that somepackets may fail to evoke a SIGPOLL leads to com-plexity in the middleware, good reasons exist to

live with this semantic. First, a per-packet SIG-POLL would only work for datagram sockets.With stream sockets using TCP, the operating sys-tem has no way to identify a user-level packet, sothe middleware would still require the additionalcomplexity. Second, per-packet SIGPOLLs wouldadd overhead. It’s not at all clear that this wouldbe less than the overhead of the user-levelschemes already described.

My third suggestion: consider replacing the tra-ditional priority-based scheduler with a fair-sharepolicy such as lottery scheduling.10 Clearly morewide-ranging and controversial than the othersuggestions, this proposal nevertheless meritsinvestigation. Fair-share scheduling offers a farsuperior basis on which to build predictable user-level ASCs while simultaneously providing oblig-atory operating system-level properties such asfairness. Lottery scheduling works by assigningnotional lottery tickets to processes (or kernelthreads) and then holding a lottery at each sched-uling point; the winning process runs on the CPUuntil the next scheduling point. Key propertiesinclude

❚ starvation doesn’t occur, as every process willwin some lotteries as long as it holds at leastsome tickets, and

❚ if a process has x percent of the available lot-tery tickets, it will probabilistically take x per-cent of the available CPU time.

Thus, virtual processors implemented as lottery-scheduled kernel threads come much closer to“real” CPUs. In fact, each virtual processorapproximates a CPU with a speed of S/x where Srepresents the speed of the physical CPU and x thepercentage of lottery tickets it holds. Such supportwould allow user-level ASCs to operate in a con-siderably more predictable manner and to per-form meaningful admission tests at the user level.

As a refinement, if the operating system had tovary the percentage of lottery tickets assigned toa given virtual processor, it could deliver an event

73

January–M

arch 1999

.

Table 5. ASP stacking overhead.

Configuration Calls per Second Percent OverheadBaseline 734 -

Baseline + 1 null layer 716 2.6 percent

Baseline + 8 null layers 607 17.4 percent

Baseline + 16 null layers 531 27.7 percent

Page 13: A configurable multimedia middleware platform

to the thread module. This would let ASCs adaptappropriately (for example, by changing schedul-ing policy or admission test criteria).

Related workRecent work in the OMG’s Corba forum has

addressed the need for streams and real-time ser-vices in distributed object platforms. In particular,the Telecom Special Interest Group’s (SIG’s) spec-ification for the “Control and Management ofAudio/Visual Streams”11 addressed the need forstreams in Corba, and the Real-time SIG’s (ongo-ing) “Real-time Corba” specification12 addressesthe need for more general real-time functionality.

As stated in the introduction, GOPI’s approachto supporting streams differs fundamentally fromthe OMG’s. The GOPI approach treats stream dataas far as possible in the same manner and in thesame environment as conventional data, whereasthe OMG approach transports stream data out-of-band and only uses the ORB for stream controland management.

The Real-time Corba activity defines a numberof concepts also found in GOPI (such as flexiblethreads and scheduling, pluggable transports, andhigher level protocols). However, I can’t yet makea detailed comparison because, although the var-ious contributors have implemented aspects ofthe Real-time Corba specification, no integratedimplementation of the whole design yet exists.

The European Commission-funded Retina pro-ject is designing a Corba platform featuringstreams and QoS extensions.3 The architecturecleanly separates between

❚ ORB support mechanisms such as interface ref-erence management, threads, buffers, and soforth, and

❚ binding classes that provide communicationsservices tailored to particular applications.

While comparable in terms of their overall goals,Retina focuses more on static QoS managementissues such as binding establishment where GOPIemphasises dynamic QoS management issues.

The Dimma project4 at APM in Cambridge, UKalso addresses issues of multimedia support in dis-tributed object platforms. Dimma builds on theANSAware distributed systems platform enhancedwith abstractions for resource management and aflexible multiplexing structure. Like GOPI, thedegree of per-binding internal multiplexing canbe configured according to the needs of different

applications. Compared to GOPI, Dimma focusesmore on global QoS configurability and less onthe fine-grained QoS configurability of individualbindings. The finer grained configurability inGOPI arises largely through the ASC and ASPframeworks, lacking in Dimma.

TAO,5 a Corba 2.0-compliant platform, runson real-time operating systems. Although TAO’sdesigners considered multimedia support, andrecently implemented the OMG’s Control andManagement of A/V Streams specification inTAO,13 the system appears primarily designed forhard real-time applications such as avionics. TAOfeatures a real-time message scheduling servicethat can provide deterministic temporal guaran-tees (given a real-time operating-system infra-structure) by avoiding priority inversion andnondeterminism. In contrast to TAO, I designedGOPI to provide integrated multimedia supportin a conventional operating-system/networkenvironment and to emphasize flexible user ser-vices support rather than hard deterministicperformance.

Related work in more specific areas also influ-enced GOPI. In terms of scheduling, split-levelscheduling14 and SunOS 5.5’s two-level threadarchitecture influenced GOPI’s two-level threadarchitecture. The GOPI architecture differs fromsplit-level scheduling in that it does not dependon specialized operating-system support for user-level threads. It differs from the SunOS designmainly in terms of flexibility. For example, GOPIallows adding new schedulers (both preemptiveor nonpreemptive) dynamically, and the eventhandling framework allows close integrationbetween external events and scheduling.

GOPI’s ASC framework also compares toscheduling classes in Unix SVR4, except thatASCs are user level and scheduling classes are ker-nel level. As a result, ASCs suffer less from mutu-al interference between classes,15 particularlywhen the underlying virtual processors are lotteryscheduled.

In terms of communications, flexible protocolframeworks such as the x-kernel16 and Ensemble17

clearly influenced GOPI’s ASP framework. GOPIdiffers from these earlier systems primarily in itsapproach to QoS configurability. In most previousdesigns, the builder of a stack would attempt torealize a given QoS requirement by explicitlyselecting layers and individually configuring themin an appropriate way. Although superficiallyattractive, this approach has the drawback thatthe stack-builder code must “know” how to map

74

IEEE

Mul

tiM

edia

.

Page 14: A configurable multimedia middleware platform

the given QoS specification to the configurationparameters of each selected layer. Furthermore, itmust recognize dependencies between layers withvarious configurations. (For example, the degreeof compression supported by an MPEG layer mayaffect the choice of throughput and delay para-meters given to a transport layer.)

Although small numbers of layer types keepthese problems surmountable, the approach doesnot scale well for many layer types and when newQoS parameters must be introduced. To avoidthese QoS mapping problems and to better sup-port extensibility, GOPI builds stacks in an implic-it, encapsulated manner. The stack builderspecifies a single top-level ASP and configures itusing the ASP’s own QoS schema. The ASPinstance itself then autonomously realizes therequired QoS by mapping its QoS parameters tothose of further, encapsulated, ASP instances (andso on recursively).

A second way in which GOPI differs from mostprevious protocol frameworks lies in its approachto scheduling. The x-kernel and Ensemble, incommon with most other frameworks, executestacks by dedicating a single thread to all stacksand using an external scheduler. In other words,they divide the total workload into discrete steps(such as the execution of individual layers in indi-vidual stacks) and serially execute these stepsaccording to some policy (like first-come, first-served or priority order) as they become ready.Although this approach allows some limited con-trol over each individual stack’s QoS, typically byassigning different priorities to different stacks’steps, the GOPI thread-per-stack approach provesmuch more configurable and fine grained.

ConclusionThe GOPI middleware platform supports mul-

timedia applications in a standard operating-sys-tem environment. Designed in a modular fashion,GOPI implements a number of configurablemechanisms to enhance performance and pre-dictability. Its performance demonstrates thatdespite its high degree of configurability, GOPIcompares favorably with related systems and canadequately meet multimedia applications’ perfor-mance requirements. Moreover, because audioand video stream bindings typically require zeroor minimal marshalling, a GOPI-based Corbaimplementation should incur little if any perfor-mance penalty above that already discussed.

The main dimensions of configurability inGOPI follow:

Threads

❚ Configure by choosing appropriate ASC andscheduling parameters

❚ Change ASC and scheduling parameters ofthreads at runtime

❚ Add new ASCs dynamically

❚ Configure ASCs with preemption, no preemp-tion, or timeslicing

Bindings/communications

❚ Configure by choosing appropriate ASPs andQoS

❚ Renegotiate ASPs and binding QoS at runtime(not addressed in this article)

❚ Add new ASPs dynamically

❚ Configure ASPs with I/O polling or I/Onotification

The ASC and ASP frameworks prove central tothis configurability. These frameworks make itstraightforward to customize middleware for spe-cific applications by designing and installing spe-cialized plug-in modules. Furthermore, theseframeworks effectively sidestep the QoS mappingproblem in which QoS specifications in some gen-eral-purpose high-level notation must be some-how mapped to low-level resources such astransport sockets, virtual processors, and memo-ry. This mapping becomes trivial in GOPI becauseASCs and ASPs define their own specialized QoSspecification schema, and the mapping from thisschema to generic resource managers (provided byGOPI) is hard wired into their code.

In future work, I intend to further develop sup-port for configurability. One direction would portGOPI to the Windows NT environment to exploitNT’s flexible support for dynamic loading to loadnew ASCs and ASPs at runtime. I also want todesign appropriate APIs to permit maximal con-figurability while not overburdening the pro-grammer with confusing detail. To this end, I aminvestigating the concept of reflection,18 whichseparates basic behavior from metabehavior (thatis, configurability). A report on early work in thisdirection appears elsewhere.19 MM

75

January–M

arch 1999

.

Page 15: A configurable multimedia middleware platform

References1. The Common Object Request Broker: Architecture and

Specification 2.2, available at http://www.omg.org/.

2. G. Coulson and M.W. Clarke, “A Distributed Object

Platform Infrastructure for Multimedia Applications,”

Computer Comm., Vol. 21, No. 9, pp. 802-818, July

1998.

3. F. Dang Tran, “Binding and Streams: The Retina

Approach,” Proc. TINA 96, 1996, available at http://

www.uk.infowin.org/ACTS/RUS/PROJECTS/ac948.

htm.

4. D. Donaldson, “Dimma—A Multimedia ORB,” Proc.

Middleware 98, Springer Verlag, London, UK, Sept.

1998, pp. 141-156.

5. D.C. Schmidt, The Design of the TAO Real-Time

Object Request Broker, http://www.cs.wustl.edu/

~schmidt/new.html#corba.

6. G.S. Blair and J.B. Stefani, Open Distributed Processing

and Multimedia, Addison-Wesley, Reading, Mass.,

1997.

7. G. Coulson and J. de Meer, “Guest Editor’s

Introduction, Special Issue on Quality of Service,”

Distributed Systems Engineering J., Vol. 4, No. 1, Mar.

1997, pp. 1-3.

8. J. Stankovic et al., “Implications of Classical

Scheduling Results for Real-Time Systems,”

Computer, Vol. 28, No. 6, June 1995, pp. 16-25.

9. D.E. Knuth, The Art of Computer Programming,

Volume 1: Fundamental Algorithms, Second Edition,

Addison-Wesley, Reading, Mass., 1973.

10.C.A. Waldspurger and W.E Weihl, “Lottery

Scheduling: Flexible Proportional-Share Resource

Management,” Proc. First Symp. on Operating

Systems Design and Implementation, Nov. 1994,

available at http://www.usenix.org/publications/

library/proceedings/osdi/index.html.

11.“Control and Management of Audio/Visual Streams,”

OMG Document number telecom/97-05-07; avail-

able from http://www.omg.org/library/schedule/

AV_Streams_RTF.htm.

12.“Real-time Corba V1.1,” Initial Submission to Real-

time SIG’s RFP on Realtime Corba, OMG Document

number orbos/98-01-08, available at

http://www.omg.org.

13.S. Mungee, N. Surendran, and D. Schmidt, The

Design and Implementation of a Corba Audio/Video

Streaming Service, Washington Univ. Tech. Report

WUCS-98-15, Dept. of Computer Science,

Washington University at St Louis, Mo., May 1998.

14.R. Govindan and D.P. Anderson, “Scheduling and

IPC Mechanisms for Continuous Media,” Proc 13th

ACM Symp. on Operating Systems Principles, SIGOPS,

Vol. 25, ACM Press, New York, 1991, pp. 68-80.

15. J. Nieh et al., “SVR4 Unix Scheduler Unacceptable

for Multimedia Applications,” Proc. 4th Workshop on

Network and Operating System Support for Digital

Audio and Video, Springer Verlag Lecture Notes in

Computer Science, Springer Verlag, Berlin, April

1994, pp. 41-53.

16.N. Hutchinson and L. Peterson, “The x-kernel: An

Architecture for Implementing Network Protocols,”

IEEE Trans. on Software Engineering, Vol. 17, No. 1,

Jan. 1991, pp. 64-76.

17.R. van Renesse, “Masking the Overhead of Protocol

Layering,” Proc. 1996 ACM SIGCOMM Conf., Stanford,

ACM Press, New York, Sept. 1996, pp. 96-105.

18.P. Maes, “Concepts and Experiments in

Computational Reflection,” Proc. of OOPSLA 87,

ACM SIGPLAN Notices, Vol. 22, ACM Press, New

York, 1987, pp. 147-155.

19.G.S. Blair, “An Architecture for Next-Generation

Middleware,” Proc. Middleware 98, Springer Verlag,

London, UK, Nov. 1998, pp. 191-206.

Geoff Coulson is a lecturer at the

University of Lancaster, UK. He is

involved in a number of middle-

ware-related research projects,

including the OpenORB project

investigating next-generation mid-

dleware based on reflective techniques. His main

research interests are distributed systems architectures,

multimedia communications, and operating system sup-

port for continuous media. He received his PhD in sys-

tems support for multimedia applications from the

Computing Department, University of Lancaster.

Contact Coulson at Distributed Multimedia Research

Group, Computing Dept., Lancaster University,

Lancaster LA1 4LA, UK, e-mail [email protected].

76

IEEE

Mul

tiM

edia

.