1% BEGIN LICENSE BLOCK 2% Version: CMPL 1.1 3% 4% The contents of this file are subject to the Cisco-style Mozilla Public 5% License Version 1.1 (the "License"); you may not use this file except 6% in compliance with the License. You may obtain a copy of the License 7% at www.eclipse-clp.org/license. 8% 9% Software distributed under the License is distributed on an "AS IS" 10% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11% the License for the specific language governing rights and limitations 12% under the License. 13% 14% The Original Code is The ECLiPSe Constraint Logic Programming System. 15% The Initial Developer of the Original Code is Cisco Systems, Inc. 16% Portions created by the Initial Developer are 17% Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. 18% 19% Contributor(s): 20% 21% END LICENSE BLOCK 22% 23% $Id: umsexcept.tex,v 1.5 2013/02/09 20:27:58 jschimpf Exp $ 24% 25% Created from umsexcept.tex 26% 27 28%---------------------------------------------------------------------- 29\chapter{Events and Interrupts} 30%HEVEA\cutdef[1]{section} 31%---------------------------------------------------------------------- 32\label{chapexcept} 33 34The normal execution of a Prolog program may be interrupted by 35events and interrupts: 36 37\begin{quote} 38\begin{description} 39\item[Events]\mbox{}\\ 40 Events have the following properties: 41 \begin{itemize} 42 \item they may occur asynchronously (when posted by the environment) 43 or synchronously (when raised by the program itself); 44 \item they are handled synchronously by a handler goal that is inserted 45 into the resolvent; 46 \item the handler can cause the interrupted execution to fail or to abort; 47 \item the handler can interact with the interrupted execution only via 48 non-logical features (e.g., global variable or references); 49 \item the handler can cause waking of delayed goals via symbolic triggers. 50 \end{itemize} 51 52\item[Errors]\mbox{}\\ 53 Errors can be viewed as a special case of events. They are raised by 54 built-in predicates (e.g., when the arguments are of the wrong type) 55 and usually pass the culprit goal to the error handler. 56 57\item[Interrupts]\mbox{}\\ 58 Interrupts usually originate from the operating system, e.g., on a Unix 59 host, signals are mapped to {\eclipse} interrupts. 60 \begin{itemize} 61 \item they occur asynchronously, but may be mapped into a sychronous event; 62 \item certain predefined actions (like aborting) can be performed 63 asynchronously. 64% \item in Unix, the handler can be executed asynchronously in a separate 65% {\eclipse} engine. This means that 66% \item the handler cannot interact with interrupted execution, except via 67% global variables, files and the like. 68% \item failure of the handler is ignored. 69% \item the development system catches and handles many operating system 70% signals as interrupts, user abort by typing \verb.^.C, 71% data arriving at sockets, memory protection faults, etc. 72 \end{itemize} 73\end{description} 74\end{quote} 75 76 77%---------------------------------------------------------------------- 78\section{Events} 79%---------------------------------------------------------------------- 80\index{events} 81 82\subsection{Event Identifiers and Event Handling} 83 84Events are identified by names (atoms) or by anonymous handles. 85 86When an event is raised, a call to the appropriate handler is inserted 87into the resolvent (the sequence of executing goals). 88The handler will be executed as soon as possible, which means at the 89next synchronous point in execution, which is usually just before the 90next regular predicate is invoked. Note that there are a few 91built-in predicates that can run for a long time and will not allow 92handlers to be executed until they return (e.g., \predspec{read/1}, 93\predspec{sort/4}). 94 95 96\subsubsection{Creating Named Events} 97 98A named event is created by defining a handler for it using 99\bipref{set_event_handler/2}{../bips/kernel/event/set_event_handler-2.html}: 100\begin{quote} 101\begin{verbatim} 102:- set_event_handler(hello, my_handler/1). 103my_handler(Event) :- 104 <code to deal with Event> 105\end{verbatim} 106\end{quote} 107A handler for a named event can have zero or one arguments. When invoked, 108the first argument is the event identifier, in this case the atom 109\notation{hello}. 110It is not possible to pass other information to the handler. 111 112The handler for a defined event can be queried using 113\bipref{get_event_handler/3}{../bips/kernel/event/get_event_handler-3.html}. 114 115 116\subsubsection{Creating Anonymous Events} 117 118An anonymous event is created with the built-in 119\bipref{event_create/3}{../bips/kernel/event/event_create-3.html}: 120\begin{quote} 121\begin{verbatim} 122..., event_create(my_other_handler(...), [], Event), ... 123\end{verbatim} 124\end{quote} 125The built-in takes a handler goal and creates an anonymous event handle Event. 126This handle is the only way to identify the event, and therefore must be 127passed to any program location that wants to raise the event. 128The handler goal can be of any arity and can take arbitrary arguments. 129Typically, these arguments would include the Event handle itself and other 130ground arguments (variables should not be passed because when the event 131is raised, a copy of the handler goal with fresh variables will be executed). 132 133 134\subsection{Raising Events} 135Events can be raised in the following different ways: 136\begin{itemize} 137\item Explicitly by the {\eclipse} program itself, using 138 \bipref{event/1}{../bips/kernel/event/event-1.html}. 139\item By foreign code (C/C++) using the \notation{ec_post_event()} function. 140\item Via signals/interrupts by setting the interrupt handler to 141 \bipref{event/1}{../bips/kernel/event/event-1.html}. 142\item Via I/O streams (e.g., queues can be configured to raise an event 143 when they get written into). 144\item Via timers, so-called after-events 145\end{itemize} 146 147\subsubsection{Raising Events Explicitly} 148To raise an event from within {\eclipse} code, call 149\bipref{event/1}{../bips/kernel/event/event-1.html} with the event 150identifier as its argument. If no handler has been defined, a warning 151will be raised: 152\begin{quote} 153\begin{verbatim} 154?- event(hello). 155WARNING: no handler for event in hello 156Yes (0.00s cpu) 157\end{verbatim} 158\end{quote} 159The event can be an anonymous event handle, e.g., 160\begin{quote} 161\begin{verbatim} 162?- event_create(writeln(handling(E)), [], E), event(E). 163handling('EVENT'(16'edbc0b20)) 164E = 'EVENT'(16'edbc0b20) 165Yes (0.00s cpu) 166\end{verbatim} 167\end{quote} 168Raising events explicitly is mainly useful for test purposes, since 169it is almost the same as calling the handler directly. 170 171\subsubsection{Raising Events from Foreign Code} 172To raise an event from within foreign C/C++ code, call 173\begin{quote} 174\begin{verbatim} 175ec_post_event(ec_atom(ec_did("hello",0))); 176\end{verbatim} 177\end{quote} 178This works both when the foreign code is called from {\eclipse} or when 179{\eclipse} is embedded into a foreign code host program. 180 181 182\subsubsection{Timed Events (``after'' events)} 183\index{after events} 184\index{timers} 185\index{timed events} 186 187An event can be triggered after a specified amount 188of elapsed time. The event is then handled sychronously by {\eclipse}. 189These events are known as ``after'' 190events, as they are set up so that the event occurs \emph{after} a 191certain amount of elapsed time. 192They are setup by one of the following predicates: 193 194\begin{quote} 195\begin{description} 196\item[\biptxtref{event_after(+\pattern{EventId},~+\pattern{Time})}% 197{event_after/2}{../bips/kernel/event/event_after-2.html}] 198This sets up an event \about{EventId} so that the event is raised once after 199\about{Time} seconds 200of elapsed time from when the predicate is executed. \about{EventId} is an event 201identifier and \about{Time} is a positive number. 202 203\item[\biptxtref{event_after_every(+\pattern{EventId},~+\pattern{Time})}% 204{event_after_every/2}{../bips/kernel/event/event_after_every-2.html}] 205This sets up an event \about{EventId} so 206that the event is raised repeatedly every \about{Time} seconds: first 207\about{Time} seconds after the invocation of the predicate, then \about{Time} 208seconds after that event was raised, and so on. 209 210\item[\biptxtref{events_after(+\pattern{EventList})}% 211{events_after/1}{../bips/kernel/event/events_after-1.html}] 212This sets up a series of after events specified in the list \about{EventList}, 213which contains events of the form \pattern{EventId-Time}, or 214\pattern{EventId-every(Time)} (specifying a single 215event or a repeated event respectively). 216 217The \about{Time} parameter is actually the minimum of elapsed time before the 218event is raised. Factors constraining the actual time of raising of the 219event include the granularity of the system clock, and also that {\eclipse} 220must be in a state where it can \emph{synchronously} process the event, i.e., 221where it can make a procedure call. 222 223Once an after event has been set up, it is pending until it is raised. In 224the case of events caused by an invocation of \predspec{event_after_every/2}, 225the event will always be pending 226because it is raised repeatedly. A pending event can be cancelled so that 227it will not be raised. 228 229 230\item[\biptxtref{% 231cancel_after_event(+\pattern{EventId},~-\pattern{Cancelled})}% 232{cancel_after_event/2}{../bips/kernel/event/cancel_after_event-2.html}] 233This finds and cancels all pending after events with name \about{EventId} and 234returns the actually cancelled ones in a list. 235 236\item[\biptxtref{current_after_events(-\pattern{Events})}% 237{current_after_events/1}{../bips/kernel/event/current_after_events-1.html}] 238This returns a list of all pending after events. 239\end{description} 240\end{quote} 241 242The after event mechanism allows multiple events to make use of the timing 243mechanism independently of each other. The same event can be setup 244multiple times with multiple calls to \predspec{event_after/2} and 245\predspec{event_after_every/2}. The \predspec{cancel_after_event/2} 246predicate will cancel all instances of an event. 247 248By default, the after event feature uses the \notation{real} timer. The 249timer can be switched to the \notation{virtual} timer, in which case the 250elapsed time measured is user CPU time.\footnote{% 251 This is time that the CPU spends on executing user code, i.e., the {\eclipse} 252 program.} 253This setting is specified by the {\eclipse} environment flag 254\notation{after_event_timer} (see \predspec{get_flag/2}, 255\predspec{set_flag/2}). Note that if the 256timer is changed while some after event is still pending, these events 257will no longer be processed. The timer should therefore not be changed 258once after events are initiated. 259 260Currently, the \notation{virtual} timer is not available on the Windows 261platform. In addition, the users should not make use of these 262timers for their own purposes if they plan to use the after event 263mechanism. 264 265 266\subsection{Events and Waking} 267 268Using the suspension and event handling mechanisms together, a goal can be 269added to the resolvent and executed after a defined elapsed time. 270To achieve this, the goal is suspended and attached to a symbolic 271trigger, which is triggered by an afer-event handler. The goal behaves 272``logically'', in that if the execution backtracks pass the point in which 273the suspended goal is created, the goal will disappear from the resolvent 274as expected and thus not be executed. The event will still be raised, but 275there will not be a suspended goal to wake up. Note that if the execution 276finishes before the suspended goal is due to be woken up, it will also not 277enter the resolvent and will thus not be executed. 278 279The following is an example of waking a goal with a timed event. 280Once \verb+monitor(X)+ is called, the current value of X will be 281printed every second until the query finishes or is backtracked over: 282\begin{quote} 283\begin{verbatim} 284:- set_event_handler(monvar, trigger/1). 285 286monitor(Var) :- 287 suspend(m(Var), 3, trigger(monvar)), 288 event_after_every(monvar, 1). 289 290:- demon m/1. 291m(Var) :- writeln(Var). 292 293:- monitor(Var), <do_something>. 294\end{verbatim} 295\end{quote} 296Note the need to declare 297\predspec{m/1} as a demon: otherwise, once \predspec{m/1} is woken up once, it 298will 299disappear from the resolvent and the next \notation{monvar} event will not have 300a suspended \predspec{m/1} to wake up. 301Note also that it is necessary to connect the event machanism to 302the waking mechanism by setting the event handler to 303\bipref{trigger/1}{../bips/kernel/suspensions/trigger-1.html}. 304 305 306\subsection{Aborting an Execution with Events} 307 308Typically, event handlers would perform some action and then succeed, 309letting the interrupted exectuion continue unharmed. Event handlers for 310asynchronous events should never fail, because the failure will be inserted 311in a random place in the resolvent, and the effect will be unpredictable. 312It is however sometimes useful to allow an asynchronous event to abort 313an execution (via 314\bipref{throw/1}{../bips/kernel/control/throw-1.html}), e.g., 315to implement timeouts.\footnote{% 316 Since implementing reliable timeouts is a 317 nontrivial task, we recommend the use of 318 \bipref{lib(timeout)}{../bips/lib/timeout/index.html} for this purpose.} 319 320When dealing with events that occur asynchronously (in particular after-events), 321and event handlers that cause the execution to abort, it is often a problem 322that event handlers may be interrupted or preempted by other event handlers. 323This can be avoided by use of the event-defer mechanism. An event can be 324declared with the defer-property, which means that all further event handling 325is temporarily suppressed as soon as the handling of this event begins. 326In this case, the event handler is responsible for reenabling event handling 327explicitly before returning by calling 328\bipref{events_nodefer/0}{../bips/kernel/event/events_nodefer-0.html}. 329For instance: 330\begin{quote} 331\begin{verbatim} 332:- set_event_handler(my_event, defers(my_handler/0)). 333my_after_handler :- % event handling is deferred at this point 334 <deal with event>, 335 events_nodefer. % allow other events to be handled again 336\end{verbatim} 337\end{quote} 338In the presence of other event handlers which can cause aborts, this will 339protect the handler code from being preempted. 340 341 342%---------------------------------------------------------------------- 343\section{Errors} 344%---------------------------------------------------------------------- 345\index{errors} 346Error handling is one particular use of events. 347The main property of error events is that they have a culprit goal, 348i.e., the goal that detected or caused the error. 349The error handler obtains that goal as an argument. 350 351The errors that the system raises have numerical identifiers, 352as documented in appendix \ref{chaperrors}. 353User-defined errors have atomic names, they are the same as events. 354Whenever an error occurs, the {\eclipse} system identifies the type of error, 355and 356calls the appropriate handler. For each type of error, it is possible 357for the user to define a separate handler. This definition will replace 358the default error handling routine for that particular error---all other 359errors will still 360be handled by their respective 361handlers. 362It is of 363course possible to associate the same user defined error handler to more 364than one error type. 365 366When a goal is called and produces an error, execution of the goal 367is aborted and the appropriate error handler is invoked. 368This invocation of the error handler is seen as \emph{replacing} 369the invocation of the erroneous goal: 370\begin{itemize} 371\item if the error handler fails it has the same effect as if the 372erroneous goal failed; 373\item if the error handler succeeds, possibly binding some variables, 374the execution continues at the point behind the call of the erroneous goal; 375\item if the handler calls \bipref{throw/1}% 376{../bips/kernel/control/throw-1.html}, it has the same effect as if 377this was done by the erroneous goal itself. 378\end{itemize} 379For errors that are classified as warnings the second point is somewhat 380different: if the handler succeeds, the goal that raised the warning 381is allowed to continue execution. 382 383Apart from binding variables in the erroneous goal, error handlers can 384also leave backtrack points. However, if the error was raised by 385an external or a built-in that is implemented as an external, these 386choicepoints are discarded.\footnote{% 387 This is necessary because the compiler recognises simple predicates as 388 deterministic at compile time and so if a simple predicate were to cause the 389 invocation of a non-deterministic error handler, the generated code might no 390 longer be correct.} 391 392 393\subsection{Error Handlers} 394The predicate \bipref{set_event_handler/2}% 395{../bips/kernel/event/set_event_handler-2.html} is used to assign a procedure as 396an error handler. The call 397\begin{quote} 398\begin{verbatim} 399set_event_handler(ErrorId, PredSpec) 400\end{verbatim} 401\end{quote} 402sets the event handler for error type \about{ErrorId} to the procedure specified 403by \about{PredSpec}, which must be of the form \pattern{Name/Arity}. 404 405The corresponding predicate 406\bipref{get_event_handler/3}{../bips/kernel/event/get_event_handler-3.html} 407may be used to identify 408the current handler for a particular error. The call 409\begin{quote} 410\begin{verbatim} 411get_event_handler(ErrorId, PredSpec, HomeModule) 412\end{verbatim} 413\end{quote} 414will, provided \about{ErrorId} is a valid error identifier, unify 415\about{PredSpec} 416with the 417specification of the current handler for error \about{ErrorId} in the form 418\pattern{Name/Arity}, and \about{HomeModule} will be unified with the module 419where the 420error handler has been defined. Note that this error handler might not be 421visible from every module and therefore may not be callable. 422 423To re-install the system's error handler in case the user error handler is 424no longer needed, 425\bipref{reset_event_handler/1}% 426{../bips/kernel/event/reset_event_handler-1.html} 427should be used. 428\bipref{reset_error_handlers/0}% 429{../bips/kernel/event/reset_error_handlers-0.html} resets all error handlers to 430their default values. 431 432To enable the user to conveniently write predicates with error checking 433the built-ins 434\indextt{error/2} 435\indextt{error/3} 436\begin{quote} 437\begin{verbatim} 438error(ErrorId, Goal) 439error(ErrorId, Goal, Module) 440\end{verbatim} 441\end{quote} 442are provided to raise the error \about{ErrorId} (an error number or a name atom) 443with the culprit \about{Goal}. 444Inside tool procedures it is usually necessary to use 445\bipref{error/3}{../bips/kernel/event/error-3.html} 446in order to pass the caller module to the error handler. 447Typical error checking code looks like this 448\begin{quote} 449\begin{verbatim} 450increment(X, X1) :- 451 ( integer(X) -> 452 X1 is X + 1 453 ; 454 error(5, increment(X, X1)) 455 ). 456\end{verbatim} 457\end{quote} 458 459The predicate 460\bipref{current_error/1}{../bips/kernel/event/current_error-1.html} 461can be used to yield all valid error numbers, a valid error is that one 462to which an error message and an error handler are associated. 463The predicate \bipref{error_id/2}{../bips/kernel/event/error_id-2.html} 464gives the corresponding error message to the specified error number. 465To ease the search for the appropriate error number, 466the library \notation{util} contains the predicate 467\indextt{list_error/3} 468\begin{quote} 469\begin{verbatim} 470util:list_error(Text, N, Message) 471\end{verbatim} 472\end{quote} 473which returns on backtracking all the errors whose error message 474contains the string \about{Text}. 475 476The ability to define any Prolog predicate as the error handler permits a 477great deal of flexibility in error handling. However, this flexibility 478should be used with caution. The action of an error handler could have side 479effects altering the correctness of a program; indeed it could be responsible 480for further errors being introduced. One particular area of danger is in the 481use of input and output streams by error handlers. 482%For example: 483%a particular error handler may interact with 484%the user at the terminal, to explain the nature of the error and ask for 485%directions regarding what action should be taken. Care should be taken in 486%such a case 487%to ensure that the error handler does not affect the input to the program. 488%If it does, since program execution continues normally after exit of the error 489%handler, any input consumed by the error handler is lost. 490 491 492\subsection{Arguments of Error Handlers} 493An error handler has four optional arguments: 494\begin{enumerate} 495\item The first argument is the number or atom that identifies the error. 496\item The second argument is 497the culprit (a structure corresponding to the call which caused the 498error). 499For instance, if, 500say, a type error occurs upon calling the second goal of the procedure 501\notation{p(2, Z)}: 502\begin{quote} 503\begin{verbatim} 504 p(X, Y) :- a(X), b(X, Y), c(Y). 505\end{verbatim} 506\end{quote} 507the structure given to the error handler is \notation{b(2, Y)}. 508Note that the handler could bind Y which would have the same effect 509as if \predspec{b/2} had done the binding. 510 511\item The third argument is only defined for a subset of the existing errors. 512If the error occurred inside a tool body, it holds the caller module, 513otherwise it is identical to the fourth argument.\footnote{% 514 Note that some events are not errors but are used for different purposes. 515 In those cases the second and third argument are sometimes used 516 differently. See Appendix \ref{chaperrors} for details.} 517 518\item The fourth argument is the lookup module for the culprit goal. This 519is needed for example when the handler wants to call the culprit reliably, 520using a qualified call via \txtbipref{:/2}{(:)/2}{../bips/kernel/control/N-2.html}. 521\end{enumerate} 522 523The error handler is free to ignore some of these arguments, 524i.e., it can have any arity from 0 to 4. 525The first argument is provided for the case that the same procedure serves 526as the handler for several error types---then it can distinguish 527which is the actual error type. 528\index{errors!handlers} 529An error handler is just an ordinary Prolog procedure and thus within 530it a call may be made to any other procedure, or any built in predicate; 531this in particular means that a call to 532\bipref{throw/1}{../bips/kernel/control/throw-1.html} may be 533made (see the section on the 534\bipref{catch/3}{../bips/kernel/control/catch-3.html} 535predicate).\index{blocks} This will work 536``through'' the call to the error handler, and so an exit may be made from 537within the handler out of the current catch-block (i.e., back to the corresponding 538call of the \bipref{catch/3}{../bips/kernel/control/catch-3.html} predicate). 539Specifying the predicates \bipref{true/0}{../bips/kernel/control/true-0.html} or 540\bipref{fail/0}{../bips/kernel/control/fail-0.html} as error handlers 541will make the erroneous predicate succeed (without binding 542any further variables) or fail respectively. 543 544The following two templates are the most common for error handlers. 545The first simply prints an error message and aborts: 546\begin{quote} 547\begin{verbatim} 548my_error_handler(ErrorId, Goal, ContextModule) :- 549 printf(error, "Error %w in %w in module %w%n", 550 [ErrorId,Goal,ContextModule]), 551 abort. 552\end{verbatim} 553\end{quote} 554The following handler tries to repair the error and call the goal again: 555\begin{quote} 556\begin{verbatim} 557my_error_repair_handler(ErrorId, Goal, ContextModule, LookupModule) :- 558 % repair the error 559 ... some code to repair the cause for the error ... 560 % try call the erroneous goal again 561 LookupModule : Goal @ ContextModule. 562\end{verbatim} 563\end{quote} 564 565 566\subsection{User Defined Errors} 567\label{user-errors} 568\index{errors!user defined} 569The following example illustrates the use of a user-defined error. 570We declare a handler for the event \notation{Invalid command} and 571raise the new error in the application code. 572\begin{quote} 573\begin{verbatim} 574% Command error handler - output invalid command, sound bell and abort 575command_error_handler(_, Command) :- 576 printf("\007\nInvalid command: %w\n", [Command]), 577 abort. 578 579% Activate the handler 580:- set_event_handler('Invalid command', command_error_handler/2). 581 582% top command processing loop 583go :- 584 writeln("Enter command."), 585 read(Command), 586 ( valid_command(Command)-> 587 process_command(Command), 588 go 589 ; 590 error('Invalid command',Command) % Call the error handler 591 ). 592 593% Some valid commands 594valid_command(start). 595valid_command(stop). 596\end{verbatim} 597\end{quote} 598 599 600 601%\subsection{Using Tools in Error Handlers} 602%\index{errors!toolhandlers} 603%\label{toolhandlers} 604%If an error occurs in a tool predicate and the error handler 605%has to fix the problem and continue the execution, 606%it usually has to call directly the system tools 607%using its module argument. 608%As an example, here is the script of constructing the error handler 609%for the error `procedure already dynamic'. 610%This error occurs if the argument of the 611%\bipref{dynamic/1}{../bips/kernel/dynamic/dynamic-1.html} 612%predicate is already dynamic. 613%The intended action is to erase the procedure so that 614%when a file with this declaration is being compiled, 615%the dynamic clauses are not added but they replace 616%the existing procedure, which is what one wants 617%during the debugging phase. 618%We want to use the predicate 619%\bipref{retract_all/1}{../bips/kernel/obsolete/retract_all-1.html} to remove 620%all existing clauses, however we have to use its body procedure 621%(it is a tool) to be able to access a predicate in an explicit module. 622% 623%\pagebreak[1] 624%\begin{quote} 625%\begin{verbatim} 626%[eclipse 1]: use_module(library(util)), 627% list_error("dynamic", N, M). 628%N = 63 629%M = "procedure not dynamic" More? (;) 630%N = 64 631%M = "procedure already dynamic" More? (;) 632%yes. 633% % find the tool body of retract_all/1 634% 635%[eclipse 2]: tool_body(retract_all/1, P, M). 636%P = retract_all_body / 2 637%M = sepia_kernel 638%yes. 639% % to be able to use the body procedure, we must import it 640% 641%[eclipse 3]: import retract_all_body/2 from sepia_kernel. 642%yes. 643% % Now we can define the error handling procedure 644% 645%[eclipse 4]: [user]. 646% dynamic_handler(_, dynamic(Name/Arity), Module) :- 647% !, 648% functor(F, Name, Arity), 649% retract_all_body(F, Module). 650% dynamic_handler(N, OtherGoal, Module) :- 651% error(default(N), OtherGoal, Module). 652% user compiled 348 bytes in 0.00 seconds 653% 654%yes. 655% % and set it as the error handler 656% 657%[eclipse 5]: set_event_handler(64, dynamic_handler/3). 658%yes. 659% % Finally, we check whether it works as desired 660% 661%[eclipse 6]: [user]. 662% :- dynamic p/1. 663% p(a). p(b). 664% :- listing p/1. 665%p(a). 666%p(b). 667% :- dynamic p/1. 668% p(1). 669% :- listing p/1. 670%p(1). 671% % the previous clauses are indeed erased 672% 673% user compiled 0 bytes in 0.07 seconds 674%\end{verbatim} 675%\end{quote} 676%\vspace*{\fill} 677 678 679%---------------------------------------------------------------------- 680\section{Interrupts\label{sectinterrupts}} 681%---------------------------------------------------------------------- 682 683\index{interrupts} 684Operating systems such as Unix provide a notion of asynchronous interrupts 685or signals. In a standalone {\eclipse} system, the signals can be handled by 686defining interrupt handlers for them. In fact, a set of 687default handlers is already predefined in this case. 688 689In an embedded {\eclipse}, signals are usually handled by the host 690application, and it is recommended to use the event mechanism described above 691(the \notation{ec_post_event()} library function) to communicate between the 692host 693application and the {\eclipse} code. 694However, even in this setting, {\eclipse} can also handle signals directly, 695provided the programmer sets up a corresponding interrupt handler. 696 697\vfill % <<<<<<<<<<<<<<<<<<<<<<<<<< 698 699\subsection{Interrupt Identifiers} 700Interrupts are identified either by their signal number (Unix) or 701by a name which is derived from the name the signal has in the operating 702system. Most built-ins understand both identifiers. It is usually 703more portable to use the symbolic name. 704The built-in 705\bipref{current_interrupt/2}{../bips/kernel/event/current_interrupt-2.html} is 706provided to check and/or 707generate the valid interrupt numbers and their mnemonic names. 708 709 710\subsection{Asynchronous handling} 711 712When an interrupt happens, the {\eclipse} system 713calls an interrupt handling routine in a manner very similar to 714the case of event handling. The only argument to the handler is 715the interrupt number. 716Just as event handlers may be user defined, so it is possible to define 717interrupt handlers. The goal 718\begin{quote} 719\preddef{set_interrupt_handler(\pattern{N},~\pattern{PredSpec})}% 720\indextt{set_interrupt_handler/2} 721\end{quote} 722assigns the procedure specified by \about{PredSpec} as the interrupt handler for 723the interrupt identified by \about{N} (a number or a name). 724Some interrupts cannot be caught by the user (e.g., the \about{kill} signal), 725trying to establish a handler for them yields an error message. Note that 726\about{PredSpec} should be one of the predefined handlers. The use of general 727user defined predicates is deprecated because of portability considerations. 728 729To test interrupt handlers, the built-in 730\bipref{kill/2}{../bips/kernel/opsys/kill-2.html} may be used to send 731a signal to the own process. 732 733The predicate 734\bipref{get_interrupt_handler/3}% 735{../bips/kernel/event/get_interrupt_handler-3.html} 736may be used to find the 737current interrupt handler for an interrupt N, in the same manner as 738\predspec{get_event_handler}: 739\begin{quote} 740\preddef{% 741get_interrupt_handler(\pattern{N},~\pattern{PredSpec},~\pattern{HomeModule})}% 742\indextt{get_interrupt_handler/3} 743\end{quote} 744 745An interrupt handler has one optional argument, which is the interrupt 746number. 747There is no argument corresponding to the error culprit, since 748the interrupt has no relation to the currently executed predicate. 749A handler may be defined which takes no argument (such 750as when the handler is defined for only one interrupt type). 751If the handler has one argument, the identifier of the interrupt is passed 752to the handler when it is called. 753 754The following is the list of predefined interrupt handlers: 755\begin{quote} 756\begin{description} 757\item[default/0]\indextt{default/0}\mbox{}\\ 758performs the standard UNIX handling of the specified interrupt (signal). 759 Setting this handler is equivalent to calling \notation{signal(N, SIG_DFL)} 760 on the C level. 761 Thus e.g., specifying 762 \begin{quote} 763 \begin{verbatim} 764 ?- set_interrupt_handler(int, default/0). 765 \end{verbatim} 766 \end{quote} 767 will exit the {\eclipse} system when \verb:^C: is pressed. 768 769\item[true/0]\indextt{true/0}\mbox{}\\ 770 This is equivalent to calling \notation{signal(N, SIG_IGN)} on the C level, 771 i.e., the interrupt is ignored. 772 773\item[throw/1]\indextt{throw/1}\mbox{}\\ 774 Invoke \predspec{throw/1} with the interupt's symbolic name. 775 776\item[abort/0]\indextt{abort/0}\mbox{}\\ 777 Invoke \notation{throw(abort)}. 778 779\item[halt/0]\indextt{halt/0}\mbox{}\\ 780 Terminate the {\eclipse} process. 781 782\item[internal/0]\indextt{internal/0}\mbox{}\\ 783 Used by {\eclipse} to implement internal functionality like the 784 profiler. This is not intended to be used by the user. 785 786\item[event/1]\indextt{event/1}\mbox{}\\ 787 The signal is handled by posting a (synchronous) event. The event 788 name is the symbolic name of the interrupt. 789\end{description} 790\end{quote} 791Apart from these special cases, all other arguments will 792result in the specified predicate being called when the appropriate 793interrupt occurs. This general asynchronous interrupt handling 794is not supported on all hardware/platforms, 795neither in an embedded {\eclipse} (including the 796\index{interrupts!tkeclipse} \tkeclipse{} development environment), 797and is therefore deprecated. 798 799 800%{\eclipse} provides special support for debugging interrupt handlers. 801%They can be debugged independently of the interrupted program. 802%To achieve this, every interrupt number has a flag that can take one of the 803%values {\tt debug}, {\tt trace}, {\tt nodebug} or {\tt notrace} 804%(the latter two are synonyms). 805%It specifies if the corresponding interrupt handlers are executed 806%with the debugger in leap mode, in creep mode or without debugger respectively. 807%The flags can be set with the built-in 808%\bipref{set_interrupt_flag/2}{../bips/kernel/event/set_interrupt_flag-2.html} 809%and queried with 810%\bipref{get_interrupt_flag/2}{../bips/kernel/event/get_interrupt_flag-2.html}. 811% 812%The remarks about care in the use of error handlers, especially in the 813%matter of how they affect input and output, are equally applicable to 814%interrupt handlers. 815 816%\section{The block/3 Predicate} 817%\index{blocks} 818%\label{blocks} 819%Another mechanism provided by {\eclipse} which may be used to provide error 820%handling is the one proposed by the BSI and ISO standardisation committees. 821%Is is called ``blocks'' in the standardisation context, 822%but also known as ``Catch and Throw'' in some other systems. There are 823%two predicates involved here: 824%\begin{quote} 825%\begin{verbatim} 826%block(Goal, Tag, Recovery) 827%\end{verbatim} 828%\begin{verbatim} 829%exit_block(Tag) 830%\end{verbatim} 831%\end{quote} 832%\index{block/3} 833%\index{exit_block/1} 834%{\it Goal} and {\it Recovery} must be callable Prolog terms, 835%{\it Tag} must be a constant or a free variable. 836%{\bf block(Goal,\ Tag,\ Recovery)} is very similar to {\bf call(Goal)}, but it 837%also creates a label to which the program can return immediately by a suitable 838%call of \bipref{exit_block/1}{../bips/kernel/control/exit_block-1.html}. 839% 840%{\bf block(Goal, Tag, Recovery)} first calls {\it Goal}, and if this succeeds 841%then \bipref{block/3}{../bips/kernel/control/block-3.html} succeeds. 842%If {\it Goal} fails then so does the call of 843%\bipref{block/3}{../bips/kernel/control/block-3.html}. 844%If, however, during the execution of 845%{\it Goal} there is a call of {\bf exit_block(TagExit)} 846%such that {\it TagExit} unifies with the {\it Tag} of a 847%\bipref{block/3}{../bips/kernel/control/block-3.html} 848%invocation, 849%then \bipref{block/3}{../bips/kernel/control/block-3.html} calls the goal {\it 850%Recovery}, and 851%succeeds or fails according to whether {\it Recovery} succeeds or fails. 852% 853%If {\it Tag} does not unify with {\it TagExit}, the system continues 854%looking for an earlier 855%invocation of \bipref{block/3}{../bips/kernel/control/block-3.html}. (An error 856%is raised if {\it TagExit} does 857%not unify with a {\it Tag} of any uncompleted call of 858%\bipref{block/3}{../bips/kernel/control/block-3.html}.) 859% 860%One of the most likely uses for the block 861%mechanism is exception handling. 862%Since {\eclipse} provides the user with a sophisticated exception 863%handling via user-definable handlers, the likely use of the block 864%mechanism is more restricted than in other systems. 865%Note that in contrast to the BSI proposal, the tag 866%of the block cannot be a compound term. 867%This restriction has been introduced because the semantics of 868%having non-ground compound terms is not clearly defined. 869%This does not mean that {\eclipse} is less powerful, though. 870%If more information is to be passed from 871%\bipref{exit_block/1}{../bips/kernel/control/exit_block-1.html} to 872%\bipref{block/3}{../bips/kernel/control/block-3.html}, 873%communication using global variables can be used instead. 874% 875 876%HEVEA\cutend 877