?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Statistics Facility: System Routing Control Manager' ??
MODULE sfm$sys_routing_control_manager;

{  PURPOSE:
{   This module contains the procedures that are used to create and manage the
{   system routing control table.
{
{  DESIGN:
{
{   The system routing control table controls the logging of statistics for the
{   system.
{
{   The routing control for a given statistic is found by calculating an index
{   into the table (statistic code MOD size of the table) and chaining down the
{   linked list of routing control entries.
{
{   Routing controls are added to the chain in last in first out order.
{
{   The size of the routing control table has been chosen to provide an average
{   chain length of 1 when all currently known statistics are activated.
{
{   Updates of the system routing control table are interlocked by using
{   signature locks.

?? NEWTITLE := 'Global Declarations Referenced by This Module.', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc avc$accounting_statistics
*copyc cml$dvs_usage_data
*copyc jml$user_id
*copyc sfe$statistics_not_available
*copyc sft$audit_statistic_code
*copyc sft$binary_logset
*copyc sft$routing_control
*copyc sft$routing_control_table
*copyc sft$statistic_code
?? POP ??
*copyc avp$security_option_active
*copyc osp$append_status_parameter
*copyc osp$clear_mainframe_sig_lock
*copyc osp$initialize_sig_lock
*copyc osp$set_mainframe_sig_lock
*copyc osp$set_status_abnormal
*copyc sfp$add_audit_control
*copyc sfp$add_routing_control
*copyc sfp$delete_audit_control
*copyc sfp$delete_routing_control
*copyc sfp$lock_routing_control
*copyc osv$mainframe_pageable_heap
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module.', EJECT ??

{ The system routing control table controls which statistics are emitted to which logs for the system.

  VAR
    sfv$sys_routing_control_table: [XDCL, #GATE, STATIC, oss$mainframe_pageable] sft$routing_control_table
           := NIL;

{ The system routing control lock controls access to the system routing control table.

  VAR
    sfv$system_routing_control_lock: [XDCL, #GATE, STATIC, oss$mainframe_pageable] ost$signature_lock;

{ This variable indicates whether open_file statistics are activated for the system.

  VAR
    sfv$emit_sys_open_statistics: [XDCL, #GATE, STATIC, oss$mainframe_pageable] boolean := FALSE;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] sfp$add_system_audit_control', EJECT ??
*copyc sfh$add_system_audit_control

  PROCEDURE [XDCL, #GATE] sfp$add_system_audit_control
    (    operation_set: sft$audited_operation_set;
         selection_criteria: sft$audit_selection_criteria;
         lock: boolean;
     VAR status: ost$status);

    status.normal := TRUE;

{ Make sure the system routing control table has been initialized.

    IF sfv$sys_routing_control_table = NIL THEN
      osp$set_status_abnormal ('SF', sfe$statistics_not_available, 'System', status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'sfp$add_system_audit_control', status);
      RETURN;
    IFEND;

{ Interlock the system routing control table.

    osp$set_mainframe_sig_lock (sfv$system_routing_control_lock);

{ Add the specified audit control information to the routing control table.

    sfp$add_audit_control (sfv$sys_routing_control_table, operation_set, selection_criteria, lock,
          osv$mainframe_pageable_heap);

{ Clear the interlock.

    osp$clear_mainframe_sig_lock (sfv$system_routing_control_lock);

  PROCEND sfp$add_system_audit_control;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] sfp$add_system_routing_control', EJECT ??
*copyc sfh$add_system_routing_control

  PROCEDURE [XDCL, #GATE] sfp$add_system_routing_control
    (    statistic_code: sft$statistic_code;
         logs: sft$binary_logset;
     VAR status: ost$status);

    VAR
      routing_control_p: ^sft$routing_control;

    status.normal := TRUE;

{ Make sure the system routing control table has been initialized.

    IF sfv$sys_routing_control_table = NIL THEN
      osp$set_status_abnormal ('SF', sfe$statistics_not_available, 'System', status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'sfp$add_system_routing_control', status);
      RETURN;
    IFEND;

{ Interlock the system routing control table.

    osp$set_mainframe_sig_lock (sfv$system_routing_control_lock);

{ Add the specified routing control information to the routing control table.

    sfp$add_routing_control (sfv$sys_routing_control_table, statistic_code, logs, osv$mainframe_pageable_heap,
          routing_control_p);

{ Clear the interlock.

    osp$clear_mainframe_sig_lock (sfv$system_routing_control_lock);

    IF (statistic_code = jml$open_file_statistics) AND NOT sfv$emit_sys_open_statistics THEN
      sfv$emit_sys_open_statistics := TRUE;
    IFEND;

  PROCEND sfp$add_system_routing_control;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] sfp$delete_sys_audit_control', EJECT ??
*copyc sfh$delete_sys_audit_control

  PROCEDURE [XDCL, #GATE] sfp$delete_sys_audit_control
    (    operation_set: sft$audited_operation_set;
     VAR status: ost$status);

    status.normal := TRUE;

{ Make sure the system routing control table has been initialized.

    IF sfv$sys_routing_control_table = NIL THEN
      osp$set_status_abnormal ('SF', sfe$statistics_not_available, 'System', status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'sfp$delete_sys_audit_control', status);
      RETURN;
    IFEND;

{ Interlock the system routing control table.

    osp$set_mainframe_sig_lock (sfv$system_routing_control_lock);

{ Delete the specified audit control information from the routing control table.

    sfp$delete_audit_control (sfv$sys_routing_control_table, operation_set, osv$mainframe_pageable_heap,
          status);

{ Clear the interlock.

    osp$clear_mainframe_sig_lock (sfv$system_routing_control_lock);

  PROCEND sfp$delete_sys_audit_control;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] sfp$delete_sys_routing_control', EJECT ??
*copyc sfh$delete_sys_routing_control

  PROCEDURE [XDCL, #GATE] sfp$delete_sys_routing_control
    (    statistic_code: sft$statistic_code;
         logs: sft$binary_logset;
     VAR status: ost$status);

    status.normal := TRUE;

{ Make sure the system routing control table has been initialized.

    IF sfv$sys_routing_control_table = NIL THEN
      osp$set_status_abnormal ('SF', sfe$statistics_not_available, 'System', status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'sfp$delete_sys_routing_control', status);
      RETURN;
    IFEND;

{ Interlock the system routing control table.

    osp$set_mainframe_sig_lock (sfv$system_routing_control_lock);

{ Delete the specified routing control information from the routing control table.

    sfp$delete_routing_control (sfv$sys_routing_control_table, statistic_code, logs, status);

{ Clear the interlock.

    osp$clear_mainframe_sig_lock (sfv$system_routing_control_lock);

    IF (statistic_code = jml$open_file_statistics) AND sfv$emit_sys_open_statistics THEN
      sfv$emit_sys_open_statistics := FALSE;
    IFEND;

  PROCEND sfp$delete_sys_routing_control;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] sfp$init_system_routing_control', EJECT ??
*copyc sfh$init_system_routing_control

  PROCEDURE [XDCL, #GATE] sfp$init_system_routing_control
    (VAR status: ost$status);

    VAR
      index: 0 .. sfc$routing_control_table_size,
      selection_criteria_p: ^sft$audit_selection_criteria;

    status.normal := TRUE;

{ Allocate the system routing control table and initialize each entry to NIL.

    ALLOCATE sfv$sys_routing_control_table: [0 .. sfc$routing_control_table_size] IN
          osv$mainframe_pageable_heap^;

    FOR index := 0 TO sfc$routing_control_table_size DO
      sfv$sys_routing_control_table^ [index] := NIL;
    FOREND;

    osp$initialize_sig_lock (sfv$system_routing_control_lock);

{ Activate accounting statistics

    sfp$add_system_routing_control (avc$begin_account, $sft$binary_logset
          [pmc$job_account_log, pmc$account_log], {ignore} status);
    sfp$add_system_routing_control (avc$end_account, $sft$binary_logset
          [pmc$job_account_log, pmc$account_log], {ignore} status);
    sfp$add_system_routing_control (avc$begin_application, $sft$binary_logset
          [pmc$job_account_log, pmc$account_log], {ignore} status);
    sfp$add_system_routing_control (avc$end_application, $sft$binary_logset
          [pmc$job_account_log, pmc$account_log], {ignore} status);
    sfp$add_system_routing_control (avc$application_units, $sft$binary_logset
          [pmc$job_account_log, pmc$account_log], {ignore} status);
    sfp$add_system_routing_control (avc$ca_interactive_interval, $sft$binary_logset
          [pmc$job_account_log, pmc$account_log], {ignore} status);

{ Activate DVS usage statistic

    sfp$add_system_routing_control (cml$dvs_usage_data, $sft$binary_logset [pmc$engineering_log],
          {ignore} status);

{ Activate and lock the user identification and job end audit controls if security audit is enabled.

    IF avp$security_option_active (avc$vso_security_audit) THEN

{ Initialize an empty selection criteria that will cause all user identification and job end audit
{ statistics to be emitted.

      PUSH selection_criteria_p: [1 .. 1];
      selection_criteria_p^ [1].selector := sfc$as_null_selector;
      sfp$add_system_audit_control ($sft$audited_operation_set[sfc$ao_job_user_identification,
            sfc$ao_job_end], selection_criteria_p^, {lock =} TRUE, { ignore } status);
    IFEND;

    status.normal := TRUE;

  PROCEND sfp$init_system_routing_control;
?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] sfp$lock_system_routing_control', EJECT ??
*copyc sfh$lock_system_routing_control

  PROCEDURE [XDCL, #GATE] sfp$lock_system_routing_control
    (    statistic_code: sft$statistic_code;
         logs: sft$binary_logset;
     VAR status: ost$status);

    status.normal := TRUE;

{ Make sure the system routing control table has been initialized.

    IF sfv$sys_routing_control_table = NIL THEN
      osp$set_status_abnormal ('SF', sfe$statistics_not_available, 'System', status);
      osp$append_status_parameter (osc$status_parameter_delimiter, 'sfp$lock_system_routing_control', status);
      RETURN;
    IFEND;

{ Interlock the system routing control table.

    osp$set_mainframe_sig_lock (sfv$system_routing_control_lock);

{ Delete the specified routing control information.

    sfp$lock_routing_control (sfv$sys_routing_control_table, statistic_code, logs,
          osv$mainframe_pageable_heap);

{ Clear the interlock.

    osp$clear_mainframe_sig_lock (sfv$system_routing_control_lock);

  PROCEND sfp$lock_system_routing_control;
?? OLDTITLE ??
MODEND sfm$sys_routing_control_manager;
