Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Programming Concepts Manual


Previous Contents Index

6.4.1 Setting Timer Requests with SYS$SETIMR

Timer requests made with the Set Timer (SYS$SETIMR) system service are queued; that is, they are ordered for processing according to their expiration times. The quota for timer queue entries (TQELM quota) controls the number of entries a process can have pending in this timer queue.

When you call the SYS$SETIMR system service, you can specify either an absolute time or a delta time value. Depending on how you want the request processed, you can specify either or both of the following:

Optionally, you can specify a request identification for the timer request. You can use this identification to cancel the request, if necessary. The request identification is also passed as the AST parameter to the AST service routine, if one is specified, so that the AST service routine can identify the timer request.

Example 6-2 and Example 6-3 show timer requests using event flags and ASTs, respectively. Event flags, event flag services, and ASTs are described in more detail in Chapter 5.

Example 6-2 Setting an Event Flag

#include <stdio.h> 
#include <ssdef.h> 
#include <descrip.h> 
 
/* Buffer to receive binary time */ 
struct { 
        unsigned int buff1, buff2; 
}b30sec; 
 
main() { 
        
        unsigned int efn = 4,status; 
        $DESCRIPTOR(a30sec,"0 00:00:30.00"); 
 
/* Convert time to binary format */ 
        status = SYS$BINTIM( &a30sec, /* timbuf - ASCII time */ 
                             &b30sec);/* timadr - binary time */ 
        if ((status & 1) != 1) 
                LIB$SIGNAL( status ); 
        else 
                printf("Converting ASCII to binary time...\n"); 
 
/* Set timer to wait */ 
        status = SYS$SETIMR( efn, /* efn - event flag */ 
                          &b30sec,/* daytim - binary time */ 
                          0,      /* astadr - AST routine */ 
                          0,      /* reqidt - timer request */ 
                          0);     /* flags */        (1)
        if ((status & 1) != 1) 
                LIB$SIGNAL( status ); 
        else 
                printf("Request event flag be set in 30 seconds...\n"); 
 
/* Wait 30 seconds */ 
        status = SYS$WAITFR( efn );                         (2)
        if ((status & 1) != 1) 
                LIB$SIGNAL( status ); 
        else 
                printf("Timer expires...\n"); 
 
} 

  1. The call to SYS$SETIMR requests that event flag 4 be set in 30 seconds (expressed in the quadword B30SEC).
  2. The Wait for Single Event Flag (SYS$WAITFR) system service places the process in a wait state until the event flag is set. When the timer expires, the flag is set and the process continues execution.

Example 6-3 Specifying an AST Service Routine

#include <stdio.h> 
#include <descrip.h> 
 
#define NOON 12 
 
struct { 
        unsigned int buff1, buff2; 
}bnoon; 
 
/* Define the AST routine */ 
 
void astserv( int ); 
 
main() { 
        unsigned int status, reqidt=12; 
        $DESCRIPTOR(anoon,"-- 12:00:00.00"); 
 
/* Convert ASCII time to binary */ 
        status = SYS$BINTIM(&anoon,     /* timbuf - ASCII time */   (1)
                            &bnoon);    /* timadr - binary time buffer */ 
        if((status & 1) != 1) 
                LIB$SIGNAL( status ); 
        else 
                printf("Converting ASCII to binary...\n"); 
 
/* Set timer */ 
        status = SYS$SETIMR(0,                  /* efn - event flag */ (2)
                            &bnoon,             /* daytim - timer expiration */ 
                            &astserv,           /* astadr - AST routine */ 
                            reqidt,             /* reqidt - timer request id */ 
                            0);                 /* cvtflg - conversion flags */ 
        if((status & 1) != 1) 
                LIB$SIGNAL( status ); 
        else 
                printf("Setting timer expiration...\n"); 
 
        status = SYS$HIBER(); 
 
} 
 
void astserv( int astprm ) {                                     (3)
 
/* Do something if it's a "noon" request */ 
        if (astprm == NOON) 
                printf("This is a noon AST request\n"); 
        else 
                printf("Handling some other request\n"); 
 
        status = SYS$SCHDWK(0, /* pidadr - process id */ 
                        0);/* prcnam - process name */ 
 
        return; 
} 
 

  1. The call to SYS$BINTIM converts the ASCII string representing 12:00 noon to format. The value returned in BNOON is used as input to the SYS$SETIMR system service.
  2. The AST routine specified in the SYS$SETIMR request will be called when the timer expires, at 12:00 noon. The reqidt argument identifies the timer request. (This argument is passed as the AST parameter and is stored at offset 4 in the argument list. See Chapter 5.) The process continues execution; when the timer expires, it is interrupted by the delivery of the AST. Note that if the current time of day is past noon, the timer expires immediately.
  3. This AST service routine checks the parameter passed by the reqidt argument to determine whether it must service the 12:00 noon timer request or another type of request (identified by a different reqidt value). When the AST service routine completes, the process continues execution at the point of interruption.

6.4.2 Canceling a Timer Request with SYS$CANTIM

The Cancel Timer Request (SYS$CANTIM) system service cancels timer requests that have not been processed. The SYS$CANTIM system service removes the entries from the timer queue. Cancellation is based on the request identification given in the timer request. For example, to cancel the request illustrated in Example 6-3, you would use the following call to SYS$CANTIM:


        unsigned int status, reqidt=12; 
   .
   .
   .
        status = SYS$CANTIM( reqidt, 0); 

If you assign the same identification to more than one timer request, all requests with that identification are canceled. If you do not specify the reqidt argument, all your requests are canceled.

6.4.3 Scheduling Wakeups with SYS$WAKE

Example 6-2 shows a process placing itself in a wait state using the SYS$SETIMR and SYS$WAITFR services. A process can also make itself inactive by hibernating. A process hibernates by issuing the Hibernate (SYS$HIBER) system service. Hibernation is reversed by a wakeup request, which can be put into effect immediately with the SYS$WAKE system service or scheduled with the Schedule Wakeup (SYS$SCHDWK) system service. For more information about the SYS$HIBER and SYS$WAKE system services, see Chapter 3.

The following example shows a process scheduling a wakeup for itself prior to hibernating:


#include <stdio.h> 
#include <descrip.h> 
 
struct { 
        unsigned int buff1, buff2; 
}btensec; 
 
main() { 
 
        unsigned int status; 
        $DESCRIPTOR(atensec,"0 00:00:10.00"); 
 
/* Convert time */ 
        status = SYS$BINTIM(&atensec, /* timbuf - ASCII time */ 
                            &btensec);/* timadr - binary time */ 
        if ((status & 1 ) != 1) 
                LIB$SIGNAL( status ); 
 
/* Schedule wakeup */ 
        status = SYS$SCHDWK(0, /* pidadr - process id */ 
                            0, /* prcnam - process name */ 
                            &btensec, /* daytim - wake up time */ 
                            0); /* reptim - repeat interval */ 
        if ((status & 1 ) != 1) 
                LIB$SIGNAL( status ); 
 
/* Sleep ten seconds */ 
        status = SYS$HIBER(); 
        if ((status & 1 ) != 1) 
                LIB$SIGNAL( status ); 
} 

Note that a suitably privileged process can wake or schedule a wakeup request for another process; thus, cooperating processes can synchronize activity using hibernation and scheduled wakeups. Moreover, when you use the SYS$SCHDWK system service in a program, you can specify that the wakeup request be repeated at fixed time intervals. See Chapter 3 for more information on hibernation and wakeup.

6.4.4 Canceling a Scheduled Wakeup with SYS$CANWAK

You can cancel scheduled wakeup requests that are pending but have not yet been processed with the Cancel Wakeup (SYS$CANWAK) system service. This service cancels a wakeup request for a specific kernel thread, if a process ID is specified. If a process name is specified, then the initial thread's wakeup request is canceled.

The following example shows the scheduling of wakeup requests for the process CYGNUS and the subsequent cancellation of the wakeups. The SYS$SCHDWK system service in this example specifies a delta time of 1 minute and an interval time of 1 minute; the wakeup is repeated every minute until the requests are canceled.


#include <stdio.h> 
#include <descrip.h> 
 
/* Buffer to hold one minute */ 
 
struct { 
        unsigned int buff1, buff2; 
}interval; 
 
main() { 
 
        unsigned int status; 
        $DESCRIPTOR(one_min,"0 00:01:00.00");  /* One minute delta */ 
        $DESCRIPTOR(cygnus, "CYGNUS");          /* Process name */ 
 
/* Convert time to binary */ 
        status = SYS$BINTIM(&one_min,   /* timbuf - ASCII delta time */ 
                           &interval);  /* timadr - Buffer to hold binary time */ 
        if((status & 1) != 1) 
                LIB$SIGNAL( status ); 
        else 
                printf("Converting time to binary format...\n"); 
 
/* Schedule wakeup */   
        status = SYS$SCHDWK(0,          /* pidadr - process id */ 
                            &cygnus,    /* prcnam - process name */ 
                            &interval,  /* daytim - time to be awakened */ 
                            &interval); /* reptim - repeat interval */ 
        if((status & 1) != 1) 
                LIB$SIGNAL( status ); 
        } 
        else 
                printf("Scheduling wakeup...\n"); 
 
        /* Cancel wakeups */ 
        status = SYS$CANWAK(0,                  /* pidadr - process id */ 
                            &cygnus);           /* prcnam - process name */ 
 
} 

6.4.5 Executing a Program at Timed Intervals

To execute a program at timed intervals, you can use either the LIB$SPAWN routine or the SYS$CREPRC system service. With LIB$SPAWN, you can create a subprocess that executes a command procedure containing three commands: the DCL command WAIT, the command that invokes the desired program, and a GOTO command that directs control back to the WAIT command. To prevent the parent process from remaining in hibernation until the subprocess executes, you should execute the subprocess concurrently; that is, you should specify CLI$M_NOWAIT.

For more information about using LIB$SPAWN and SYS$CREPRC, see Chapter 3.

6.5 Routines Used for Timer Statistics

This section presents information about the LIB$INIT_TIMER, LIB$SHOW_TIMER, LIB$STAT_TIMER, and LIB$FREE_TIMER routines. By calling these run-time library routines, you can collect the following timer statistics from the system:

Following are descriptions of each routine:

You must invoke LIB$INIT_TIMER to allocate storage for the timer. You should invoke LIB$FREE_TIMER before you exit from your program unit. In between, you can invoke LIB$SHOW_TIMER or LIB$STAT_TIMER, or both, as often as you want. Example 6-4 invokes LIB$SHOW_TIMER and uses a user-written subprogram either to display the statistics or to write them to a file.

Example 6-4 Displaying and Writing Timer Statistics

   .
   .
   .
! Timer arguments 
INTEGER*4 TIMER_ADDR, 
2         TIMER_DATA, 
2         TIMER_ROUTINE 
EXTERNAL  TIMER_ROUTINE 
! Declare library procedures as functions 
INTEGER*4 LIB$INIT_TIMER, 
2         LIB$SHOW_TIMER 
EXTERNAL  LIB$INIT_TIMER, 
2         LIB$SHOW_TIMER 
! Work variables 
CHARACTER*5 REQUEST 
INTEGER*4   STATUS 
! User request - either WRITE or FILE 
INTEGER*4   WRITE, 
2           FILE 
PARAMETER  (WRITE = 1, 
2           FILE = 2) 
! Get user request 
WRITE (UNIT=*, FMT='($,A)') ' Request: ' 
ACCEPT *, REQUEST 
IF (REQUEST .EQ. 'WRITE') TIMER_DATA = WRITE 
IF (REQUEST .EQ. 'FILE') TIMER_DATA = FILE 
! Set timer 
STATUS = LIB$INIT_TIMER (TIMER_ADDR) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS)) 
   .
   .
   .
! Get statistics 
STATUS = LIB$SHOW_TIMER (TIMER_ADDR,, 
2                        TIMER_ROUTINE, 
2                        TIMER_DATA) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS)) 
   .
   .
   .
! Free timer 
STATUS = LIB$FREE_TIMER (TIMER_ADDR) 
IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS)) 
   .
   .
   .
INTEGER FUNCTION TIMER_ROUTINE (STATS, 
2                               TIMER_DATA) 
! Dummy arguments 
CHARACTER*(*) STATS 
INTEGER TIMER_DATA 
! Logical unit number for file 
INTEGER STATS_FILE 
! User request 
INTEGER WRITE, 
2       FILE 
PARAMETER (WRITE = 1, 
2          FILE = 2) 
! Return code 
INTEGER SUCCESS, 
2       FAILURE 
PARAMETER (SUCCESS = 1, 
2          FAILURE = 0) 
! Set return status to success 
TIMER_ROUTINE = SUCCESS 
! Write statistics or file them in STATS.DAT 
IF (TIMER_DATA .EQ. WRITE) THEN 
  TYPE *, STATS 
ELSE IF (TIMER_DATA .EQ. FILE) THEN 
  CALL LIB$GET_LUN (STATS_FILE) 
  OPEN (UNIT=STATS_FILE, 
2       FILE='STATS.DAT') 
  WRITE (UNIT=STATS_FILE, 
2        FMT='(A)') STATS 
ELSE 
  TIMER_ROUTINE = FAILURE 
END IF 
END 

You can use the SYS$GETSYI system service to obtain more detailed system information about boot time, the cluster, processor type, emulated instructions, nodes, paging files, swapping files, and hardware and software versions. With SYS$GETQUI and LIB$GETQUI, you can obtain queue information.

6.6 Date/Time Formatting Routines

This section provides information about using date/time formatting routines that allow you to specify input and output formats other than the standard operating system format for dates and times. These include international formats with appropriate language spellings for days and months.

If the desired language is English (the default language) and the desired format is the standard operating system format, then initialization of logical names is not required in order to use the date/time input and output routines. However, if the desired language and format are not the defaults, the system manager (or any user having CMEXEC, SYSNAM, and SYSPRV privileges) must initialize the required logical names.

6.6.1 Performing Date/Time Logical Initialization

Note

You must complete the initialization steps outlined in this section before you can use any of the date/time input and output routines with languages and formats other than the defaults.

As an alternative to the standard operating system format, the command procedure SYS$MANAGER:LIB$DT_STARTUP.COM defines several output formats for dates and times. This command procedure must be executed by the system manager prior to using any of the run-time library date/time routines for input or output formats other than the default. Ideally, this command procedure should be executed from a site-specific startup procedure.

In addition to defining the date/time formats, the LIB$DT_STARTUP.COM command procedure also defines spellings for date and time elements in languages other than English. If different language spellings are required, the system manager must define the logical name SYS$LANGUAGES before invoking LIB$DT_STARTUP.COM. The translation of SYS$LANGUAGES is then used to select which languages are defined.

Table 6-5 shows the available languages and their logical names.

Table 6-5 Available Languages for Date/Time Formatting
Language Logical Name
Austrian AUSTRIAN
Danish DANISH
Dutch DUTCH
Finnish FINNISH
French FRENCH
French Canadian CANADIAN
German GERMAN
Hebrew HEBREW
Italian ITALIAN
Norwegian NORWEGIAN
Portuguese PORTUGUESE
Spanish SPANISH
Swedish SWEDISH
Swiss French SWISS_FRENCH
Swiss German SWISS_GERMAN

For example, if the system manager wants the spellings for French, German, and Italian languages to be defined, he or she must define SYS$LANGUAGES as shown, prior to invoking LIB$DT_STARTUP.COM:


$ DEFINE SYS$LANGUAGES FRENCH, GERMAN, ITALIAN

If the user requires an additional language, for example FINNISH, then the system manager must add FINNISH to the definition of SYS$LANGUAGES and reexecute the command procedure.

Date/Time Manipulation Option

The Date/Time Manipulation option provides date/time spelling support for four new languages. Users or application programmers can select the desired language by defining the logical name SYS$LANGUAGES. The new languages and their equivalent names are as follows:
Language Equivalent Name
Chinese (simplified character) Hanzi
Chinese (traditional character) Hanyu
Korean Hangul
Thai Thai

Defining Date/Time Spelling

To define the spelling for Hanzi and Hanyu, define SYS$LANGUAGES as shown below, prior to invoking LIB$DT_STARTUP.COM:


$ DEFINE SYS$LANGUAGES HANZI, HANYU 
$ @SYS$MANAGER:LIB$DT_STARTUP 

Predefined Output Formats

Figure 6-1 lists the new predefined date format logical names in the first column, their formats in the second column, and examples of the output generated using these formats in the third column.

Figure 6-1 Predefined Output Date Formats


Note

LIB$DATE_FORMAT_042 and LIB$DATE_FORMAT_043 support the DEC Hanzi coded character set.

LIB$DATE_FORMAT_044 and LIB$DATE_FORMAT_045 support the DEC Hanyu coded character set.

LIB$DATE_FORMAT_046 and LIB$DATE_FORMAT_047 support the DEC Hangul coded character set.

Figure 6-2 lists the new predefined time format logical names in the first column, their formats in the second column, and examples of the output generated using these formats in the third column.

Figure 6-2 Predefined Output Time Formats


Note

LIB$TIME_FORMAT_021 supports the DEC Hanzi coded character set.

LIB$TIME_FORMAT_022 supports the DEC Hanyu coded character set.

LIB$TIME_FORMAT_023 supports the DEC Hangul coded character set.

Thus, to select a particular format for a date or time, or both, you can define the LIB$DT_FORMAT logical name using the following logicals:


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
5841PRO_016.HTML