From:	SMTP%"law@corp1.cincom.com" 17-MAY-1996 15:19:16.52
To:	EVERHART
CC:	
Subj:	Re: Problems going from 6.1 to 6.2?

Date: Wed, 15 May 1996 09:16:06 -0400
From: law@corp1.cincom.com (Socket() to me)
Subject: Re: Problems going from 6.1 to 6.2?
To: jont@tiger.hsc.edu, open-vms-sig@DECUS.Org
Errors-to: open-vms-sig-owner@DECUS.Org
Warnings-to: open-vms-sig-owner@DECUS.Org
Message-id: <96051509160660@corp1.cincom.com>
X-VMS-To: SMTP%"jont@tiger.hsc.edu"
X-VMS-Cc: SMTP%"open-vms-sig@decus.org",LAW
Content-transfer-encoding: 7BIT
Comments: Send OPEN-VMS-SIG subscribe/unsubscribe requests to mailserv@DECUS.Org

Greetings,

>I have an Alpha 2100 and I'm going to upgrade from VMS 6.1 to 6.2.  Anyone
>have/know of any problems I should be aware of in this upgrade?
Included below is a problem I encountered and reported via DSNlink. And
below that is the DSN response.

Cheers, Bill Law  :-)
blaw@cincom.com

------  s t a r t   o f   p r o b l e m   d e s c r i p t i o n   ------

Part of our applications client/server synchronization has broken with
the introduction of OpenVMS 6.2.  A sleep() function is called
followed by a sys$hiber() call, and a sys$wake() is expected from
another process.  However, if the $wake AST is delivered during the
sleep() interval then the following sys$hiber() never wakes up and the
process is forever stuck in HIB state.

This mechanism has worked in all previous VMS releases up to and
including 6.1.  With 6.2 it is broken.  It is as if the sleep()
function clears all pending $wake AST's rather than leaving them
queued up as it should.  The following program illustrates the
problem.  This is with DECC on both Vax and Alpha.

Note that if the sleep() function below is replaced with another
sys$schdwk/sys$hiber then there is no problem.  The issue seems to
center around the sleep() function.

#include stdio
#include signal
#include starlet
#include descrip

unsigned long status = 0;
unsigned long mypid = 0;
unsigned long bintime[2];

main()
{
  $DESCRIPTOR( asctime, "0 00:00:02.00" );
  sys$bintim( &asctime, &bintime );

  printf( "Calling sys$schdwk(2)..." );
  status = sys$schdwk( &mypid, 0, &bintime, 0 );
  printf( "done %%X%08X\n", status );

  printf( "Calling sleep(4)........" );
  status = sleep( 4 );
  printf( "done %%X%08X\n", status );

  printf( "Calling sys$hiber()....." );
  status = sys$hiber();
  printf( "done %%X%08X\n", status );
}

----------   s t a r t   o f   D S N   r e s p o n s e   ---------------

I verified that your program completes on OpenVMS V6.1 and
hibernates on OpenVMS V6.2.

This is related to a fix to a different problem, about sleep
returning early due to not clearing pending wakeups.  For
example, the following program behaves like this on OpenVMS
V6.1

	$ run sleeper
	slept for approximately 10 seconds
	slept for approximately 3 seconds
	slept for approximately 7 seconds
	slept for approximately 3 seconds
	slept for approximately 7 seconds
	slept for approximately 3 seconds
	slept for approximately 7 seconds
	slept for approximately 3 seconds
	slept for approximately 7 seconds
	slept for approximately 3 seconds
	$

but thanks to the change it behaves like this on OpenVMS V6.2

	$ run sleeper
	slept for approximately 10 seconds
	slept for approximately 3 seconds
	slept for approximately 10 seconds
	slept for approximately 10 seconds
	slept for approximately 10 seconds
	slept for approximately 10 seconds
	slept for approximately 10 seconds
	slept for approximately 10 seconds
	slept for approximately 10 seconds
	slept for approximately 10 seconds
	$

I'll let the DEC C run-time library engineering team know
about the impact of the change on your application.

>Note that if the sleep() function below is replaced with another
>sys$schdwk/sys$hiber then there is no problem.

I take it that means you have a workaround for now.  If not,
you can compile all of your calls to sleep with

	CC/PREFIX=(ALL,EXCEPT=SLEEP)

and the compiled code will no longer reference the prefixed
symbol decc$sleep in SYS$SHARE:DECC$SHR.EXE, it will instead
reference the non-prefixed symbol sleep.  Then you can define
your own sleep routine in sleep.c, also compiled with

	CC/PREFIX=(ALL,EXCEPT=SLEEP)

and link with it.  For example, sleep.c can use sys$setimr
and sys$waitfr, or lib$wait, or some combination of sys$schdwk,
sys$wake and sys$hiber that is better suited to your application.

Dan

Dan D'Eramo
Language Support Team



#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef void (*handler_t)(int sig);

static volatile sig_atomic_t timeout = 0;
static void handler(int sig)
{
    timeout = 1;
}

int main()
{
    handler_t old_handler;
    time_t before;
    time_t after;
    int i;

    timeout = 0;
    old_handler = signal(SIGALRM, handler);
    if (old_handler == SIG_ERR) {
        perror("signal");
        exit(EXIT_FAILURE);
    }
    alarm(13);

    for (i = 0 ; i < 10; ++i) {
        before = time(0);
        sleep(10);
        after = time(0);
        printf("slept for approximately %.0f seconds\n",
            difftime(after, before));
    }

    if (signal(SIGALRM, old_handler) == SIG_ERR) {
        perror("signal");
        exit(EXIT_FAILURE);
    }
    exit(EXIT_SUCCESS);
}
