[Info-vax] POSIX Thread stack highwater mark

RobertsonEricW robertsonericw at netzero.net
Fri Feb 11 16:17:09 EST 2011


On Feb 10, 9:10 pm, VAXman-  @SendSpamHere.ORG wrote:
> In article <2174b7d3-c50a-4062-85b4-212b6c8c0... at i39g2000prd.googlegroups.com>, RobertsonEricW <robertsoner... at netzero.net> writes:
>
> >Is there a way to determine the highwater mark for usage of a POSIX
> >Thread's stack?
>
> >I am trying to determine the appropriate stack size based on empirical
> >executions of a thread so that I don't waste memory by allocating an
> >unnecessarily large stack when creating a POSIX thread.
>
> >Thanks in advance for any wisdom.
>
> Perhaps this will shed some light as well.  I have to be on the road
> tomorrow.  If you have any other questions, post them here or email,
> and I'll answer when I have a chance.
>
> //++
> // Copyright 2010-2011 by Brian Schenkenberger and TMESIS SOFTWARE
> // ALL RIGHTS RESERVED.
> //
> // The technology embodied within this code is not authorized for use
> // by any schmucks without the prior written consent of its author.
> //
> // I see C -- Yuck!
> //--
>
> #pragma environment save
> #pragma message disable MAINPROGEXT
> #define __NEW_STARLET 1
>
> #include <errno.h>
> #include <errnodef.h>
>
> #include <stsdef.h>
> #include <lib$routines.h>
>
> #ifdef  EABANDONED
> #define DECC$ERRNO_TO_MSGCOD(x) (x <= EBADMSG ? C$_EPERM+((x-1)<<STS$V_CODE) \
>                                  : C$_EABANDONED+((x-1-EBADMSG)<<STS$V_CODE) )
> #else
> #define DECC$ERRNO_TO_MSGCOD(x)               ( C$_EPERM+((x-1)<<STS$V_CODE) )
> #endif
>
> #include <pthread.h>
> #include <tebdef.h>
>
> #include <stdio.h>
> #include <stdlib.h>
> #include <starlet.h>
>
> #pragma optimize save
> #pragma optimize level=5
> #pragma required_pointer_size save
> #pragma required_pointer_size long
>
> #ifdef __ia64
> __int64 __SP() {__int64 i; return (__int64)&i;}
> #endif
> #ifdef  __alpha
> __int64 __SP() {__int64 i; return (__int64)&i+8;}
> #endif
> #pragma inline (__SP)
>
> #pragma required_pointer_size restore
> #pragma optimize restore
>
> #pragma optimize save
> #pragma optimize level=0                        // or the array is optimized away
> small ()
>   {
>     int small_array[16];                        // consume a small amount of stack
>
>     printf("small: TEB: %08X\n", pthread_self());
>
>     ((TEB*) pthread_self())->teb$pq_stack_hiwater = (void*) __SP();
>
>     printf("stack base: %08X\nstack high: %08X\nstack used: %08X\n\n",
>            ((TEB*) pthread_self())->teb$pq_stack_base,
>            ((TEB*) pthread_self())->teb$pq_stack_hiwater,
>       (int)((TEB*) pthread_self())->teb$pq_stack_base - (int)((TEB*) pthread_self())->teb$pq_stack_hiwater);
>
>     SYS$HIBER();
>   }
> #pragma optimize restore
>
> #pragma optimize save
> #pragma optimize level=0                        // or the array is optimized away
> large ()
>   {
>     int large_array[1024];                      // consume a small amount of stack
>
>     printf("large: TEB: %08X\n", pthread_self());
>
>     ((TEB*) pthread_self())->teb$pq_stack_hiwater = (void*) __SP();
>
>     printf("stack base: %08X\nstack high: %08X\nstack used: %08X\n\n",
>            ((TEB*) pthread_self())->teb$pq_stack_base,
>            ((TEB*) pthread_self())->teb$pq_stack_hiwater,
>       (int)((TEB*) pthread_self())->teb$pq_stack_base - (int)((TEB*) pthread_self())->teb$pq_stack_hiwater);
>
>     SYS$HIBER();
>   }
> #pragma optimize restore
>
> thread_demo() main_program
>   {
>     int sts;
>
>     pthread_t   small_stack_thread;
>     pthread_t   large_stack_thread;
>     pthread_attr_t attr;
>
>     if (sts=pthread_attr_init(&attr)) { LIB$SIGNAL(DECC$ERRNO_TO_MSGCOD(sts)); }
>     if (sts=pthread_attr_setstacksize(&attr, PTHREAD_STACK_MIN*2)) { LIB$SIGNAL(DECC$ERRNO_TO_MSGCOD(sts)); }
>
>     if (sts=pthread_create(&small_stack_thread, &attr, (void *(*)(void*)) small, 0)) { LIB$SIGNAL(DECC$ERRNO_TO_MSGCOD(sts)); }
>     if (sts=pthread_detach(small_stack_thread)) { LIB$SIGNAL(DECC$ERRNO_TO_MSGCOD(sts)); }
>
>     if (sts=pthread_create(&large_stack_thread, &attr, (void *(*)(void*)) large, 0)) { LIB$SIGNAL(DECC$ERRNO_TO_MSGCOD(sts)); }
>     if (sts=pthread_detach(large_stack_thread)) { LIB$SIGNAL(DECC$ERRNO_TO_MSGCOD(sts)); }
>
>     SYS$HIBER();
>   }
>
> #pragma environment restore
> --
> VAXman- A Bored Certified VMS Kernel Mode Hacker    VAXman(at)TMESIS(dot)ORG
>
> All your spirit rack abuses, come to haunt you back by day.
> All your Byzantine excuses, given time, given you away.

Thanks VAXman.

I will try simply enabling the stack metering by defining the
PTHREAD_CONFIG logical name (I hadn't yet bumped across this nugget of
knowledge in the OpenVMS Guide to POSIX Threads documentation). If
that doesn't seem to work, then I will resort to the method described
in your code sample.

Eric



More information about the Info-vax mailing list