Universal System Call Extension

Wed May 22 10:21:35 1996
Brian Bershad & Yasushi Saito


Overview

USyscall, the universal system call extension, provides primitive services that all user space programs might use. The usyscall services can be grouped into the below 5 categories.
  1. Utility services, like printing string on the screen.
  2. Identity services, like getting the space and thread ID.
  3. Domain services; creating and manipulating a domain.
  4. Termination; terminate yourself.
  5. Rendezvous service; bootstrap other systemcall extension by yourself.
and The usyscall extension is meant to be a static extension; it is installed into the system when it starts up. All user space programs may assume that usyscall is present when they start up.

List of Services

Utilities

Putc(c: CHAR);
Putx(x: Word.T);
Putc puts a character on the screen. Putx puts a hexadecimal representation of the value x on the screen.
System(<*AS CTEXT*>command : TEXT) : ErrorCode;
This systemcall calls a shell command.

Identity

SpaceSelf() : Space.T
ThreadSelf() : Strand.T
These two get the identity. The return values are externalized and returned to the user space app.
SpaceDestroy(s : Space.T)
StrandDestroy(s : Strand.T)
Destroy the space or strand.
Close(xref : Word.T) : ErrorCode
Closes the external reference xref

Domain

DomainLookup(<*AS CTEXT*>name : TEXT;): Domain.T;
DomainCreate(<*AS CTEXT*>name : TEXT): Domain.T;
DomainRegister(<*AS CTEXT*>name : TEXT; d: Domain.T): ErrorCode;
DomainLoad (d     : Domain.T;  
                 <*AS VAR %s : INTEGER! void *%s *> object: Word.T;
                 size  : INTEGER): ErrorCode;
     
DomainLink(domain, extern: Domain.T): ErrorCode;
DomainInitialize(domain: Domain.T): ErrorCode;
DomainDestroy(domain: Domain.T): ErrorCode;
They are all calls to domain. Strings like <*AS CTEXT*> are directives to Sieg.

Rendezvous

Rendezvous(<*AS CTEXT*>simpleName: TEXT; 
		     key: REFANY;  (* Protect the rendezvous, NIL if any *)
		     VAR reply: REFANY): ErrorCode;
       
This service is used to autoload a systemcall extension. simpleName specifies the name of the extension, which is typically a Brand string defined in the extension. (ex. "Dlib" in case of Dlib extension).
I'm not sure about the use of key and reply. At least it's not used currently. Ask Brian about them. This service actually does nothing. Systemcall extensions should install its own handler to USyscall.Rendezvous. The handler typically installs the system call handler for the caller.
Sounds confusing. Here's how a Dlib application starts up.
  1. Dlib user app starts up. At this point, USyscall is loaded and installed, but dlib is not loaded.
  2. The user app calls USyscall_DomainLookup("Dlib"). This calls the name server, and since dlib isn't loaded, nanny is called to load dlib.
  3. Dlib is loaded. Dlib does not installs the system call handler at startup. However, it installs a handler for the USyscall.Rendezvous event.
  4. Control goes back to the user app, and the user app then calls USyscall_Rendezvous("Dlib")
  5. Dlib.Rendezvous is called in response to USyscall.Rendezvous event. This procedure installs a handler for the MachineTrap.Syscall event. As a authorizer key, the triple
    &\lt; user space thread id, min proc ID, max proc ID &\gt;
    is passed to the dispatcher.
  6. Dispatcher installs the systemcall handler along with an imposed guard that checks the systemcall number range and thread identity upon each systemcall event.

Using USyscall From User Space

USyscall is described using Sieg. There is an assembly procedure for each of the services described in the previous section. The name of the procedure is USyscall_ prepended to the original service name. The parameter types obey the sieg rule. Below are examples of user side procedures. See USyscallUser.s also.
void USyscall_Putc(char x);
long USyscall_System(char *command);
long USyscall_Rendezvous(char *simpleName, long key, long *reply);
The most interesting use of USyscall is loading a systemcall extension on demand. Here's the example user bootstrap code.
#define SPIN_NIL_REF (unsigned long)(0x7fffffffffffffff)

__Dlib_BootPrintString(char *s)
{
    while (*s) {
	USyscall_Putc(*s);
	s++;
    }
}
__Dlib_Boot()
{
    unsigned long reply;
    int fd = USyscall_DomainLookup("Dlib");

    if (USyscall_DomainLookup("Dlib") == SPIN_NIL_REF)  {
	__Dlib_BootPrintString("Dlib : could not find\n");
	return 0;
    } else {
	USyscall_Close(fd);
    }
    
    __Dlib_BootPrintString("Rendezvous w/Dlib\n");
    if (USyscall_Rendezvous(name, SPIN_NIL_REF, &reply) == SPIN_FAILURE) {
	 __Dlib_BootPrintString("Could not rendezvous\n");
	 return 0;
    }
    return 1;
}


yasushi@cs.washington.edu