alp man page on IRIX

Man page or keyword search:  
man Server   31559 pages
apropos Keyword Search (all sections)
Output format
IRIX logo
[printable version]



alp(7)									alp(7)

NAME
     alp - algorithm pool management module

DESCRIPTION
     The STREAMS module alp maintains a pool of algorithms (in the form of
     STREAMS-compatible subroutines) that may be used for processing STREAMS
     data messages.  Interfaces are defined allowing modules to request and
     initiate processing by any of the algorithms maintained in the pool.  It
     is expected to help centralize and standardize the interfaces to
     algorithms that now represent a proliferation of similar-but-different
     STREAMS modules.  Its major use is envisioned as a central registry of
     available code set conversion algorithms or other types of common data-
     manipulating routines.

     An algorithm pool is a registry (or pool) of available functions; in this
     case, routines for performing transformations on STREAMS data messages.
     Registered functions may keep information on attached users, which means
     that algorithms need not be stateless, but may maintain extensive state
     information related to each connection.  An algorithm from the pool is
     called by another in-kernel module with arguments that are a STREAMS data
     message and a unique identifier.  If a message is passed back to the
     caller, it is the algorithm's output, otherwise the algorithm may store
     partially convertible input until enough input is received to give back
     output on a subsequent call.

     This pool is one means for providing a consistent and flexible interface
     for code set conversion within STREAMS modules, especially kbd, but it
     may also be used to provide other services that are commonly duplicated
     by several modules.

     The alp module contains some subroutines dealing with its (minor) role as
     a module, a data definition for an algorithm list, connection and
     disconnection routines, and a search routine for finding registered
     items. The module interface incorporated into alp serves the purpose of
     providing an ioctl interface, so that users can find out what algorithms
     are registered [see alpq(1)].

     The programmer of a function for use with alp provides a simple module
     with a simple specified interface.	 The module must have an
     initialization routine (xxxinit) which is called at system startup time
     to register itself with alp, an open routine, and an interface routine
     (which actually implements the algorithm).

     The registry method of dynamically building the list of available
     functions obviates the need for recompiling modules or otherwise updating
     a list or reconfiguring other parts of the system to accommodate
     additions or deletions. To install a new function module, one merely
     links it with the kernel in whatever manner is standard for that system;
     there is no need for updating or re-configuring any other parts of the
     kernel (including alp itself).  The remainder of this discussion concerns
     the in-kernel operation and use of the module.

									Page 1

alp(7)									alp(7)

   Calling Sequence
     An algorithm is called from the pool by first requesting a connection via
     the alp connection interface.  The alp module returns the function
     address of an interface routine, and fills in a unique identifier (id)
     for the connection.  The returned function address is NULL on failure
     (and id is undefined).  This is a sample of making a connection to a
     function managed by alp:
	  unsigned char *name;	  /* algorithm name */
	  caddr_t id;		  /* unique id */
	  mblk_t *(*func)();	  /* func returns pointer to mblk_t */
	  mblk_t *(*alp_con())(); /* returns pointer to mblk_t */
	  ...
	  if (func = alp_con(name, (caddr_t) &id))
	       regular processing;
	  else
	       error processing;

     Once the connection has been made, the interface routine can be called
     directly by the connecting module to process messages:
	  mblk_t *inp, *outp;
	  mblk_t *(*func)();
	  ...
	  outp = (*func)(mp, id);
	  mp = NULL;   /* mp cannot be re-used! */
	  if (outp)
	       regular processing;

     If the interface routine processed the entire message, then outp is a
     valid pointer to the algorithm's output message.  If, however, the
     routine needs more information, or is buffering something, outp will be a
     null pointer.  In either case, the original message (mp) may not be
     subsequently accessed by the caller.  The interface routine takes charge
     of the message mp, and may free it or otherwise dispose of it (it may
     even return the same message).  The caller may pass a null message
     pointer to an interface routine to cause a flush of any data being held
     by the routine; this is useful for end-of-file conditions to insure that
     all data have been passed through.	 (Interface routines must thus
     recognize a null message pointer and deal with it.)

     Synchronization between input and output messages is not guaranteed for
     all items in the pool.  If one message of input does not produce one
     message of output, this fact should be documented for that particular
     module.  Many multibyte code set conversion algorithms, to cite one
     instance, buffer partial sequences, so that if a multibyte character
     happens to be spread across more than one message, it may take two or
     more output messages to complete translation; in this case, it is only
     possible to synchronize when input message boundaries coincide with
     character boundaries.

									Page 2

alp(7)									alp(7)

   Building an Algorithm for the Pool
     As mentioned, the modules managed by alp are implemented as simple
     modules-not STREAMS modules-each with an initialization routine, an open
     routine, and a user-interface routine.  The initialization routine is
     called when the system is booted and prior to nearly everything else that
     happens at boot-time.  The routine takes no arguments and its sole
     purpose is to register the algorithm with the alp module, so that it may
     subsequently accessed.  Any other required initialization may also be
     performed at that time. A generic initialization routine for a module
     called GEN, with prefix gen is as follows:
	  geninit()
	  {
	       mblk_t *genfunc(); /* interface routine */
	       int rval;	  /* return value from registrar */

	       rval = alp_register(genfunc, "name", "explanation");
	       if (rval) cmn_err(CE_WARN, "warning message");
	  }

     The registration routine, alp_register takes three arguments and returns
     zero if successful.  The arguments are (1) a pointer to the algorithm's
     entry point (in this case, the function genfunc), (2) a pointer to its
     name, and (3) a pointer to a character string containing a brief
     explanation.  The name should be limited to under 16 bytes, and the
     explanation to under 60 bytes, as shown in the following example.
     Neither the name nor the explanation need include a newline.
	i = alp_register(sjisfunc, "stou", "Shift-JIS to UJIS converter");

     It is possible for a single module to contain several different, related
     algorithms, which can each be registered separately by a single init
     routine.

     A module's open routine is called by alp_con when a connection is first
     requested by a user (that is, a module that wishes to use it).  The open
     routine takes two arguments.  The first argument is an integer; if it is
     non-zero, the request is an open request, and the second argument is
     unused.  The function should allocate a unique identifier and return it
     as a generic address pointer.  If the first argument is zero, the request
     is a close request, and the second argument is the unique identifier that
     was returned by a previous open request, indicating which of (potentially
     several) connections is to be closed.  The routine does any necessary
     clean-up and closes the connection; thereafter, any normal interface
     requests on that identifier will fail.  This use of unique identifiers
     allows these modules to keep state information relating to each open
     connection; no format is imposed upon the unique identifier, so it may
     contain any arbitrary type of information, equivalent in size to a core
     address; alp and most callers will treat it as being of type caddr_t, in
     a manner similar to the private data held by each instantiation of a
     STREAMS module.

									Page 3

alp(7)									alp(7)

     A skeleton for the gen module's open routine is:
	  genopen(arg, id)
	       int arg;
	       caddr_t id;
	  {
	       if ( arg ) {
		    open processing;
		    return( unique-id );
	       }
	       close processing for id;
	       return(0);
	  }

     Once a connection has been made, users may proceed as in the example in
     the previous section.  When the connection is to be closed (for example,
     the connecting module is being popped), a call is made to alp_discon,
     passing the unique id and the name:
	  caddr_t id;
	  char *name;
	  mblk_t *alp_discon(), *mp;
	  ...
	  mp = alp_discon(name, id);
	  if (mp)
	       process ``left-over'' data;

     If the disconnect request returns a valid message pointer (mp) then there
     was unprocessed or partially processed data left in an internal buffer,
     and it should be dealt with by the caller (for example, by flushing it or
     sending it to the neighboring module).

   The ioctl and Query Interfaces
     A kernel-level query interface is provided in addition to the query
     interface supported by the alpq command.  The routine alp_query takes a
     single argument, a pointer to a name.  If the name matches a registered
     function, alp_query returns a pointer to the function's explanation
     string, otherwise it returns a null pointer.  A calling example is:
	  unsigned char *alp_query(), *name, *expl;
	  ...
	  if (expl = alp_query(name))
	       regular processing;
	  else
	       error processing;

     The ioctl interface provides calls for querying registered functions (for
     which the explanation discussed above is necessary); this is supported by
     the alpq command, which may be used whenever user-level programs need the
     associated information.

									Page 4

alp(7)									alp(7)

   Uses
     The alp module can be used to replace various kernel-resident code set
     conversion functions in international or multi-language environments.
     The KBD subsystem (which supplies code set conversion and keyboard
     mapping) supports the use of alp algorithms as processing elements.

     Since state information may be maintained, functions may also implement
     processing on larger or more structured data elements, such as
     transaction records and network packets.  Currently, STREAMS CPU priority
     is assumed by alp or should be set individually by interface and open
     routines.

									Page 5

alp(7)									alp(7)

EXAMPLES
     /*
      * This is a SAMPLE module that registers with ALP and performs
      * a one-message delay.
      */
     #include <sys/types.h>
     #include <sys/stream.h>
     #include <sys/stropts.h>
     #include <sys/kmem.h>
     #include <sys/alp.h>

     static mblk_t *dely();
     caddr_t delyopen();

     /*
      * Our state structure.  Keeps its own address and a pointer.
      */
     struct dstruct {
	  caddr_t d_unique;
	  mblk_t *d_mp;
     };

     /*
      * The name is "Dely".  It has an open routine "delyopen"
      * and an interface "dely".
      */
     static struct algo delyalgo =
     {
	  0, (queue_t *) 0, (queue_t *) 0, dely, delyopen,
	  (unsigned char *) "Dely",
	  (unsigned char *) "One Message Delay Buffer",
	  (struct algo *) 0
     };

     /*
      * This is the sysinit routine, called when the system is
      * being brought up.  It registers "Dely" with ALP.
      */
     delyinit()
     {
	  if (alp_register(&delyalgo))	/* then register with ALP */
	       printf("DELY: register failed\n");
     }
     /*
      * This is the interface routine itself.
      * Holds onto "mp" and returns whatever it had before.
      */
     static mblk_t *
     dely(mp, id)
	  mblk_t *mp;
	  caddr_t id;
     {

									Page 6

alp(7)									alp(7)

	 register mblk_t *rp;
	  register struct dstruct *d;

	  d = (struct dstruct *) id;	/* clarify the situation */
	  rp = d->d_mp;
	  d->d_mp = mp;
	  return(rp);	      /* return the previous message */
     }

     /*
      * The open (and close) routine.  Use kmem_alloc() to get a private
      * structure for saving state info.
      */
     caddr_t
     delyopen(arg, id)
	  int arg;  /* 1 = open, 0 = close */
	  caddr_t id;	 /* ignored on open; is unique id on close */
     {
	  register struct dstruct *d;
	  register mblk_t *rp;

	  if (! arg) {	 /* close processing */
	       d = (struct dstruct *) id;
	       d->d_unique = (caddr_t) -1;
	       rp = d->d_mp;
	       kmem_free(d, sizeof(struct dstruct));
	       return((caddr_t) rp);
	  }
	  /* otherwise, open processing */
	  d = (struct dstruct *) kmem_zalloc(sizeof(struct dstruct),
		     KM_NOSLEEP);
	  d->d_unique = (caddr_t) &d;
	  return((caddr_t) d);
     }

SEE ALSO
     alpq(1), kbd(7).

									Page 7

[top]

List of man pages available for IRIX

Copyright (c) for man pages and the logo by the respective OS vendor.

For those who want to learn more, the polarhome community provides shell access and support.

[legal] [privacy] [GNU] [policy] [cookies] [netiquette] [sponsors] [FAQ]
Tweet
Polarhome, production since 1999.
Member of Polarhome portal.
Based on Fawad Halim's script.
....................................................................
Vote for polarhome
Free Shell Accounts :: the biggest list on the net