view man/lispref/tooltalk.texi @ 5157:1fae11d56ad2

redo memory-usage mechanism, add way of dynamically initializing Lisp objects -------------------- ChangeLog entries follow: -------------------- lisp/ChangeLog addition: 2010-03-18 Ben Wing <ben@xemacs.org> * diagnose.el (show-memory-usage): Rewrite to take into account API changes in memory-usage functions. src/ChangeLog addition: 2010-03-18 Ben Wing <ben@xemacs.org> * alloc.c: * alloc.c (disksave_object_finalization_1): * alloc.c (lisp_object_storage_size): * alloc.c (listu): * alloc.c (listn): * alloc.c (Fobject_memory_usage_stats): * alloc.c (compute_memusage_stats_length): * alloc.c (Fobject_memory_usage): * alloc.c (Ftotal_object_memory_usage): * alloc.c (malloced_storage_size): * alloc.c (common_init_alloc_early): * alloc.c (reinit_alloc_objects_early): * alloc.c (reinit_alloc_early): * alloc.c (init_alloc_once_early): * alloc.c (syms_of_alloc): * alloc.c (reinit_vars_of_alloc): * buffer.c: * buffer.c (struct buffer_stats): * buffer.c (compute_buffer_text_usage): * buffer.c (compute_buffer_usage): * buffer.c (buffer_memory_usage): * buffer.c (buffer_objects_create): * buffer.c (syms_of_buffer): * buffer.c (vars_of_buffer): * console-impl.h (struct console_methods): * dynarr.c (Dynarr_memory_usage): * emacs.c (main_1): * events.c (clear_event_resource): * extents.c: * extents.c (compute_buffer_extent_usage): * extents.c (extent_objects_create): * extents.h: * faces.c: * faces.c (compute_face_cachel_usage): * faces.c (face_objects_create): * faces.h: * general-slots.h: * glyphs.c: * glyphs.c (compute_glyph_cachel_usage): * glyphs.c (glyph_objects_create): * glyphs.h: * lisp.h: * lisp.h (struct usage_stats): * lrecord.h: * lrecord.h (enum lrecord_type): * lrecord.h (struct lrecord_implementation): * lrecord.h (MC_ALLOC_CALL_FINALIZER_FOR_DISKSAVE): * lrecord.h (DEFINE_DUMPABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_FROB_BLOCK_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_SIZABLE_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_FROB_BLOCK_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_INTERNAL_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_SIZABLE_INTERNAL_LISP_OBJECT): * lrecord.h (MAKE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_LISP_OBJECT): * lrecord.h (DEFINE_DUMPABLE_MODULE_SIZABLE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_LISP_OBJECT): * lrecord.h (DEFINE_NODUMP_MODULE_SIZABLE_LISP_OBJECT): * lrecord.h (MAKE_MODULE_LISP_OBJECT): * lrecord.h (INIT_LISP_OBJECT): * lrecord.h (INIT_MODULE_LISP_OBJECT): * lrecord.h (UNDEF_LISP_OBJECT): * lrecord.h (UNDEF_MODULE_LISP_OBJECT): * lrecord.h (DECLARE_LISP_OBJECT): * lrecord.h (DECLARE_MODULE_API_LISP_OBJECT): * lrecord.h (DECLARE_MODULE_LISP_OBJECT): * lstream.c: * lstream.c (syms_of_lstream): * lstream.c (vars_of_lstream): * marker.c: * marker.c (compute_buffer_marker_usage): * mc-alloc.c (mc_alloced_storage_size): * mc-alloc.h: * mule-charset.c: * mule-charset.c (struct charset_stats): * mule-charset.c (compute_charset_usage): * mule-charset.c (charset_memory_usage): * mule-charset.c (mule_charset_objects_create): * mule-charset.c (syms_of_mule_charset): * mule-charset.c (vars_of_mule_charset): * redisplay.c: * redisplay.c (compute_rune_dynarr_usage): * redisplay.c (compute_display_block_dynarr_usage): * redisplay.c (compute_glyph_block_dynarr_usage): * redisplay.c (compute_display_line_dynarr_usage): * redisplay.c (compute_line_start_cache_dynarr_usage): * redisplay.h: * scrollbar-gtk.c (gtk_compute_scrollbar_instance_usage): * scrollbar-msw.c (mswindows_compute_scrollbar_instance_usage): * scrollbar-x.c (x_compute_scrollbar_instance_usage): * scrollbar.c (compute_scrollbar_instance_usage): * scrollbar.h: * symbols.c: * symbols.c (reinit_symbol_objects_early): * symbols.c (init_symbols_once_early): * symbols.c (reinit_symbols_early): * symbols.c (defsymbol_massage_name_1): * symsinit.h: * ui-gtk.c: * ui-gtk.c (emacs_gtk_object_getprop): * ui-gtk.c (emacs_gtk_object_putprop): * ui-gtk.c (ui_gtk_objects_create): * unicode.c (compute_from_unicode_table_size_1): * unicode.c (compute_to_unicode_table_size_1): * unicode.c (compute_from_unicode_table_size): * unicode.c (compute_to_unicode_table_size): * window.c: * window.c (struct window_stats): * window.c (compute_window_mirror_usage): * window.c (compute_window_usage): * window.c (window_memory_usage): * window.c (window_objects_create): * window.c (syms_of_window): * window.c (vars_of_window): * window.h: Redo memory-usage mechanism, make it general; add way of dynamically initializing Lisp object types -- OBJECT_HAS_METHOD(), similar to CONSOLE_HAS_METHOD(). (1) Create OBJECT_HAS_METHOD(), OBJECT_HAS_PROPERTY() etc. for specifying that a Lisp object type has a particular method or property. Call such methods with OBJECT_METH, MAYBE_OBJECT_METH, OBJECT_METH_OR_GIVEN; retrieve properties with OBJECT_PROPERTY. Methods that formerly required a DEFINE_*GENERAL_LISP_OBJECT() to specify them (getprop, putprop, remprop, plist, disksave) now instead use the dynamic-method mechanism. The main benefit of this is that new methods or properties can be added without requiring that the declaration statements of all existing methods be modified. We have to make the `struct lrecord_implementation' non-const, but I don't think this should have any effect on speed -- the only possible method that's really speed-critical is the mark method, and we already extract those out into a separate (non-const) array for increased cache locality. Object methods need to be reinitialized after pdump, so we put them in separate functions such as face_objects_create(), extent_objects_create() and call them appropriately from emacs.c The only current object property (`memusage_stats_list') that objects can specify is a Lisp object and gets staticpro()ed so it only needs to be set during dump time, but because it references symbols that might not exist in a syms_of_() function, we initialize it in vars_of_(). There is also an object property (`num_extra_memusage_stats') that is automatically initialized based on `memusage_stats_list'; we do that in reinit_vars_of_alloc(), which is called after all vars_of_() functions are called. `disksaver' method was renamed `disksave' to correspond with the name normally given to the function (e.g. disksave_lstream()). (2) Generalize the memory-usage mechanism in `buffer-memory-usage', `window-memory-usage', `charset-memory-usage' into an object-type- specific mechanism called by a single function `object-memory-usage'. (Former function `object-memory-usage' renamed to `total-object-memory-usage'). Generalize the mechanism of different "slices" so that we can have different "classes" of memory described and different "slices" onto each class; `t' separates classes, `nil' separates slices. Currently we have three classes defined: the memory of an object itself, non-Lisp-object memory associated with the object (e.g. arrays or dynarrs stored as fields in the object), and Lisp-object memory associated with the object (other internal Lisp objects stored in the object). This isn't completely finished yet and we might need to further separate the "other internal Lisp objects" class into two classes. The memory-usage mechanism uses a `struct usage_stats' (renamed from `struct overhead_stats') to describe a malloc-view onto a set of allocated memory (listing how much was requested and various types of overhead) and a more general `struct generic_usage_stats' (with a `struct usage_stats' in it) to hold all statistics about object memory. `struct generic_usage_stats' contains an array of 32 Bytecounts, which are statistics of unspecified semantics. The intention is that individual types declare a corresponding struct (e.g. `struct window_stats') with the same structure but with specific fields in place of the array, corresponding to specific statistics. The number of such statistics is an object property computed from the list of tags (Lisp symbols describing the statistics) stored in `memusage_stats_list'. The idea here is to allow particular object types to customize the number and semantics of the statistics where completely avoiding consing. This doesn't matter so much yet, but the intention is to have the memory usage of all objects computed at the end of GC, at the same time as other statistics are currently computed. The values for all statistics for a single type would be added up to compute aggregate values for all objects of a specific type. To make this efficient, we can't allow any memory allocation at all. (3) Create some additional functions for creating lists that specify the elements directly as args rather than indirectly through an array: listn() (number of args given), listu() (list terminated by Qunbound). (4) Delete a bit of remaining unused C window_config stuff, also unused lrecord_type_popup_data.
author Ben Wing <ben@xemacs.org>
date Thu, 18 Mar 2010 10:50:06 -0500
parents 576fb035e263
children 9fae6227ede5
line wrap: on
line source

@c -*-texinfo-*-
@c This is part of the XEmacs Lisp Reference Manual.
@c Copyright (C) 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
@c See the file lispref.texi for copying conditions.
@setfilename ../../info/tooltalk.info
@node ToolTalk Support, LDAP Support, X-Windows, top
@chapter ToolTalk Support
@cindex ToolTalk

@menu
* XEmacs ToolTalk API Summary::
* Sending Messages::
* Receiving Messages::
@end menu

@node XEmacs ToolTalk API Summary
@section XEmacs ToolTalk API Summary

The XEmacs Lisp interface to ToolTalk is similar, at least in spirit,
to the standard C ToolTalk API.  Only the message and pattern parts
of the API are supported at present; more of the API could be added
if needed.  The Lisp interface departs from the C API in a few ways:

@itemize @bullet
@item
ToolTalk is initialized automatically at XEmacs startup-time.  Messages
can only be sent other ToolTalk applications connected to the same X11
server that XEmacs is running on.

@item
There are fewer entry points; polymorphic functions with keyword
arguments are used instead.

@item
The callback interface is simpler and marginally less functional.
A single callback may be associated with a message or a pattern;
the callback is specified with a Lisp symbol (the symbol should
have a function binding).

@item
The session attribute for messages and patterns is always
initialized to the default session.

@item
Anywhere a ToolTalk enum constant, e.g. @samp{TT_SESSION}, is valid, one
can substitute the corresponding symbol, e.g. @code{'TT_SESSION}.  This
simplifies building lists that represent messages and patterns.
@end itemize

@node Sending Messages
@section Sending Messages
@cindex sending ToolTalk messages
@cindex ToolTalk message

@menu
* Example of Sending Messages::
* Elisp Interface for Sending Messages::
@end menu

@node Example of Sending Messages
@subsection Example of Sending Messages

Here's a simple example that sends a query to another application
and then displays its reply.  Both the query and the reply are
stored in the first argument of the message.

@example
(defun tooltalk-random-query-handler (msg)
  (let ((state (get-tooltalk-message-attribute msg 'state)))
    (cond
      ((eq state 'TT_HANDLED)
       (message (get-tooltalk-message-attribute msg arg_val 0)))
      ((memq state '(TT_FAILED TT_REJECTED))
       (message "Random query turns up nothing")))))

(defvar random-query-message
  '(   class TT_REQUEST
       scope TT_SESSION
     address TT_PROCEDURE
          op "random-query"
        args '((TT_INOUT "?" "string"))
    callback tooltalk-random-query-handler))

(let ((m (make-tooltalk-message random-query-message)))
  (send-tooltalk-message m))
@end example

@node Elisp Interface for Sending Messages
@subsection Elisp Interface for Sending Messages

@defun make-tooltalk-message attributes
Create a ToolTalk message and initialize its attributes.
The value of @var{attributes} must be a list of alternating keyword/values,
where keywords are symbols that name valid message attributes.
For example:

@example
  (make-tooltalk-message
    '(class TT_NOTICE
      scope TT_SESSION
      address TT_PROCEDURE
      op "do-something"
      args ("arg1" 12345 (TT_INOUT "arg3" "string"))))
@end example

Values must always be strings, integers, or symbols that represent
ToolTalk constants.  Attribute names are the same as those supported by
@code{set-tooltalk-message-attribute}, plus @code{args}.

The value of @code{args} should be a list of message arguments where
each message argument has the following form:

@quotation
   @samp{(mode [value [type]])} or just @samp{value}
@end quotation

Where @var{mode} is one of @code{TT_IN}, @code{TT_OUT}, or
@code{TT_INOUT} and @var{type} is a string.  If @var{type} isn't
specified then @code{int} is used if @var{value} is a number; otherwise
@code{string} is used.  If @var{type} is @code{string} then @var{value}
is converted to a string (if it isn't a string already) with
@code{prin1-to-string}.  If only a value is specified then @var{mode}
defaults to @code{TT_IN}.  If @var{mode} is @code{TT_OUT} then
@var{value} and @var{type} don't need to be specified.  You can find out
more about the semantics and uses of ToolTalk message arguments in
chapter 4 of the @cite{ToolTalk Programmer's Guide}.
@refill
@end defun

@defun send-tooltalk-message msg
Send the message on its way.  Once the message has been sent it's almost
always a good idea to get rid of it with
@code{destroy-tooltalk-message}.
@refill
@end defun

@defun return-tooltalk-message msg &optional mode
Send a reply to this message.  The second argument can be @code{reply},
@code{reject} or @code{fail}; the default is @code{reply}.  Before
sending a reply, all message arguments whose mode is @code{TT_INOUT} or
@code{TT_OUT} should have been filled in---see
@code{set-tooltalk-message-attribute}.
@refill
@end defun

@defun get-tooltalk-message-attribute msg attribute &optional argn
Returns the indicated ToolTalk message attribute.  Attributes are
identified by symbols with the same name (underscores and all) as the
suffix of the ToolTalk @samp{tt_message_<attribute>} function that
extracts the value.  String attribute values are copied and enumerated
type values (except disposition) are converted to symbols;
e.g. @samp{TT_HANDLER} is @code{'TT_HANDLER}, @samp{uid} and @samp{gid}
are represented by fixnums (small integers), @samp{opnum} is converted
to a string, and @samp{disposition} is converted to a fixnum.  We
convert @samp{opnum} (a C int) to a string (e.g. @code{123} @result{}
@code{"123"}) because there's no guarantee that opnums will fit within
the range of XEmacs Lisp integers.
@refill

[TBD] Use the @code{plist} attribute instead of C API @code{user}
attribute for user-defined message data.  To retrieve the value of a
message property, specify the indicator for @var{argn}.  For example, to
get the value of a property called @code{rflag}, use

@example
   (get-tooltalk-message-attribute msg 'plist 'rflag)
@end example

To get the value of a message argument use one of the @code{arg_val}
(strings), @code{arg_ival} (integers), or @code{arg_bval} (strings with
embedded nulls), attributes.  For example, to get the integer value of
the third argument:

@example
   (get-tooltalk-message-attribute msg 'arg_ival 2)
@end example

As you can see, argument numbers are zero-based.  The type of each
arguments can be retrieved with the @code{arg_type} attribute; however
ToolTalk doesn't define any semantics for the string value of
@code{arg_type}.  Conventionally @code{string} is used for strings and
@code{int} for 32 bit integers.  Note that XEmacs Lisp stores the lengths
of strings explicitly (unlike C) so treating the value returned by
@code{arg_bval} like a string is fine.
@refill
@end defun

@defun set-tooltalk-message-attribute value msg attribute &optional argn
Initialize one ToolTalk message attribute.

Attribute names and values are the same as for
@code{get-tooltalk-message-attribute}.  A property list is provided for
user data (instead of the @code{user} message attribute); see
@code{get-tooltalk-message-attribute}.
@refill

Callbacks are handled slightly differently than in the C ToolTalk API.
The value of @var{callback} should be the name of a function of one
argument.  It will be called each time the state of the message changes.
This is usually used to notice when the message's state has changed to
@code{TT_HANDLED} (or @code{TT_FAILED}), so that reply argument values
can be used.
@refill

If one of the argument attributes is specified as @code{arg_val},
@code{arg_ival}, or @code{arg_bval}, then @var{argn} must be the
number of an already created argument.  Arguments can be added to a
message with @code{add-tooltalk-message-arg}.
@refill
@end defun

@defun add-tooltalk-message-arg msg mode type &optional value
Append one new argument to the message.  @var{mode} must be one of
@code{TT_IN}, @code{TT_INOUT}, or @code{TT_OUT}, @var{type} must be a
string, and @var{value} can be a string or an integer.  ToolTalk doesn't
define any semantics for @var{type}, so only the participants in the
protocol you're using need to agree what types mean (if anything).
Conventionally @code{string} is used for strings and @code{int} for 32
bit integers.  Arguments can initialized by providing a value or with
@code{set-tooltalk-message-attribute}; the latter is necessary if you
want to initialize the argument with a string that can contain embedded
nulls (use @code{arg_bval}).
@refill
@end defun

@defun create-tooltalk-message &optional no-callback
Create a new ToolTalk message.  The message's session attribute is
initialized to the default session.  Other attributes can be initialized
with @code{set-tooltalk-message-attribute}.
@code{make-tooltalk-message} is the preferred way to create and
initialize a message.

Optional arg @var{no-callback} says don't add a C-level callback at all.
Normally don't do that; just don't specify the Lisp callback when
calling @code{make-tooltalk-message}.
@refill
@end defun

@defun destroy-tooltalk-message msg
Apply @samp{tt_message_destroy} to the message.  It's not necessary to
destroy messages after they've been processed by a message or pattern
callback, the Lisp/ToolTalk callback machinery does this for you.
@end defun

@node Receiving Messages
@section Receiving Messages
@cindex ToolTalk pattern
@cindex receiving ToolTalk messages

@menu
* Example of Receiving Messages::
* Elisp Interface for Receiving Messages::
@end menu

@node Example of Receiving Messages
@subsection Example of Receiving Messages

Here's a simple example of a handler for a message that tells XEmacs to
display a string in the mini-buffer area.  The message operation is
called @samp{emacs-display-string}.  Its first (0th) argument is the
string to display.

@example
(defun tooltalk-display-string-handler (msg)
  (message (get-tooltalk-message-attribute msg 'arg_val 0)))

(defvar display-string-pattern
  '(category TT_HANDLE
       scope TT_SESSION
          op "emacs-display-string"
    callback tooltalk-display-string-handler))

(let ((p (make-tooltalk-pattern display-string-pattern)))
  (register-tooltalk-pattern p))
@end example

@node Elisp Interface for Receiving Messages
@subsection Elisp Interface for Receiving Messages

@defun make-tooltalk-pattern attributes
Create a ToolTalk pattern and initialize its attributes.
The value of attributes must be a list of alternating keyword/values,
where keywords are symbols that name valid pattern attributes
or lists of valid attributes.  For example:

@example
  (make-tooltalk-pattern
    '(category TT_OBSERVE
         scope TT_SESSION
            op ("operation1" "operation2")
          args ("arg1" 12345 (TT_INOUT "arg3" "string"))))
@end example

Attribute names are the same as those supported by
@code{add-tooltalk-pattern-attribute}, plus @code{'args}.

Values must always be strings, integers, or symbols that represent
ToolTalk constants or lists of same.  When a list of values is provided
all of the list elements are added to the attribute.  In the example
above, messages whose @samp{op} attribute is @samp{"operation1"} or
@samp{"operation2"} would match the pattern.

The value of @var{args} should be a list of pattern arguments where each
pattern argument has the following form:

@quotation
   @samp{(mode [value [type]])} or just @samp{value}
@end quotation

Where @var{mode} is one of @code{TT_IN}, @code{TT_OUT}, or
@code{TT_INOUT} and @var{type} is a string.  If @var{type} isn't
specified then @code{int} is used if @var{value} is a number; otherwise
@code{string} is used.  If @var{type} is @code{string} then @var{value}
is converted to a string (if it isn't a string already) with
@code{prin1-to-string}.  If only a value is specified then @var{mode}
defaults to @code{TT_IN}.  If @var{mode} is @code{TT_OUT} then
@var{value} and @var{type} don't need to be specified.  You can find out
more about the semantics and uses of ToolTalk pattern arguments in
chapter 3 of the @cite{ToolTalk Programmer's Guide}.
@refill
@end defun

@defun register-tooltalk-pattern pattern
XEmacs will begin receiving messages that match this pattern.
@end defun

@defun unregister-tooltalk-pattern pattern
XEmacs will stop receiving messages that match this pattern.
@end defun

@defun add-tooltalk-pattern-attribute value pattern indicator
Add one value to the indicated pattern attribute. The names of
attributes are the same as the ToolTalk accessors used to set them less
the @samp{tooltalk_pattern_} prefix and the @samp{_add} suffix.  For
example, the name of the attribute for the
@samp{tt_pattern_disposition_add} attribute is @code{disposition}.  The
@code{category} attribute is handled specially, since a pattern can only
be a member of one category (@code{TT_OBSERVE} or @code{TT_HANDLE}).
@refill

Callbacks are handled slightly differently than in the C ToolTalk API.
The value of @var{callback} should be the name of a function of one
argument.  It will be called each time the pattern matches an incoming
message.
@end defun

@defun add-tooltalk-pattern-arg pattern mode vtype &optional value
Add one fully-specified argument to a ToolTalk pattern.  @var{mode} must
be one of @code{TT_IN}, @code{TT_INOUT}, or @code{TT_OUT}.  @var{vtype}
must be a string.  @var{value} can be an integer, string or @code{nil}.
If @var{value} is an integer then an integer argument
(@samp{tt_pattern_iarg_add}) is added; otherwise a string argument is
added.  At present there's no way to add a binary data argument.
@refill
@end defun

@defun create-tooltalk-pattern
Create a new ToolTalk pattern and initialize its session attribute to
be the default session.
@end defun

@defun destroy-tooltalk-pattern pattern
Apply @samp{tt_pattern_destroy} to the pattern.  This effectively
unregisters the pattern.
@end defun

@defun describe-tooltalk-message msg &optional stream
Print the message's attributes and arguments to @var{stream}.  This is
often useful for debugging.
@end defun