* Makefile.in: Add rule for hpux-thread.o (needs special header
authorStu Grossman <grossman@cygnus>
Tue, 8 Oct 1996 17:06:17 +0000 (17:06 +0000)
committerStu Grossman <grossman@cygnus>
Tue, 8 Oct 1996 17:06:17 +0000 (17:06 +0000)
files).
* (SUBDIRS):  Remove mswin.
* Change procedure for creating init.c.  Speeds things up quite a
bit.
* config.in configure configure.in:  Check for select, poll.
* Check for OSF header files before including hpux-thread.o.
* Don't configure doc or testsuite when building under MSVC.
* findvar.c value.h (read_register_pid write_register_pid):  Make
global.  Needed for hppa-tdep.c.
* (supply_register):  Don't set pid to inferior_pid when supplying
registers.
* hppa-tdep.c (saved_pc_after_call):  frame_saved_pc ->
FRAME_SAVED_PC.
* (frame_saved_pc):  Change name to hppa_frame_saved_pc.
* (hppa_pop_frame):  Don't use a pid of 0 with target_write_pc.
Use write_pc instead, which uses the correct pid.
* (target_read_pc target_write_pc):  Use read/write_register_pid
instead of read/write_register to preserve the pid passed in.
* inftarg.c (child_can_run):  Add flag child_suppress_run to allow
hpux-threads.c to override this as a runnable target.
* config/pa/nm-hppah.h:  Define target_new_objfile and
target_pid_to_str.
* config/pa/tm-hppa.h (FRAME_SAVED_PC):  Use hppa_frame_saved_pc
instead of frame_saved_pc.
* config/m68k/tm-m68k.h:  Define TARGET_M68K for Wingdb.
* config/m68k/tm-monitor.h:  Use FRAME_CHAIN_VALID_ALTERNATE, since
we can't easily determine the start file bounds with ELF.
* config/mips/tm-mips.h:  Define TARGET_MIPS for Wingdb.
* hpux-thread.c:  New file for HPUX/OSF thread support.
* osf-share/{README AT386/cma_thread_io.h HP800/cma_thread_io.h
RIOS/cma_thread_io.h cma_attr.h cma_deb_core.h cma_debug_client.h
cma_errors.h cma_handle.h cma_init.h cma_list.h cma_mutex.h
cma_sched.h cma_semaphore_defs.h cma_sequence.h cma_stack.h
cma_stack_int.h cma_tcb_defs.h cma_util.h}:  New files for OSF
thread support.

33 files changed:
gdb/ChangeLog
gdb/Makefile.in
gdb/config.in
gdb/config/m68k/tm-m68k.h
gdb/config/mips/tm-mips.h
gdb/config/pa/nm-hppah.h
gdb/configure
gdb/configure.in
gdb/hppa-tdep.c
gdb/hpux-thread.c [new file with mode: 0644]
gdb/osf-share/.Sanitize [new file with mode: 0644]
gdb/osf-share/AT386/.Sanitize [new file with mode: 0644]
gdb/osf-share/AT386/cma_thread_io.h [new file with mode: 0644]
gdb/osf-share/HP800/.Sanitize [new file with mode: 0644]
gdb/osf-share/HP800/cma_thread_io.h [new file with mode: 0644]
gdb/osf-share/README [new file with mode: 0644]
gdb/osf-share/RIOS/.Sanitize [new file with mode: 0644]
gdb/osf-share/RIOS/cma_thread_io.h [new file with mode: 0644]
gdb/osf-share/cma_attr.h [new file with mode: 0644]
gdb/osf-share/cma_deb_core.h [new file with mode: 0644]
gdb/osf-share/cma_debug_client.h [new file with mode: 0644]
gdb/osf-share/cma_errors.h [new file with mode: 0644]
gdb/osf-share/cma_handle.h [new file with mode: 0644]
gdb/osf-share/cma_init.h [new file with mode: 0644]
gdb/osf-share/cma_list.h [new file with mode: 0644]
gdb/osf-share/cma_mutex.h [new file with mode: 0644]
gdb/osf-share/cma_sched.h [new file with mode: 0644]
gdb/osf-share/cma_semaphore_defs.h [new file with mode: 0644]
gdb/osf-share/cma_sequence.h [new file with mode: 0644]
gdb/osf-share/cma_stack.h [new file with mode: 0644]
gdb/osf-share/cma_stack_int.h [new file with mode: 0644]
gdb/osf-share/cma_tcb_defs.h [new file with mode: 0644]
gdb/osf-share/cma_util.h [new file with mode: 0644]

index 40e65a6..c275baf 100644 (file)
@@ -1,3 +1,42 @@
+Tue Oct  8 09:03:22 1996  Stu Grossman  (grossman@critters.cygnus.com)
+
+       * Makefile.in:  Add rule for hpux-thread.o (needs special header
+       files).
+       * (SUBDIRS):  Remove mswin.
+       * Change procedure for creating init.c.  Speeds things up quite a
+       bit.
+       * config.in configure configure.in:  Check for select, poll.
+       * Check for OSF header files before including hpux-thread.o.
+       * Don't configure doc or testsuite when building under MSVC.
+       * findvar.c value.h (read_register_pid write_register_pid):  Make
+       global.  Needed for hppa-tdep.c.
+       * (supply_register):  Don't set pid to inferior_pid when supplying
+       registers.
+       * hppa-tdep.c (saved_pc_after_call):  frame_saved_pc ->
+       FRAME_SAVED_PC.
+       * (frame_saved_pc):  Change name to hppa_frame_saved_pc.
+       * (hppa_pop_frame):  Don't use a pid of 0 with target_write_pc.
+       Use write_pc instead, which uses the correct pid.
+       * (target_read_pc target_write_pc):  Use read/write_register_pid
+       instead of read/write_register to preserve the pid passed in.
+       * inftarg.c (child_can_run):  Add flag child_suppress_run to allow
+       hpux-threads.c to override this as a runnable target.
+       * config/pa/nm-hppah.h:  Define target_new_objfile and
+       target_pid_to_str.
+       * config/pa/tm-hppa.h (FRAME_SAVED_PC):  Use hppa_frame_saved_pc
+       instead of frame_saved_pc.
+       * config/m68k/tm-m68k.h:  Define TARGET_M68K for Wingdb.
+       * config/m68k/tm-monitor.h:  Use FRAME_CHAIN_VALID_ALTERNATE, since
+       we can't easily determine the start file bounds with ELF.
+       * config/mips/tm-mips.h:  Define TARGET_MIPS for Wingdb.
+       * hpux-thread.c:  New file for HPUX/OSF thread support.
+       * osf-share/{README AT386/cma_thread_io.h HP800/cma_thread_io.h
+       RIOS/cma_thread_io.h cma_attr.h cma_deb_core.h cma_debug_client.h
+       cma_errors.h cma_handle.h cma_init.h cma_list.h cma_mutex.h
+       cma_sched.h cma_semaphore_defs.h cma_sequence.h cma_stack.h
+       cma_stack_int.h cma_tcb_defs.h cma_util.h}:  New files for OSF
+       thread support.
+
 Sun Oct  6 15:48:09 1996  Fred Fish  <fnf@cygnus.com>
 
        * buildsym.c (finish_block): Change innerblock_anon_complaint to
index 344558c..de5a5b8 100644 (file)
@@ -183,7 +183,8 @@ INTERNAL_CFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) \
 # Profiling options need to go here to work.
 # I think it's perfectly reasonable for a user to set -pg in CFLAGS
 # and have it work; that's why CFLAGS is here.
-INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(LDFLAGS) @CONFIG_LDFLAGS@
+INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(PROFILE_CFLAGS) $(LDFLAGS) @CONFIG_LDFLAGS@ @HLDFLAGS@
+HLDENV = @HLDENV@
 
 # We are using our own version of REGEX now to be consistent across
 # machines.
@@ -487,7 +488,7 @@ NTSOBS = standalone.o
 
 NTSSTART = kdb-start.o
 
-SUBDIRS = doc testsuite nlm mswin
+SUBDIRS = doc testsuite nlm
 
 # For now, shortcut the "configure GDB for fewer languages" stuff.
 YYFILES = c-exp.tab.c f-exp.tab.c m2-exp.tab.c
@@ -585,9 +586,9 @@ init.c: $(OBS) $(TSOBS)
        @echo '#include "ansidecl.h"' >>init.c-tmp
        @echo 'extern void initialize_all_files PARAMS ((void));' >>init.c-tmp
        @echo 'void initialize_all_files PARAMS ((void)) {' >>init.c-tmp
-       @for i in $(OBS) $(TSOBS); do \
-         filename=`echo $$i | sed \
-           -e '/^Onindy.o/d' \
+       @echo $(OBS) $(TSOBS) | \
+       tr ' ' '\012' | \
+       sed -e '/^Onindy.o/d' \
            -e '/^nindy.o/d' \
            -e '/ttyflush.o/d' \
            -e '/xdr_ld.o/d' \
@@ -599,13 +600,10 @@ init.c: $(OBS) $(TSOBS)
            -e '/version.o/d' \
            -e '/^[a-z0-9A-Z_]*_[SU].o/d' \
            -e '/[a-z0-9A-Z_]*-exp.tab.o/d' \
-           -e 's/\.o/.c/'` ; \
-         case $$filename in \
-           "") ;; \
-           *) sed <$(srcdir)/$$filename >>init.c-tmp -n \
-           -e '/^_initialize_[a-z_0-9A-Z]* *(/s/^\([a-z_0-9A-Z]*\).*/  {extern void \1 PARAMS ((void)); \1 ();}/p' ; ;; \
-         esac ; \
-       done
+           -e 's/\.o/.c/' \
+           -e 's|\([^  ][^     ]*\)|$(srcdir)/\1|g' | \
+       xargs grep -h -s '^_initialize_[a-z_0-9A-Z]* *(' | \
+       sed -e 's/^\([a-z_0-9A-Z]*\).*/  {extern void \1 PARAMS ((void)); \1 ();}/p' >>init.c-tmp
        @echo '}' >>init.c-tmp
        @mv init.c-tmp init.c
 
@@ -614,7 +612,7 @@ init.c: $(OBS) $(TSOBS)
 # Removing the old gdb first works better if it is running, at least on SunOS.
 gdb: $(OBS) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o
        rm -f gdb
-       $(CC_LD) $(INTERNAL_LDFLAGS) -o gdb \
+       $(HLDENV) $(CC_LD) $(INTERNAL_LDFLAGS) -o gdb \
          init.o $(OBS) $(TSOBS) $(ADD_FILES) $(CLIBS) $(LOADLIBES)
 
 nlm:   force
@@ -622,9 +620,6 @@ nlm:        force
 
 libgdb:        libgdb-files $(LIBGDB_OBS)
 
-mswin/libwingdb.a: force
-       rootme=`pwd`; export rootme; $(MAKE) $(FLAGS_TO_PASS) DO=all DODIRS=mswin subdir_do
-
 # libproc is not listed here because all-libproc is a dependency of all-gui,
 # not all-gdb, and thus might be built after us.
 LIBGDBDEPS=$(COMMON_OBS) $(LIBGDB_OBS) $(TSOBS) $(ADD_DEPS) $(CDEPS) init.o
@@ -1326,6 +1321,10 @@ somread.o: somread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
 
 somsolib.o: somsolib.c $(defs_h)
 
+hpux-thread.o: hpux-thread.c $(defs_h) gdbthread.h target.h inferior.h
+       $(CC) -c $(INTERNAL_CFLAGS) -I$(srcdir)/osf-share \
+         -I$(srcdir)/osf-share/HP800 -I/usr/include/dce $(srcdir)/hpux-thread.c
+
 hpread.o: hpread.c $(bfd_h) buildsym.h complaints.h $(defs_h) \
        gdb-stabs.h objfiles.h symfile.h $(symtab_h) gdb_string.h
 
index a3b3e51..a719fb0 100644 (file)
 
 /* Define if you have the <unistd.h> header file.  */
 #undef HAVE_UNISTD_H
+
+/* Define if you have the select function.  */
+#undef HAVE_SELECT
+
+/* Define if you have the poll function.  */
+#undef HAVE_POLL
+
+/* Define if you have HPUX threads */
+#undef HAVE_HPUX_THREAD_SUPPORT
index 6305f59..e21fd28 100644 (file)
@@ -387,3 +387,5 @@ extern void m68k_pop_frame PARAMS ((void));
 /* Offset from SP to first arg on stack at first instruction of a function */
 
 #define SP_ARG0 (1 * 4)
+
+#define TARGET_M68K
index 841b7fe..d96dd0b 100644 (file)
@@ -543,4 +543,6 @@ extern void fixup_sigtramp PARAMS ((void));
 /* Defined in mips-tdep.c and used in remote-mips.c */
 extern char *mips_read_processor_type PARAMS ((void));
 
+#define TARGET_MIPS
+
 #endif /* TM_MIPS_H */
index d40e5f8..1584c9b 100644 (file)
@@ -75,3 +75,17 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
    target process...  Which really pisses off GDB.)  */
 
 #define ATTACH_DETACH
+
+#ifdef HAVE_HPUX_THREAD_SUPPORT
+
+#ifdef __STDC__
+struct objfile;
+#endif
+
+void hpux_thread_new_objfile PARAMS ((struct objfile *objfile));
+#define target_new_objfile(OBJFILE) hpux_thread_new_objfile (OBJFILE)
+
+extern char *hpux_pid_to_str PARAMS ((int pid));
+#define target_pid_to_str(PID) hpux_pid_to_str (PID)
+
+#endif /* HAVE_HPUX_THREAD_SUPPORT */
index b39ee60..9a6742b 100755 (executable)
@@ -1461,7 +1461,7 @@ EOF
 fi
 
 
-for ac_func in setpgid sbrk
+for ac_func in setpgid sbrk select poll
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
@@ -2044,6 +2044,21 @@ EOF
        else
                echo "$ac_t""no" 1>&6
        fi
+       case ${host_os} in
+       hpux*)
+               echo $ac_n "checking for HPUX/OSF thread support""... $ac_c" 1>&6
+               if test -f /usr/include/dce/cma_config.h ; then
+                       echo "$ac_t""yes" 1>&6
+                       cat >> confdefs.h <<\EOF
+#define HAVE_HPUX_THREAD_SUPPORT 1
+EOF
+
+                       THREAD_DB_OBS=hpux-thread.o
+               else
+                       echo "$ac_t""no" 1>&6
+               fi
+               ;;
+       esac
        
        
 fi
@@ -2422,12 +2437,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2426 "configure"
+#line 2441 "configure"
 #include "confdefs.h"
 #include <tclInt.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2431: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2446: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2554,12 +2569,12 @@ if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2558 "configure"
+#line 2573 "configure"
 #include "confdefs.h"
 #include <tk.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2563: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2578: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2763,7 +2778,7 @@ i[3456]86-*-isc*) gdb_host=i386v32 ;;
 i[3456]86-*-os9k)      gdb_host=i386os9k ;;
 i[3456]86-*-cygwin32)  gdb_host=cygwin32 ;;
 i[3456]86-*-windows)   gdb_host=windows
-                       configdirs="${configdirs} mswin" ;;
+                       configdirs=mswin ;;
 m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
 m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
 m68030-sony-*)         gdb_host=news1000 ;;
index 4b794f4..9f0abde 100644 (file)
@@ -45,7 +45,7 @@ AC_HEADER_STAT
 
 AC_C_CONST
 
-AC_CHECK_FUNCS(setpgid sbrk)
+AC_CHECK_FUNCS(setpgid sbrk select poll)
 
 # If we are configured native on Linux, work around problems with sys/procfs.h
 if test "${target}" = "${host}"; then
@@ -163,6 +163,18 @@ if test ${build} = ${host} -a ${host} = ${target} ; then
        else
                AC_MSG_RESULT(no)
        fi
+       case ${host_os} in
+       hpux*)
+               AC_MSG_CHECKING(for HPUX/OSF thread support)
+               if test -f /usr/include/dce/cma_config.h ; then
+                       AC_MSG_RESULT(yes)
+                       AC_DEFINE(HAVE_HPUX_THREAD_SUPPORT)
+                       THREAD_DB_OBS=hpux-thread.o
+               else
+                       AC_MSG_RESULT(no)
+               fi
+               ;;
+       esac
        AC_SUBST(THREAD_DB_OBS)
        AC_SUBST(CONFIG_LDFLAGS)
 fi
@@ -414,7 +426,7 @@ i[3456]86-*-isc*)   gdb_host=i386v32 ;;
 i[3456]86-*-os9k)      gdb_host=i386os9k ;;
 i[3456]86-*-cygwin32)  gdb_host=cygwin32 ;;
 i[3456]86-*-windows)   gdb_host=windows
-                       configdirs="${configdirs} mswin" ;;
+                       configdirs=mswin ;;
 m680[01]0-sun-sunos3*) gdb_host=sun2os3 ;;
 m680[01]0-sun-sunos4*) gdb_host=sun2os4 ;;
 m68030-sony-*)         gdb_host=news1000 ;;
index 3c3f058..05463b4 100644 (file)
@@ -812,13 +812,13 @@ saved_pc_after_call (frame)
      the stub will return to out of the stack.  */
   u = find_unwind_entry (pc);
   if (u && u->stub_type != 0)
-    return frame_saved_pc (frame);
+    return FRAME_SAVED_PC (frame);
   else
     return pc;
 }
 \f
 CORE_ADDR
-frame_saved_pc (frame)
+hppa_frame_saved_pc (frame)
      struct frame_info *frame;
 {
   CORE_ADDR pc = get_frame_pc (frame);
@@ -1394,7 +1394,7 @@ hppa_pop_frame ()
   else 
     {
       npc = read_register (RP_REGNUM);
-      target_write_pc (npc, 0);
+      write_pc (npc);
     }
 
   write_register (FP_REGNUM, read_memory_integer (fp, 4));
@@ -1749,12 +1749,15 @@ CORE_ADDR
 target_read_pc (pid)
      int pid;
 {
-  int flags = read_register (FLAGS_REGNUM);
+  int flags = read_register_pid (FLAGS_REGNUM, pid);
 
-  if (flags & 2) {
-    return read_register (31) & ~0x3;
-  }
-  return read_register (PC_REGNUM) & ~0x3;
+  /* The following test does not belong here.  It is OS-specific, and belongs
+     in native code.  */
+  /* Test SS_INSYSCALL */
+  if (flags & 2)
+    return read_register_pid (31, pid) & ~0x3;
+
+  return read_register_pid (PC_REGNUM, pid) & ~0x3;
 }
 
 /* Write out the PC.  If currently in a syscall, then also write the new
@@ -1765,15 +1768,18 @@ target_write_pc (v, pid)
      CORE_ADDR v;
      int pid;
 {
-  int flags = read_register (FLAGS_REGNUM);
+  int flags = read_register_pid (FLAGS_REGNUM, pid);
 
+  /* The following test does not belong here.  It is OS-specific, and belongs
+     in native code.  */
   /* If in a syscall, then set %r31.  Also make sure to get the 
      privilege bits set correctly.  */
+  /* Test SS_INSYSCALL */
   if (flags & 2)
-    write_register (31, (long) (v | 0x3));
+    write_register_pid (31, v | 0x3, pid);
 
-  write_register (PC_REGNUM, (long) v);
-  write_register (NPC_REGNUM, (long) v + 4);
+  write_register_pid (PC_REGNUM, v, pid);
+  write_register_pid (NPC_REGNUM, v + 4, pid);
 }
 
 /* return the alignment of a type in bytes. Structures have the maximum
diff --git a/gdb/hpux-thread.c b/gdb/hpux-thread.c
new file mode 100644 (file)
index 0000000..b8c227a
--- /dev/null
@@ -0,0 +1,638 @@
+/* Low level interface for debugging HPUX/DCE threads for GDB, the GNU debugger.
+   Copyright 1996 Free Software Foundation, Inc.
+
+This file is part of GDB.
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+
+/* This module implements a sort of half target that sits between the
+   machine-independent parts of GDB and the ptrace interface (infptrace.c) to
+   provide access to the HPUX user-mode thread implementation.
+
+   HPUX threads are true user-mode threads, which are invoked via the cma_*
+   and pthread_* (DCE and Posix respectivly) interfaces.  These are mostly
+   implemented in user-space, with all thread context kept in various
+   structures that live in the user's heap.  For the most part, the kernel has
+   no knowlege of these threads.
+
+   */
+
+#include "defs.h"
+
+#define _CMA_NOWRAPPERS_
+
+#include <cma_tcb_defs.h>
+#include <cma_deb_core.h>
+#include "gdbthread.h"
+#include "target.h"
+#include "inferior.h"
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/stat.h>
+#include "gdbcore.h"
+
+extern struct target_ops hpux_thread_ops; /* Forward declaration */
+
+extern int child_suppress_run;
+extern struct target_ops child_ops; /* target vector for inftarg.c */
+
+struct string_map
+{
+  int num;
+  char *str;
+};
+
+static int hpux_thread_active = 0;
+
+static int main_pid;           /* Real process ID */
+
+static CORE_ADDR P_cma__g_known_threads;
+static CORE_ADDR P_cma__g_current_thread;
+
+static struct cleanup * save_inferior_pid PARAMS ((void));
+static void restore_inferior_pid PARAMS ((int pid));
+static void hpux_thread_resume PARAMS ((int pid, int step,
+                                       enum target_signal signo));
+\f
+/*
+
+LOCAL FUNCTION
+
+       save_inferior_pid - Save inferior_pid on the cleanup list
+       restore_inferior_pid - Restore inferior_pid from the cleanup list
+
+SYNOPSIS
+
+       struct cleanup *save_inferior_pid ()
+       void restore_inferior_pid (int pid)
+
+DESCRIPTION
+
+       These two functions act in unison to restore inferior_pid in
+       case of an error.
+
+NOTES
+
+       inferior_pid is a global variable that needs to be changed by many of
+       these routines before calling functions in procfs.c.  In order to
+       guarantee that inferior_pid gets restored (in case of errors), you
+       need to call save_inferior_pid before changing it.  At the end of the
+       function, you should invoke do_cleanups to restore it.
+
+ */
+
+
+static struct cleanup *
+save_inferior_pid ()
+{
+  return make_cleanup (restore_inferior_pid, inferior_pid);
+}
+
+static void
+restore_inferior_pid (pid)
+     int pid;
+{
+  inferior_pid = pid;
+}
+\f
+static int find_active_thread PARAMS ((void));
+
+static int cached_thread;
+static int cached_active_thread;
+static cma__t_int_tcb cached_tcb;
+
+static int
+find_active_thread ()
+{
+  static cma__t_int_tcb tcb;
+  CORE_ADDR tcb_ptr;
+
+  if (cached_active_thread != 0)
+    return cached_active_thread;
+
+  read_memory ((CORE_ADDR)P_cma__g_current_thread,
+              (char *)&tcb_ptr,
+              sizeof tcb_ptr);
+
+  read_memory (tcb_ptr, (char *)&tcb, sizeof tcb);
+
+  return (cma_thread_get_unique (&tcb.prolog.client_thread) << 16) | main_pid;
+}
+
+static cma__t_int_tcb * find_tcb PARAMS ((int thread));
+
+static cma__t_int_tcb *
+find_tcb (thread)
+     int thread;
+{
+  cma__t_known_object queue_header;
+  cma__t_queue *queue_ptr;
+
+  if (thread == cached_thread)
+    return &cached_tcb;
+
+  read_memory ((CORE_ADDR)P_cma__g_known_threads,
+              (char *)&queue_header,
+              sizeof queue_header);
+
+  for (queue_ptr = queue_header.queue.flink;
+       queue_ptr != (cma__t_queue *)P_cma__g_known_threads;
+       queue_ptr = cached_tcb.threads.flink)
+    {
+      cma__t_int_tcb *tcb_ptr;
+
+      tcb_ptr = cma__base (queue_ptr, threads, cma__t_int_tcb);
+
+      read_memory ((CORE_ADDR)tcb_ptr, (char *)&cached_tcb, sizeof cached_tcb);
+
+      if (cached_tcb.header.type == cma__c_obj_tcb)
+       if (cma_thread_get_unique (&cached_tcb.prolog.client_thread) == thread >> 16)
+         {
+           cached_thread = thread;
+           return &cached_tcb;
+         }
+    }
+
+  error ("Can't find TCB %d,%d", thread >> 16, thread & 0xffff);
+  return NULL;
+}
+\f
+/* Most target vector functions from here on actually just pass through to
+   inftarg.c, as they don't need to do anything specific for threads.  */
+
+/* ARGSUSED */
+static void
+hpux_thread_open (arg, from_tty)
+     char *arg;
+     int from_tty;
+{
+  child_ops.to_open (arg, from_tty);
+}
+
+/* Attach to process PID, then initialize for debugging it
+   and wait for the trace-trap that results from attaching.  */
+
+static void
+hpux_thread_attach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  child_ops.to_attach (args, from_tty);
+
+  /* XXX - might want to iterate over all the threads and register them. */
+}
+
+/* Take a program previously attached to and detaches it.
+   The program resumes execution and will no longer stop
+   on signals, etc.  We'd better not have left any breakpoints
+   in the program or it'll die when it hits one.  For this
+   to work, it may be necessary for the process to have been
+   previously attached.  It *might* work if the program was
+   started via the normal ptrace (PTRACE_TRACEME).  */
+
+static void
+hpux_thread_detach (args, from_tty)
+     char *args;
+     int from_tty;
+{
+  child_ops.to_detach (args, from_tty);
+}
+
+/* Resume execution of process PID.  If STEP is nozero, then
+   just single step it.  If SIGNAL is nonzero, restart it with that
+   signal activated.  We may have to convert pid from a thread-id to an LWP id
+   for procfs.  */
+
+static void
+hpux_thread_resume (pid, step, signo)
+     int pid;
+     int step;
+     enum target_signal signo;
+{
+  struct cleanup *old_chain;
+
+  old_chain = save_inferior_pid ();
+
+  pid = inferior_pid = main_pid;
+
+#if 0
+  if (pid != -1)
+    {
+      pid = thread_to_lwp (pid, -2);
+      if (pid == -2)           /* Inactive thread */
+       error ("This version of Solaris can't start inactive threads.");
+    }
+#endif
+
+  child_ops.to_resume (pid, step, signo);
+
+  cached_thread = 0;
+  cached_active_thread = 0;
+
+  do_cleanups (old_chain);
+}
+
+/* Wait for any threads to stop.  We may have to convert PID from a thread id
+   to a LWP id, and vice versa on the way out.  */
+
+static int
+hpux_thread_wait (pid, ourstatus)
+     int pid;
+     struct target_waitstatus *ourstatus;
+{
+  int rtnval;
+  struct cleanup *old_chain;
+
+  old_chain = save_inferior_pid ();
+
+  inferior_pid = main_pid;
+
+  if (pid != -1)
+    pid = main_pid;
+
+  rtnval = child_ops.to_wait (pid, ourstatus);
+
+  rtnval = find_active_thread ();
+
+  do_cleanups (old_chain);
+
+  return rtnval;
+}
+
+static char regmap[NUM_REGS] =
+{
+  -2, -1, -1, 0, 4, 8, 12, 16, 20, 24, /* flags, r1 -> r9 */
+  28, 32, 36, 40, 44, 48, 52, 56, 60, -1, /* r10 -> r19 */
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* r20 -> r29 */
+
+  /* r30, r31, sar, pcoqh, pcsqh, pcoqt, pcsqt, eiem, iir, isr */
+  -2, -1, -1, -2, -1, -1, -1, -1, -1, -1,
+
+  /* ior, ipsw, goto, sr4, sr0, sr1, sr2, sr3, sr5, sr6 */
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+  /* sr7, cr0, cr8, cr9, ccr, cr12, cr13, cr24, cr25, cr26 */
+  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+
+  -1, -1, -1, -1,              /* mpsfu_high, mpsfu_low, mpsfu_ovflo, pad */
+  144, -1, -1, -1, -1, -1, -1, -1, /* fpsr, fpe1 -> fpe7 */
+  -1, -1, -1, -1, -1, -1, -1, -1, /* fr4 -> fr7 */
+  -1, -1, -1, -1, -1, -1, -1, -1, /* fr8 -> fr11 */
+  136, -1, 128, -1, 120, -1, 112, -1, /* fr12 -> fr15 */
+  104, -1, 96, -1, 88, -1, 80, -1, /* fr16 -> fr19 */
+  72, -1, 64, -1, -1, -1, -1, -1, /* fr20 -> fr23 */
+  -1, -1, -1, -1, -1, -1, -1, -1, /* fr24 -> fr27 */
+  -1, -1, -1, -1, -1, -1, -1, -1, /* fr28 -> fr31 */
+};
+
+static void
+hpux_thread_fetch_registers (regno)
+     int regno;
+{
+  cma__t_int_tcb tcb, *tcb_ptr;
+  struct cleanup *old_chain;
+  int i;
+  int first_regno, last_regno;
+
+  tcb_ptr = find_tcb (inferior_pid);
+
+  old_chain = save_inferior_pid ();
+
+  inferior_pid = main_pid;
+
+  if (tcb_ptr->state == cma__c_state_running)
+    {
+      child_ops.to_fetch_registers (regno);
+
+      do_cleanups (old_chain);
+
+      return;
+    }
+
+  if (regno == -1)
+    {
+      first_regno = 0;
+      last_regno = NUM_REGS - 1;
+    }
+  else
+    {
+      first_regno = regno;
+      last_regno = regno;
+    }
+
+  for (regno = first_regno; regno <= last_regno; regno++)
+    {
+      if (regmap[regno] == -1)
+       child_ops.to_fetch_registers (regno);
+      else
+       {
+         unsigned char buf[MAX_REGISTER_RAW_SIZE];
+         CORE_ADDR sp;
+
+         sp = (CORE_ADDR)tcb_ptr->static_ctx.sp - 160;
+
+         if (regno == FLAGS_REGNUM)
+           /* Flags must be 0 to avoid bogus value for SS_INSYSCALL */
+           memset (buf, '\000', REGISTER_RAW_SIZE (regno));
+         else if (regno == SP_REGNUM)
+           store_address (buf, sizeof sp, sp);
+         else if (regno == PC_REGNUM)
+           read_memory (sp - 20, buf, REGISTER_RAW_SIZE (regno));
+         else
+           read_memory (sp + regmap[regno], buf, REGISTER_RAW_SIZE (regno));
+
+         supply_register (regno, buf);
+       }
+    }
+
+  do_cleanups (old_chain);
+}
+
+static void
+hpux_thread_store_registers (regno)
+     int regno;
+{
+  cma__t_int_tcb tcb, *tcb_ptr;
+  struct cleanup *old_chain;
+  int i;
+  int first_regno, last_regno;
+
+  tcb_ptr = find_tcb (inferior_pid);
+
+  old_chain = save_inferior_pid ();
+
+  inferior_pid = main_pid;
+
+  if (tcb_ptr->state == cma__c_state_running)
+    {
+      child_ops.to_store_registers (regno);
+
+      do_cleanups (old_chain);
+
+      return;
+    }
+
+  if (regno == -1)
+    {
+      first_regno = 0;
+      last_regno = NUM_REGS - 1;
+    }
+  else
+    {
+      first_regno = regno;
+      last_regno = regno;
+    }
+
+  for (regno = first_regno; regno <= last_regno; regno++)
+    {
+      if (regmap[regno] == -1)
+       child_ops.to_store_registers (regno);
+      else
+       {
+         unsigned char buf[MAX_REGISTER_RAW_SIZE];
+         CORE_ADDR sp;
+
+         sp = (CORE_ADDR)tcb_ptr->static_ctx.sp - 160;
+
+         if (regno == FLAGS_REGNUM)
+           child_ops.to_store_registers (regno); /* Let lower layer handle this... */
+         else if (regno == SP_REGNUM)
+           {
+             write_memory ((CORE_ADDR)&tcb_ptr->static_ctx.sp,
+                           registers + REGISTER_BYTE (regno),
+                           REGISTER_RAW_SIZE (regno));
+             tcb_ptr->static_ctx.sp = (cma__t_hppa_regs *)
+               (extract_address (registers + REGISTER_BYTE (regno), REGISTER_RAW_SIZE (regno)) + 160);
+           }
+         else if (regno == PC_REGNUM)
+           write_memory (sp - 20,
+                         registers + REGISTER_BYTE (regno),
+                         REGISTER_RAW_SIZE (regno));
+         else
+           write_memory (sp + regmap[regno],
+                         registers + REGISTER_BYTE (regno),
+                         REGISTER_RAW_SIZE (regno));
+       }
+    }
+
+  do_cleanups (old_chain);
+}
+
+/* Get ready to modify the registers array.  On machines which store
+   individual registers, this doesn't need to do anything.  On machines
+   which store all the registers in one fell swoop, this makes sure
+   that registers contains all the registers from the program being
+   debugged.  */
+
+static void
+hpux_thread_prepare_to_store ()
+{
+  child_ops.to_prepare_to_store ();
+}
+
+static int
+hpux_thread_xfer_memory (memaddr, myaddr, len, dowrite, target)
+     CORE_ADDR memaddr;
+     char *myaddr;
+     int len;
+     int dowrite;
+     struct target_ops *target; /* ignored */
+{
+  int retval;
+  struct cleanup *old_chain;
+
+  old_chain = save_inferior_pid ();
+
+  inferior_pid = main_pid;
+
+  retval = child_ops.to_xfer_memory (memaddr, myaddr, len, dowrite, target);
+
+  do_cleanups (old_chain);
+
+  return retval;
+}
+
+/* Print status information about what we're accessing.  */
+
+static void
+hpux_thread_files_info (ignore)
+     struct target_ops *ignore;
+{
+  child_ops.to_files_info (ignore);
+}
+
+static void
+hpux_thread_kill_inferior ()
+{
+  child_ops.to_kill ();
+}
+
+static void
+hpux_thread_notice_signals (pid)
+     int pid;
+{
+  child_ops.to_notice_signals (pid);
+}
+
+/* Fork an inferior process, and start debugging it with /proc.  */
+
+static void
+hpux_thread_create_inferior (exec_file, allargs, env)
+     char *exec_file;
+     char *allargs;
+     char **env;
+{
+  child_ops.to_create_inferior (exec_file, allargs, env);
+
+  if (hpux_thread_active)
+    {
+      main_pid = inferior_pid;
+
+      push_target (&hpux_thread_ops);
+
+      inferior_pid = find_active_thread ();
+
+      add_thread (inferior_pid);
+    }
+}
+
+/* This routine is called whenever a new symbol table is read in, or when all
+   symbol tables are removed.  libthread_db can only be initialized when it
+   finds the right variables in libthread.so.  Since it's a shared library,
+   those variables don't show up until the library gets mapped and the symbol
+   table is read in.  */
+
+void
+hpux_thread_new_objfile (objfile)
+     struct objfile *objfile;
+{
+  struct minimal_symbol *ms;
+
+  if (!objfile)
+    {
+      hpux_thread_active = 0;
+
+      return;
+    }
+
+  ms = lookup_minimal_symbol ("cma__g_known_threads", NULL, objfile);
+
+  if (!ms)
+    return;
+
+  P_cma__g_known_threads = SYMBOL_VALUE_ADDRESS (ms);
+
+  ms = lookup_minimal_symbol ("cma__g_current_thread", NULL, objfile);
+
+  if (!ms)
+    return;
+
+  P_cma__g_current_thread = SYMBOL_VALUE_ADDRESS (ms);
+
+  hpux_thread_active = 1;
+}
+
+/* Clean up after the inferior dies.  */
+
+static void
+hpux_thread_mourn_inferior ()
+{
+  child_ops.to_mourn_inferior ();
+}
+
+/* Mark our target-struct as eligible for stray "run" and "attach" commands.  */
+
+static int
+hpux_thread_can_run ()
+{
+  return child_suppress_run;
+}
+
+static int
+hpux_thread_alive (pid)
+     int pid;
+{
+  return 1;
+}
+
+static void
+hpux_thread_stop ()
+{
+  child_ops.to_stop ();
+}
+\f
+/* Convert a pid to printable form. */
+
+char *
+hpux_pid_to_str (pid)
+     int pid;
+{
+  static char buf[100];
+
+  sprintf (buf, "Thread %d", pid >> 16);
+
+  return buf;
+}
+\f
+struct target_ops hpux_thread_ops = {
+  "hpux-threads",              /* to_shortname */
+  "HPUX threads and pthread.", /* to_longname */
+  "HPUX threads and pthread support.", /* to_doc */
+  hpux_thread_open,            /* to_open */
+  0,                           /* to_close */
+  hpux_thread_attach,          /* to_attach */
+  hpux_thread_detach,          /* to_detach */
+  hpux_thread_resume,          /* to_resume */
+  hpux_thread_wait,            /* to_wait */
+  hpux_thread_fetch_registers, /* to_fetch_registers */
+  hpux_thread_store_registers, /* to_store_registers */
+  hpux_thread_prepare_to_store,        /* to_prepare_to_store */
+  hpux_thread_xfer_memory,     /* to_xfer_memory */
+  hpux_thread_files_info,      /* to_files_info */
+  memory_insert_breakpoint,    /* to_insert_breakpoint */
+  memory_remove_breakpoint,    /* to_remove_breakpoint */
+  terminal_init_inferior,      /* to_terminal_init */
+  terminal_inferior,           /* to_terminal_inferior */
+  terminal_ours_for_output,    /* to_terminal_ours_for_output */
+  terminal_ours,               /* to_terminal_ours */
+  child_terminal_info,         /* to_terminal_info */
+  hpux_thread_kill_inferior,   /* to_kill */
+  0,                           /* to_load */
+  0,                           /* to_lookup_symbol */
+  hpux_thread_create_inferior, /* to_create_inferior */
+  hpux_thread_mourn_inferior,  /* to_mourn_inferior */
+  hpux_thread_can_run,         /* to_can_run */
+  hpux_thread_notice_signals,  /* to_notice_signals */
+  hpux_thread_alive,           /* to_thread_alive */
+  hpux_thread_stop,            /* to_stop */
+  process_stratum,             /* to_stratum */
+  0,                           /* to_next */
+  1,                           /* to_has_all_memory */
+  1,                           /* to_has_memory */
+  1,                           /* to_has_stack */
+  1,                           /* to_has_registers */
+  1,                           /* to_has_execution */
+  0,                           /* sections */
+  0,                           /* sections_end */
+  OPS_MAGIC                    /* to_magic */
+};
+
+void
+_initialize_hpux_thread ()
+{
+  add_target (&hpux_thread_ops);
+
+  child_suppress_run = 1;
+}
diff --git a/gdb/osf-share/.Sanitize b/gdb/osf-share/.Sanitize
new file mode 100644 (file)
index 0000000..1a2c426
--- /dev/null
@@ -0,0 +1,61 @@
+# .Sanitize for devo/gdb/osf-share.
+
+# Each directory to survive its way into a release will need a file
+# like this one called "./.Sanitize".  All keyword lines must exist,
+# and must exist in the order specified by this file.  Each directory
+# in the tree will be processed, top down, in the following order.
+
+# Hash started lines like this one are comments and will be deleted
+# before anything else is done.  Blank lines will also be squashed
+# out.
+
+# The lines between the "Do-first:" line and the "Things-to-keep:"
+# line are executed as a /bin/sh shell script before anything else is
+# done in this directory.
+
+Do-first:
+
+# All files listed between the "Things-to-keep:" line and the
+# "Files-to-sed:" line will be kept.  All other files will be removed.
+# Directories listed in this section will have their own Sanitize
+# called.  Directories not listed will be removed in their entirety
+# with rm -rf.
+
+Things-to-keep:
+
+AT386
+HP800
+RIOS
+cma_attr.h
+cma_deb_core.h
+cma_debug_client.h
+cma_errors.h
+cma_handle.h
+cma_init.h
+cma_list.h
+cma_mutex.h
+cma_sched.h
+cma_semaphore_defs.h
+cma_sequence.h
+cma_stack.h
+cma_stack_int.h
+cma_tcb_defs.h
+cma_util.h
+
+# Things which are explicitly *not* kept, for now.
+
+Things-to-lose:
+
+Do-last:
+
+# Don't try to clean directories here, as the 'mv' command will fail.
+# Also, grep fails on NFS mounted directories.
+
+for i in * ; do
+       if test ! -d $i && (grep sanitize $i > /dev/null) ; then
+               echo '***' Some mentions of Sanitize are still left in $i! 1>&2
+       fi
+done
+
+#
+# End of file.
diff --git a/gdb/osf-share/AT386/.Sanitize b/gdb/osf-share/AT386/.Sanitize
new file mode 100644 (file)
index 0000000..2ef8e54
--- /dev/null
@@ -0,0 +1,44 @@
+# .Sanitize for devo/gdb/osf-share/AT386.
+
+# Each directory to survive its way into a release will need a file
+# like this one called "./.Sanitize".  All keyword lines must exist,
+# and must exist in the order specified by this file.  Each directory
+# in the tree will be processed, top down, in the following order.
+
+# Hash started lines like this one are comments and will be deleted
+# before anything else is done.  Blank lines will also be squashed
+# out.
+
+# The lines between the "Do-first:" line and the "Things-to-keep:"
+# line are executed as a /bin/sh shell script before anything else is
+# done in this directory.
+
+Do-first:
+
+# All files listed between the "Things-to-keep:" line and the
+# "Files-to-sed:" line will be kept.  All other files will be removed.
+# Directories listed in this section will have their own Sanitize
+# called.  Directories not listed will be removed in their entirety
+# with rm -rf.
+
+Things-to-keep:
+
+cma_thread_io.h
+
+# Things which are explicitly *not* kept, for now.
+
+Things-to-lose:
+
+Do-last:
+
+# Don't try to clean directories here, as the 'mv' command will fail.
+# Also, grep fails on NFS mounted directories.
+
+for i in * ; do
+       if test ! -d $i && (grep sanitize $i > /dev/null) ; then
+               echo '***' Some mentions of Sanitize are still left in $i! 1>&2
+       fi
+done
+
+#
+# End of file.
diff --git a/gdb/osf-share/AT386/cma_thread_io.h b/gdb/osf-share/AT386/cma_thread_io.h
new file mode 100644 (file)
index 0000000..a90dba1
--- /dev/null
@@ -0,0 +1,457 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for thread synchrounous I/O
+ */
+
+#ifndef CMA_THREAD_IO
+#define CMA_THREAD_IO
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma_config.h>
+#include <sys/file.h>
+#include <cma.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <cma_init.h>
+#include <cma_errors.h>
+
+/*
+ * CONSTANTS
+ */
+
+/*
+ * Define symbols which indicate whether to compile code for obsolete 
+ * "non-blocking mode" flags:  FNDELAY and FNBLOCK.  If the obsolete
+ * symbols are defined, and if their replacement symbols are defined 
+ * and are different or if they are undefined, then define a symbol
+ * that says to compile the code in; otherwise no code will be compiled
+ * for these obsolete symbols.
+ */
+#ifdef FNDELAY
+# ifdef O_NDELAY
+#  if O_NDELAY != FNDELAY
+#   define _CMA_FNDELAY_
+#  endif
+# else
+#  define _CMA_FNDELAY_
+# endif
+#endif
+
+#ifdef FNBLOCK
+# ifdef O_NONBLOCK
+#  if O_NONBLOCK != FNBLOCK
+#   define _CMA_FNBLOCK_
+#  endif
+# else
+#  define _CMA_FNBLOCK_
+# endif
+#endif
+
+
+extern cma_t_boolean cma_is_open(int);
+/*
+ * Maximum number of files (ie, max_fd+1)
+ */
+#define cma__c_mx_file FD_SETSIZE
+
+/*
+ * Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
+ */
+#define cma__c_nbpm    NFDBITS
+
+/*
+ * TYPE DEFINITIONS
+ */
+
+typedef enum CMA__T_IO_TYPE {
+    cma__c_io_read   = 0,
+    cma__c_io_write  = 1,
+    cma__c_io_except = 2
+    } cma__t_io_type;
+#define cma__c_max_io_type     2
+
+/*
+ * From our local <sys/types.h>:
+ *
+ *  typedef long    fd_mask;
+ *
+ *  typedef struct fd_set {
+ *          fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+ *  } fd_set;
+ *
+ */
+typedef fd_mask cma__t_mask;
+typedef fd_set  cma__t_file_mask;
+
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
+ */
+extern int     cma__g_mx_file;
+
+/*
+ * Number of submasks (ie "int" sized chunks) per file descriptor mask as
+ * determined by getdtablesize().
+ */
+extern int     cma__g_nspm;
+
+/*
+ * MACROS
+ */
+
+/*
+ * Define a constant for the errno value which indicates that the requested
+ * operation was not performed because it would block the process.
+ */
+# define cma__is_blocking(s) \
+    ((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
+     (s == EALREADY) || (s == EDEADLK))
+
+/*
+*      It is necessary to issue an I/O function, before calling cma__io_wait()
+*      in the following cases:
+*
+*              *       This file descriptor has been set non-blocking by CMA
+*              *       This file descriptor has been set non-blocking by the user.
+*/
+
+#define cma__issue_io_call(fd)                                 \
+       ( (cma__g_file[fd]->non_blocking) || \
+         (cma__g_file[fd]->user_fl.user_non_blocking) )
+
+
+#define cma__set_user_nonblocking(flags) \
+
+/*
+ * Determine if the file is open
+ */
+/*
+ * If the file gets closed while waiting for the mutex cma__g_file[rfd]
+ * gets set to null. This results in a crash if NDEBUG is set to 0 
+ * since cma__int_lock tries to dereference it to set the mutex ownership 
+ * after it gets the mutex. The following will still set the ownership
+ * in cma__int_lock so we'll set it back to noone if cma__g_file is null
+ * when we come back just in case it matters. It shouldn't since its no
+ * longer in use but..... 
+ * Callers of this should recheck cma__g_file after the reservation to
+ * make sure continueing makes sense.
+ */
+#define cma__fd_reserve(rfd)   \
+               { \
+               cma__t_int_mutex *__mutex__; \
+               __mutex__ = cma__g_file[rfd]->mutex; \
+               cma__int_lock (__mutex__); \
+               if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
+                       cma__int_unlock(__mutex__); \
+               }
+               
+
+/*
+ * Unreserve a file descriptor
+ */
+#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
+
+/*
+ * AND together two select file descriptor masks
+ */
+#define cma__fdm_and(target,a,b)                                       \
+       {                                                               \
+       int __i__ = cma__g_nspm;                                        \
+       while (__i__--)                                                 \
+           (target)->fds_bits[__i__] =                                 \
+               (a)->fds_bits[__i__] & (b)->fds_bits[__i__];            \
+       }
+
+/*
+ * Clear a bit in a select file descriptor mask
+ *
+ * FD_CLR(n, p)  :=  ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_clr_bit(n,p)  FD_CLR (n, p)
+
+/*
+ * Copy the contents of one file descriptor mask into another.  If the 
+ * destination operand is null, do nothing; if the source operand is null, 
+ * simply zero the destination.
+ */
+#define cma__fdm_copy(src,dst,nfds) {                                  \
+       if (dst)                                                        \
+           if (src) {                                                  \
+               cma__t_mask *__s__ = (cma__t_mask *)(src);              \
+               cma__t_mask *__d__ = (cma__t_mask *)(dst);              \
+               int __i__;                                              \
+               for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm)   \
+                   *__d__++ = *__s__++;                                \
+               }                                                       \
+           else                                                        \
+               cma__fdm_zero (dst);                                    \
+           }
+
+/*
+ * To increment count for each bit set in fd - mask
+ */
+#define cma__fdm_count_bits(map,count)                                 \
+       {                                                               \
+       int     __i__ = cma__g_nspm;                                    \
+       while (__i__--) {                                               \
+           cma__t_mask    __tm__;                                      \
+           __tm__ = (map)->fds_bits[__i__];                            \
+           while(__tm__) {                                             \
+               (count)++;                                              \
+               __tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
+               }                                                       \
+           }                                                           \
+       }
+
+/*
+ * Test if a bit is set in a select file descriptor mask
+ *
+ * FD_ISSET(n,p)  :=  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_is_set(n,p)   FD_ISSET (n, p)
+
+/*
+ * OR together two select file descriptor masks
+ */
+#define cma__fdm_or(target,a,b)                                                \
+       {                                                               \
+       int __i__ = cma__g_nspm;                                        \
+       while (__i__--)                                                 \
+           (target)->fds_bits[__i__] =                                 \
+               (a)->fds_bits[__i__] | (b)->fds_bits[__i__];            \
+       }
+
+/*
+ * Set a bit in a select file descriptor mask
+ * 
+ * FD_SET(n,p)  :=  ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_set_bit(n,p)  FD_SET (n, p)
+
+/*
+ * Clear a select file descriptor mask.
+ */
+#define cma__fdm_zero(n)                                               \
+       cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
+
+
+\f
+/*
+ * CMA "thread-synchronous" I/O read/write operations
+ */
+
+    /*
+     * Since all CMA "thread-synchronous" I/O (read or write) operations on 
+     * U*ix follow the exact same structure, the wrapper routines have been
+     * condensed into a macro.
+     *
+     * The steps performed are as follows:
+     * 1. Check that the file descriptor is a legitimate value.
+     * 2. Check that the entry in the CMA file "database" which corresponds to 
+     *     the file descriptor indicates that the "file" was "opened" by CMA.
+     *  3. Reserve the file, to serialized access to files.  This not only 
+     *     simplifies things, but also defends against non-reentrancy.
+     *  4. If the "file" is "set" for non-blocking I/O, check if we
+     *      have actually set the file non-blocking yet, and if not do so.
+     *     Then, issue the I/O operantion.
+     *     Success or failure is returned immediately, after unreserving the 
+     *     file.  If the error indicates that the operation would have caused
+     *     the process to block, continue to the next step.
+     * 5. The I/O prolog adds this "file" to the global bit mask, which 
+     *     represents all "files" which have threads waiting to perform I/O on 
+     *     them, and causes the thread to block on the condition variable for
+     *     this "file".  Periodically, a select is done on this global bit 
+     *     mask, and the condition variables corresponding to "files" which 
+     *     are ready for I/O are signaled, releasing those waiting threads to
+     *     perform their I/O.
+     *  6. When the thread returns from the I/O prolog, it can (hopefully) 
+     *     perform its operation without blocking the process.
+     * 7. The I/O epilog clears the bit in the global mask and/or signals the 
+     *     the next thread waiting for this "file", as appropriate.
+     *  8. If the I/O failed, continue to loop.
+     * 9. Finally, the "file" is unreserved, as we're done with it, and the
+     *     result of the operation is returned.
+     *
+     *
+     * Note:  currently, we believe that timeslicing which is based on the
+     *     virtual-time timer does not cause system calls to return EINTR.  
+     *     Threfore, any EINTR returns are relayed directly to the caller.
+     *     On platforms which do not support a virtual-time timer, the code
+     *     should probably catch EINTR returns and restart the system call.
+     */
+
+/*
+ * This macro is used for both read-type and write-type functions.
+ *
+ * Note:  the second call to "func" may require being bracketed in a
+ *       cma__interrupt_disable/cma__interrupt_enable pair, but we'll 
+ *       wait and see if this is necessary.
+ */
+#define cma__ts_func(func,fd,arglist,type,post_process)        { \
+    cma_t_integer   __res__; \
+    cma_t_boolean   __done__ = cma_c_false; \
+    if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
+    if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+    cma__fd_reserve (fd); \
+    if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+    if (cma__issue_io_call(fd)) {\
+       if ((!cma__g_file[fd]->set_non_blocking) && \
+               (cma__g_file[fd]->non_blocking == cma_c_true)) \
+           cma__set_nonblocking(fd); \
+        cma__interrupt_disable (0); \
+       TRY { \
+           __res__ = func arglist; \
+           } \
+       CATCH_ALL { \
+           cma__interrupt_enable (0); \
+           cma__fd_unreserve (fd); \
+           RERAISE; \
+           } \
+       ENDTRY \
+        cma__interrupt_enable (0); \
+       if ((__res__ != -1) \
+               || (!cma__is_blocking (errno)) \
+               || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+           __done__ = cma_c_true; \
+       } \
+    if (__done__) { \
+       cma__fd_unreserve (fd); \
+       } \
+    else { \
+       TRY { \
+           cma__io_prolog (type, fd); \
+           while (!__done__) { \
+               cma__io_wait (type, fd); \
+               __res__ = func arglist; \
+               if ((__res__ != -1) \
+                       || (!cma__is_blocking (errno)) \
+                       || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+                   __done__ = cma_c_true; \
+               } \
+           } \
+       FINALLY { \
+           cma__io_epilog (type, fd); \
+           cma__fd_unreserve (fd); \
+           } \
+       ENDTRY \
+       } \
+    if (__res__ != -1)  post_process; \
+    return __res__;  \
+    }
+
+    /*
+     * Since most CMA "thread-synchronous" I/O ("open"-type) operations on 
+     * U*ix follow the exact same structure, the wrapper routines have been
+     * condensed into a macro.
+     *
+     * The steps performed are as follows:
+     * 1. Issue the open function.
+     * 2. If the value returned indicates an error, return it to the caller.
+     *  3. If the file descriptor returned is larger than what we think is the
+     *     maximum value (ie if it is too big for our database) then bugcheck.
+     *  4. "Open" the "file" in the CMA file database.
+     * 5. Return the file descriptor value to the caller.
+     *
+     * FIX-ME: for the time being, if the I/O operation returns EINTR, we 
+     *     simply return it to the caller; eventually, we should catch this 
+     *     and "do the right thing" (if we can figure out what that is).
+     */
+
+/*
+ * This macro is used for all "open"-type functions which return a single file
+ * desciptor by immediate value.
+ */
+#define cma__ts_open(func,arglist,post_process)  {             \
+    int        __fd__;                                                 \
+    TRY {                                                      \
+       cma__int_init ();                                       \
+       cma__int_lock (cma__g_io_data_mutex);                   \
+       __fd__ = func arglist;                                  \
+       cma__int_unlock (cma__g_io_data_mutex);                 \
+       if (__fd__ >= 0 && __fd__ < cma__g_mx_file)             \
+           post_process;                                       \
+       }                                                       \
+    CATCH_ALL                                                  \
+       {                                                       \
+       cma__set_errno (EBADF);                                 \
+       __fd__ = -1;                                            \
+       }                                                       \
+    ENDTRY                                                     \
+    if (__fd__ >= cma__g_mx_file)                              \
+       cma__bugcheck ("cma__ts_open:  fd is too large");       \
+    return __fd__;                                             \
+    }
+/*
+ * This macro is used for all "open"-type functions which return a pair of file
+ * desciptors by reference parameter.
+ */
+#define cma__ts_open2(func,fdpair,arglist,post_process)  {             \
+    int            __res__;                                                    \
+    TRY {                                                              \
+       cma__int_init ();                                               \
+       cma__int_lock (cma__g_io_data_mutex);                           \
+       __res__ = func arglist;                                         \
+       cma__int_unlock (cma__g_io_data_mutex);                         \
+       if (__res__ >= 0 && fdpair[0] < cma__g_mx_file                  \
+               && fdpair[1] < cma__g_mx_file)                          \
+           post_process;                                               \
+       }                                                               \
+    CATCH_ALL                                                          \
+       {                                                               \
+       cma__set_errno (EBADF);                                         \
+       __res__ = -1;                                                   \
+       }                                                               \
+    ENDTRY                                                             \
+    if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
+       cma__bugcheck ("cma__ts_open2:  one of fd's is too large"); \
+    return __res__;                                                    \
+    }
+
+/*
+ * INTERNAL INTERFACES
+ */
+extern void cma__close_general (int);
+
+extern void cma__init_thread_io (void);
+
+extern cma_t_boolean cma__io_available (cma__t_io_type,int,struct timeval *);
+
+extern void cma__io_epilog (cma__t_io_type,int);
+
+extern void cma__io_prolog (cma__t_io_type,int);
+
+extern void cma__io_wait (cma__t_io_type,int);
+
+extern void cma__open_general (int);
+
+extern void cma__reinit_thread_io (int);
+
+extern void cma__set_nonblocking (int);
+
+extern void cma__set_user_nonblock_flags (int,int);
+
+extern cma_t_boolean cma__is_open (int);
+
+
+#endif
diff --git a/gdb/osf-share/HP800/.Sanitize b/gdb/osf-share/HP800/.Sanitize
new file mode 100644 (file)
index 0000000..17e1389
--- /dev/null
@@ -0,0 +1,44 @@
+# .Sanitize for devo/gdb/osf-share/HP800.
+
+# Each directory to survive its way into a release will need a file
+# like this one called "./.Sanitize".  All keyword lines must exist,
+# and must exist in the order specified by this file.  Each directory
+# in the tree will be processed, top down, in the following order.
+
+# Hash started lines like this one are comments and will be deleted
+# before anything else is done.  Blank lines will also be squashed
+# out.
+
+# The lines between the "Do-first:" line and the "Things-to-keep:"
+# line are executed as a /bin/sh shell script before anything else is
+# done in this directory.
+
+Do-first:
+
+# All files listed between the "Things-to-keep:" line and the
+# "Files-to-sed:" line will be kept.  All other files will be removed.
+# Directories listed in this section will have their own Sanitize
+# called.  Directories not listed will be removed in their entirety
+# with rm -rf.
+
+Things-to-keep:
+
+cma_thread_io.h
+
+# Things which are explicitly *not* kept, for now.
+
+Things-to-lose:
+
+Do-last:
+
+# Don't try to clean directories here, as the 'mv' command will fail.
+# Also, grep fails on NFS mounted directories.
+
+for i in * ; do
+       if test ! -d $i && (grep sanitize $i > /dev/null) ; then
+               echo '***' Some mentions of Sanitize are still left in $i! 1>&2
+       fi
+done
+
+#
+# End of file.
diff --git a/gdb/osf-share/HP800/cma_thread_io.h b/gdb/osf-share/HP800/cma_thread_io.h
new file mode 100644 (file)
index 0000000..e9bef3b
--- /dev/null
@@ -0,0 +1,432 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *
+ *     Header file for thread synchrounous I/O
+ */
+
+#ifndef CMA_THREAD_IO
+#define CMA_THREAD_IO
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma_config.h>
+#include <sys/file.h>
+#include <cma.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <cma_init.h>
+#include <cma_errors.h>
+
+/*
+ * CONSTANTS
+ */
+
+
+
+/*
+ * Maximum number of files (ie, max_fd+1)
+ */
+#define cma__c_mx_file FD_SETSIZE
+
+/*
+ * Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
+ */
+#define cma__c_nbpm    NFDBITS
+
+/*
+ * TYPE DEFINITIONS
+ */
+
+typedef enum CMA__T_IO_TYPE {
+    cma__c_io_read   = 0,
+    cma__c_io_write  = 1,
+    cma__c_io_except = 2
+    } cma__t_io_type;
+#define cma__c_max_io_type     2
+
+/*
+ * From our local <sys/types.h>:
+ *
+ *  typedef long    fd_mask;
+ *
+ *  typedef struct fd_set {
+ *          fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+ *  } fd_set;
+ *
+ */
+typedef fd_mask cma__t_mask;
+typedef fd_set  cma__t_file_mask;
+
+
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
+ */
+extern int     cma__g_mx_file;
+
+/*
+ * Number of submasks (ie "int" sized chunks) per file descriptor mask as
+ * determined by getdtablesize().
+ */
+extern int     cma__g_nspm;
+
+/*
+ * MACROS
+ */
+
+/*
+ * Define a constant for the errno value which indicates that the requested
+ * operation was not performed because it would block the process.
+ */
+# define cma__is_blocking(s) \
+    ((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
+     (s == EALREADY) || (s == EDEADLK))
+
+/*
+*      It is necessary to issue an I/O function, before calling cma__io_wait()
+*      in the following cases:
+*
+*              *       This file descriptor has been set non-blocking by CMA
+*              *       This file descriptor has been set non-blocking by the user.
+*/
+
+#define cma__issue_io_call(fd)                                 \
+       ( (cma__g_file[fd]->non_blocking) || \
+         (cma__g_file[fd]->user_fl.user_non_blocking) )
+
+
+#define cma__set_user_nonblocking(flags) \
+
+/*
+ * Determine if the file is open
+ */
+/*
+ * If the file gets closed while waiting for the mutex cma__g_file[rfd]
+ * gets set to null. This results in a crash if NDEBUG is set to 0 
+ * since cma__int_lock tries to dereference it to set the mutex ownership 
+ * after it gets the mutex. The following will still set the ownership
+ * in cma__int_lock so we'll set it back to noone if cma__g_file is null
+ * when we come back just in case it matters. It shouldn't since its no
+ * longer in use but..... 
+ * Callers of this should recheck cma__g_file after the reservation to
+ * make sure continueing makes sense.
+ */
+#define cma__fd_reserve(rfd)   \
+               { \
+               cma__t_int_mutex *__mutex__; \
+               __mutex__ = cma__g_file[rfd]->mutex; \
+               cma__int_lock (__mutex__); \
+               if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
+                       cma__int_unlock(__mutex__); \
+               }
+               
+
+/*
+ * Unreserve a file descriptor
+ */
+#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
+
+/*
+ * AND together two select file descriptor masks
+ */
+#define cma__fdm_and(target,a,b)                                       \
+       {                                                               \
+       int __i__ = cma__g_nspm;                                        \
+       while (__i__--)                                                 \
+           (target)->fds_bits[__i__] =                                 \
+               (a)->fds_bits[__i__] & (b)->fds_bits[__i__];            \
+       }
+
+/*
+ * Clear a bit in a select file descriptor mask
+ *
+ * FD_CLR(n, p)  :=  ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_clr_bit(n,p)  FD_CLR (n, p)
+
+/*
+ * Copy the contents of one file descriptor mask into another.  If the 
+ * destination operand is null, do nothing; if the source operand is null, 
+ * simply zero the destination.
+ */
+#define cma__fdm_copy(src,dst,nfds) {                                  \
+       if (dst)                                                        \
+           if (src) {                                                  \
+               cma__t_mask *__s__ = (cma__t_mask *)(src);              \
+               cma__t_mask *__d__ = (cma__t_mask *)(dst);              \
+               int __i__;                                              \
+               for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm)   \
+                   *__d__++ = *__s__++;                                \
+               }                                                       \
+           else                                                        \
+               cma__fdm_zero (dst);                                    \
+           }
+
+/*
+ * To increment count for each bit set in fd - mask
+ */
+#define cma__fdm_count_bits(map,count)                                 \
+       {                                                               \
+       int     __i__ = cma__g_nspm;                                    \
+       while (__i__--) {                                               \
+           cma__t_mask    __tm__;                                      \
+           __tm__ = (map)->fds_bits[__i__];                            \
+           while(__tm__) {                                             \
+               (count)++;                                              \
+               __tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
+               }                                                       \
+           }                                                           \
+       }
+
+/*
+ * Test if a bit is set in a select file descriptor mask
+ *
+ * FD_ISSET(n,p)  :=  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_is_set(n,p)   FD_ISSET (n, p)
+
+/*
+ * OR together two select file descriptor masks
+ */
+#define cma__fdm_or(target,a,b)                                                \
+       {                                                               \
+       int __i__ = cma__g_nspm;                                        \
+       while (__i__--)                                                 \
+           (target)->fds_bits[__i__] =                                 \
+               (a)->fds_bits[__i__] | (b)->fds_bits[__i__];            \
+       }
+
+/*
+ * Set a bit in a select file descriptor mask
+ * 
+ * FD_SET(n,p)  :=  ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_set_bit(n,p)  FD_SET (n, p)
+
+/*
+ * Clear a select file descriptor mask.
+ */
+#define cma__fdm_zero(n)                                               \
+       cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
+
+
+
+
+\f
+/*
+ * CMA "thread-synchronous" I/O read/write operations
+ */
+
+    /*
+     * Since all CMA "thread-synchronous" I/O (read or write) operations on 
+     * U*ix follow the exact same structure, the wrapper routines have been
+     * condensed into a macro.
+     *
+     * The steps performed are as follows:
+     * 1. Check that the file descriptor is a legitimate value.
+     * 2. Check that the entry in the CMA file "database" which corresponds to 
+     *     the file descriptor indicates that the "file" was "opened" by CMA.
+     *  3. Reserve the file, to serialized access to files.  This not only 
+     *     simplifies things, but also defends against non-reentrancy.
+     *  4. If the "file" is "set" for non-blocking I/O, check if we
+     *      have actually set the file non-blocking yet, and if not do so.
+     *     Then, issue the I/O operantion.
+     *     Success or failure is returned immediately, after unreserving the 
+     *     file.  If the error indicates that the operation would have caused
+     *     the process to block, continue to the next step.
+     * 5. The I/O prolog adds this "file" to the global bit mask, which 
+     *     represents all "files" which have threads waiting to perform I/O on 
+     *     them, and causes the thread to block on the condition variable for
+     *     this "file".  Periodically, a select is done on this global bit 
+     *     mask, and the condition variables corresponding to "files" which 
+     *     are ready for I/O are signaled, releasing those waiting threads to
+     *     perform their I/O.
+     *  6. When the thread returns from the I/O prolog, it can (hopefully) 
+     *     perform its operation without blocking the process.
+     * 7. The I/O epilog clears the bit in the global mask and/or signals the 
+     *     the next thread waiting for this "file", as appropriate.
+     *  8. If the I/O failed, continue to loop.
+     * 9. Finally, the "file" is unreserved, as we're done with it, and the
+     *     result of the operation is returned.
+     *
+     *
+     * Note:  currently, we believe that timeslicing which is based on the
+     *     virtual-time timer does not cause system calls to return EINTR.  
+     *     Threfore, any EINTR returns are relayed directly to the caller.
+     *     On platforms which do not support a virtual-time timer, the code
+     *     should probably catch EINTR returns and restart the system call.
+     */
+
+/*
+ * This macro is used for both read-type and write-type functions.
+ *
+ * Note:  the second call to "func" may require being bracketed in a
+ *       cma__interrupt_disable/cma__interrupt_enable pair, but we'll 
+ *       wait and see if this is necessary.
+ */
+#define cma__ts_func(func,fd,arglist,type,post_process)        { \
+    cma_t_integer   __res__; \
+    cma_t_boolean   __done__ = cma_c_false; \
+    if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
+    if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+    cma__fd_reserve (fd); \
+    if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+    if (cma__issue_io_call(fd)) {\
+       if ((!cma__g_file[fd]->set_non_blocking) && \
+               (cma__g_file[fd]->non_blocking == cma_c_true)) \
+           cma__set_nonblocking(fd); \
+        cma__interrupt_disable (0); \
+       TRY { \
+           __res__ = func arglist; \
+           } \
+       CATCH_ALL { \
+           cma__interrupt_enable (0); \
+           cma__fd_unreserve (fd); \
+           RERAISE; \
+           } \
+       ENDTRY \
+        cma__interrupt_enable (0); \
+       if ((__res__ != -1) \
+               || (!cma__is_blocking (errno)) \
+               || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+           __done__ = cma_c_true; \
+       } \
+    if (__done__) { \
+       cma__fd_unreserve (fd); \
+       } \
+    else { \
+       TRY { \
+           cma__io_prolog (type, fd); \
+           while (!__done__) { \
+               cma__io_wait (type, fd); \
+               __res__ = func arglist; \
+               if ((__res__ != -1) \
+                       || (!cma__is_blocking (errno)) \
+                       || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+                   __done__ = cma_c_true; \
+               } \
+           } \
+       FINALLY { \
+           cma__io_epilog (type, fd); \
+           cma__fd_unreserve (fd); \
+           } \
+       ENDTRY \
+       } \
+    if (__res__ != -1)  post_process; \
+    return __res__;  \
+    }
+
+    /*
+     * Since most CMA "thread-synchronous" I/O ("open"-type) operations on 
+     * U*ix follow the exact same structure, the wrapper routines have been
+     * condensed into a macro.
+     *
+     * The steps performed are as follows:
+     * 1. Issue the open function.
+     * 2. If the value returned indicates an error, return it to the caller.
+     *  3. If the file descriptor returned is larger than what we think is the
+     *     maximum value (ie if it is too big for our database) then bugcheck.
+     *  4. "Open" the "file" in the CMA file database.
+     * 5. Return the file descriptor value to the caller.
+     *
+     * FIX-ME: for the time being, if the I/O operation returns EINTR, we 
+     *     simply return it to the caller; eventually, we should catch this 
+     *     and "do the right thing" (if we can figure out what that is).
+     */
+
+/*
+ * This macro is used for all "open"-type functions which return a single file
+ * desciptor by immediate value.
+ */
+#define cma__ts_open(func,arglist,post_process)  {             \
+    int        __fd__;                                                 \
+    TRY {                                                      \
+       cma__int_init ();                                       \
+       cma__int_lock (cma__g_io_data_mutex);                   \
+       __fd__ = func arglist;                                  \
+       cma__int_unlock (cma__g_io_data_mutex);                 \
+       if (__fd__ >= 0 && __fd__ < cma__g_mx_file)             \
+           post_process;                                       \
+       }                                                       \
+    CATCH_ALL                                                  \
+       {                                                       \
+       cma__set_errno (EBADF);                                 \
+       __fd__ = -1;                                            \
+       }                                                       \
+    ENDTRY                                                     \
+    if (__fd__ >= cma__g_mx_file)                              \
+       cma__bugcheck ("cma__ts_open:  fd is too large");       \
+    return __fd__;                                             \
+    }
+/*
+ * This macro is used for all "open"-type functions which return a pair of file
+ * desciptors by reference parameter.
+ */
+#define cma__ts_open2(func,fdpair,arglist,post_process)  {             \
+    int            __res__;                                                    \
+    TRY {                                                              \
+       cma__int_init ();                                               \
+       cma__int_lock (cma__g_io_data_mutex);                           \
+       __res__ = func arglist;                                         \
+       cma__int_unlock (cma__g_io_data_mutex);                         \
+       if (__res__ >= 0 && fdpair[0] < cma__g_mx_file                  \
+               && fdpair[1] < cma__g_mx_file)                          \
+           post_process;                                               \
+       }                                                               \
+    CATCH_ALL                                                          \
+       {                                                               \
+       cma__set_errno (EBADF);                                         \
+       __res__ = -1;                                                   \
+       }                                                               \
+    ENDTRY                                                             \
+    if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
+       cma__bugcheck ("cma__ts_open2:  one of fd's is too large"); \
+    return __res__;                                                    \
+    }
+
+/*
+ * INTERNAL INTERFACES
+ */
+extern void cma__close_general  (int);
+
+extern void cma__init_thread_io  (void);
+
+extern cma_t_boolean cma__io_available  (cma__t_io_type,int,struct timeval *);
+
+extern void cma__io_epilog  (cma__t_io_type,int);
+
+extern void cma__io_prolog  (cma__t_io_type,int);
+
+extern void cma__io_wait  (cma__t_io_type,int);
+
+extern void cma__open_general  (int);
+
+extern void cma__reinit_thread_io  (int);
+
+extern void cma__set_nonblocking  (int);
+
+extern void cma__set_user_nonblock_flags  (int,int);
+
+extern cma_t_boolean cma__is_open (int);
+
+#endif
diff --git a/gdb/osf-share/README b/gdb/osf-share/README
new file mode 100644 (file)
index 0000000..c6d2e0f
--- /dev/null
@@ -0,0 +1,8 @@
+This directory contains header files necessary to build a thread-aware GDB on
+systems based on OSF's CMA threads package.
+
+The latest version of these header files are available for free from:
+
+       http://www.osf.org/mall/dce/SW-code
+
+Currently, the only port of GDB which supports CMA threads is HP/UX-10.10.
diff --git a/gdb/osf-share/RIOS/.Sanitize b/gdb/osf-share/RIOS/.Sanitize
new file mode 100644 (file)
index 0000000..3820304
--- /dev/null
@@ -0,0 +1,44 @@
+# .Sanitize for devo/gdb/osf-share/RIOS.
+
+# Each directory to survive its way into a release will need a file
+# like this one called "./.Sanitize".  All keyword lines must exist,
+# and must exist in the order specified by this file.  Each directory
+# in the tree will be processed, top down, in the following order.
+
+# Hash started lines like this one are comments and will be deleted
+# before anything else is done.  Blank lines will also be squashed
+# out.
+
+# The lines between the "Do-first:" line and the "Things-to-keep:"
+# line are executed as a /bin/sh shell script before anything else is
+# done in this directory.
+
+Do-first:
+
+# All files listed between the "Things-to-keep:" line and the
+# "Files-to-sed:" line will be kept.  All other files will be removed.
+# Directories listed in this section will have their own Sanitize
+# called.  Directories not listed will be removed in their entirety
+# with rm -rf.
+
+Things-to-keep:
+
+cma_thread_io.h
+
+# Things which are explicitly *not* kept, for now.
+
+Things-to-lose:
+
+Do-last:
+
+# Don't try to clean directories here, as the 'mv' command will fail.
+# Also, grep fails on NFS mounted directories.
+
+for i in * ; do
+       if test ! -d $i && (grep sanitize $i > /dev/null) ; then
+               echo '***' Some mentions of Sanitize are still left in $i! 1>&2
+       fi
+done
+
+#
+# End of file.
diff --git a/gdb/osf-share/RIOS/cma_thread_io.h b/gdb/osf-share/RIOS/cma_thread_io.h
new file mode 100644 (file)
index 0000000..98117ca
--- /dev/null
@@ -0,0 +1,434 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for thread synchrounous I/O
+ */
+
+#ifndef CMA_THREAD_IO
+#define CMA_THREAD_IO
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma_config.h>
+#include <sys/select.h>
+#include <cma.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <cma_init.h>
+#include <cma_errors.h>
+
+/*
+ * CONSTANTS
+ */
+
+/*
+ * Maximum number of files (ie, max_fd+1)
+ */
+#define cma__c_mx_file FD_SETSIZE
+
+/*
+ * Number of bits per file descriptor bit mask (ie number of bytes * bits/byte)
+ */
+#define cma__c_nbpm    NFDBITS
+
+/*
+ * TYPE DEFINITIONS
+ */
+
+typedef enum CMA__T_IO_TYPE {
+    cma__c_io_read   = 0,
+    cma__c_io_write  = 1,
+    cma__c_io_except = 2
+    } cma__t_io_type;
+#define cma__c_max_io_type     2
+
+/*
+ * From our local <sys/types.h>:
+ *
+ *  typedef long    fd_mask;
+ *
+ *  typedef struct fd_set {
+ *          fd_mask fds_bits[howmany(FD_SETSIZE, NFDBITS)];
+ *  } fd_set;
+ *
+ */
+typedef fd_mask cma__t_mask;
+typedef fd_set  cma__t_file_mask;
+
+
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * Maximum number of files (ie, max_fd+1) as determined by getdtablesize().
+ */
+extern int     cma__g_mx_file;
+
+/*
+ * Number of submasks (ie "int" sized chunks) per file descriptor mask as
+ * determined by getdtablesize().
+ */
+extern int     cma__g_nspm;
+
+/*
+ * MACROS
+ */
+
+/*
+ * Define a constant for the errno value which indicates that the requested
+ * operation was not performed because it would block the process.
+ */
+# define cma__is_blocking(s) \
+    ((s == EAGAIN) || (s == EWOULDBLOCK) || (s == EINPROGRESS) || \
+     (s == EALREADY) || (s == EDEADLK))
+
+/*
+*      It is necessary to issue an I/O function, before calling cma__io_wait()
+*      in the following cases:
+*
+*              *       This file descriptor has been set non-blocking by CMA
+*              *       This file descriptor has been set non-blocking by the user.
+*/
+
+#define cma__issue_io_call(fd)                                 \
+       ( (cma__g_file[fd]->non_blocking) || \
+         (cma__g_file[fd]->user_fl.user_non_blocking) )
+
+
+#define cma__set_user_nonblocking(flags) \
+
+/*
+ * Determine if the file is open
+ */
+/*
+ * If the file gets closed while waiting for the mutex cma__g_file[rfd]
+ * gets set to null. This results in a crash if NDEBUG is set to 0 
+ * since cma__int_lock tries to dereference it to set the mutex ownership 
+ * after it gets the mutex. The following will still set the ownership
+ * in cma__int_lock so we'll set it back to noone if cma__g_file is null
+ * when we come back just in case it matters. It shouldn't since its no
+ * longer in use but..... 
+ * Callers of this should recheck cma__g_file after the reservation to
+ * make sure continueing makes sense.
+ */
+#define cma__fd_reserve(rfd)   \
+               { \
+               cma__t_int_mutex *__mutex__; \
+               __mutex__ = cma__g_file[rfd]->mutex; \
+               cma__int_lock (__mutex__); \
+               if(cma__g_file[rfd] == (cma__t_file_obj *)cma_c_null_ptr) \
+                       cma__int_unlock(__mutex__); \
+               }
+               
+
+/*
+ * Unreserve a file descriptor
+ */
+#define cma__fd_unreserve(ufd) cma__int_unlock (cma__g_file[ufd]->mutex)
+
+/*
+ * AND together two select file descriptor masks
+ */
+#define cma__fdm_and(target,a,b)                                       \
+       {                                                               \
+       int __i__ = cma__g_nspm;                                        \
+       while (__i__--)                                                 \
+           (target)->fds_bits[__i__] =                                 \
+               (a)->fds_bits[__i__] & (b)->fds_bits[__i__];            \
+       }
+
+/*
+ * Clear a bit in a select file descriptor mask
+ *
+ * FD_CLR(n, p)  :=  ((p)->fds_bits[(n)/NFDBITS] &= ~(1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_clr_bit(n,p)  FD_CLR (n, p)
+
+/*
+ * Copy the contents of one file descriptor mask into another.  If the 
+ * destination operand is null, do nothing; if the source operand is null, 
+ * simply zero the destination.
+ */
+#define cma__fdm_copy(src,dst,nfds) {                                  \
+       if (dst)                                                        \
+           if (src) {                                                  \
+               cma__t_mask *__s__ = (cma__t_mask *)(src);              \
+               cma__t_mask *__d__ = (cma__t_mask *)(dst);              \
+               int __i__;                                              \
+               for (__i__ = 0; __i__ < (nfds); __i__ += cma__c_nbpm)   \
+                   *__d__++ = *__s__++;                                \
+               }                                                       \
+           else                                                        \
+               cma__fdm_zero (dst);                                    \
+           }
+
+/*
+ * To increment count for each bit set in fd - mask
+ */
+#define cma__fdm_count_bits(map,count)                                 \
+       {                                                               \
+       int     __i__ = cma__g_nspm;                                    \
+       while (__i__--) {                                               \
+           cma__t_mask    __tm__;                                      \
+           __tm__ = (map)->fds_bits[__i__];                            \
+           while(__tm__) {                                             \
+               (count)++;                                              \
+               __tm__ &= ~(__tm__ & (-__tm__)); /* Assumes 2's comp */ \
+               }                                                       \
+           }                                                           \
+       }
+
+/*
+ * Test if a bit is set in a select file descriptor mask
+ *
+ * FD_ISSET(n,p)  :=  ((p)->fds_bits[(n)/NFDBITS] & (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_is_set(n,p)   FD_ISSET (n, p)
+
+/*
+ * OR together two select file descriptor masks
+ */
+#define cma__fdm_or(target,a,b)                                                \
+       {                                                               \
+       int __i__ = cma__g_nspm;                                        \
+       while (__i__--)                                                 \
+           (target)->fds_bits[__i__] =                                 \
+               (a)->fds_bits[__i__] | (b)->fds_bits[__i__];            \
+       }
+
+/*
+ * Set a bit in a select file descriptor mask
+ * 
+ * FD_SET(n,p)  :=  ((p)->fds_bits[(n)/NFDBITS] |= (1 << ((n) % NFDBITS)))
+ */
+#define cma__fdm_set_bit(n,p)  FD_SET (n, p)
+
+/*
+ * Clear a select file descriptor mask.
+ */
+#define cma__fdm_zero(n)                                               \
+       cma__memset ((char *) n, 0, cma__g_nspm * sizeof(cma__t_mask))
+
+
+
+
+\f
+/*
+ * CMA "thread-synchronous" I/O read/write operations
+ */
+
+    /*
+     * Since all CMA "thread-synchronous" I/O (read or write) operations on 
+     * U*ix follow the exact same structure, the wrapper routines have been
+     * condensed into a macro.
+     *
+     * The steps performed are as follows:
+     * 1. Check that the file descriptor is a legitimate value.
+     * 2. Check that the entry in the CMA file "database" which corresponds to 
+     *     the file descriptor indicates that the "file" was "opened" by CMA.
+     *  3. Reserve the file, to serialized access to files.  This not only 
+     *     simplifies things, but also defends against non-reentrancy.
+     *  4. If the "file" is "set" for non-blocking I/O, check if we
+     *      have actually set the file non-blocking yet, and if not do so.
+     *     Then, issue the I/O operantion.
+     *     Success or failure is returned immediately, after unreserving the 
+     *     file.  If the error indicates that the operation would have caused
+     *     the process to block, continue to the next step.
+     * 5. The I/O prolog adds this "file" to the global bit mask, which 
+     *     represents all "files" which have threads waiting to perform I/O on 
+     *     them, and causes the thread to block on the condition variable for
+     *     this "file".  Periodically, a select is done on this global bit 
+     *     mask, and the condition variables corresponding to "files" which 
+     *     are ready for I/O are signaled, releasing those waiting threads to
+     *     perform their I/O.
+     *  6. When the thread returns from the I/O prolog, it can (hopefully) 
+     *     perform its operation without blocking the process.
+     * 7. The I/O epilog clears the bit in the global mask and/or signals the 
+     *     the next thread waiting for this "file", as appropriate.
+     *  8. If the I/O failed, continue to loop.
+     * 9. Finally, the "file" is unreserved, as we're done with it, and the
+     *     result of the operation is returned.
+     *
+     *
+     * Note:  currently, we believe that timeslicing which is based on the
+     *     virtual-time timer does not cause system calls to return EINTR.  
+     *     Threfore, any EINTR returns are relayed directly to the caller.
+     *     On platforms which do not support a virtual-time timer, the code
+     *     should probably catch EINTR returns and restart the system call.
+     */
+
+/*
+ * This macro is used for both read-type and write-type functions.
+ *
+ * Note:  the second call to "func" may require being bracketed in a
+ *       cma__interrupt_disable/cma__interrupt_enable pair, but we'll 
+ *       wait and see if this is necessary.
+ */
+#define cma__ts_func(func,fd,arglist,type,post_process)        { \
+    cma_t_integer   __res__; \
+    cma_t_boolean   __done__ = cma_c_false; \
+    if ((fd < 0) || (fd >= cma__g_mx_file)) return (cma__set_errno (EBADF), -1); \
+    if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+    cma__fd_reserve (fd); \
+    if (!cma__is_open(fd)) return (cma__set_errno (EBADF), -1); \
+    if (cma__issue_io_call(fd)) {\
+       if ((!cma__g_file[fd]->set_non_blocking) && \
+               (cma__g_file[fd]->non_blocking == cma_c_true)) \
+           cma__set_nonblocking(fd); \
+        cma__interrupt_disable (0); \
+       TRY { \
+           __res__ = func arglist; \
+           } \
+       CATCH_ALL { \
+           cma__interrupt_enable (0); \
+           cma__fd_unreserve (fd); \
+           RERAISE; \
+           } \
+       ENDTRY \
+        cma__interrupt_enable (0); \
+       if ((__res__ != -1) \
+               || (!cma__is_blocking (errno)) \
+               || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+           __done__ = cma_c_true; \
+       } \
+    if (__done__) { \
+       cma__fd_unreserve (fd); \
+       } \
+    else { \
+       TRY { \
+           cma__io_prolog (type, fd); \
+           while (!__done__) { \
+               cma__io_wait (type, fd); \
+               __res__ = func arglist; \
+               if ((__res__ != -1) \
+                       || (!cma__is_blocking (errno)) \
+                       || (cma__g_file[fd]->user_fl.user_non_blocking)) \
+                   __done__ = cma_c_true; \
+               } \
+           } \
+       FINALLY { \
+           cma__io_epilog (type, fd); \
+           cma__fd_unreserve (fd); \
+           } \
+       ENDTRY \
+       } \
+    if (__res__ != -1)  post_process; \
+    return __res__;  \
+    }
+
+    /*
+     * Since most CMA "thread-synchronous" I/O ("open"-type) operations on 
+     * U*ix follow the exact same structure, the wrapper routines have been
+     * condensed into a macro.
+     *
+     * The steps performed are as follows:
+     * 1. Issue the open function.
+     * 2. If the value returned indicates an error, return it to the caller.
+     *  3. If the file descriptor returned is larger than what we think is the
+     *     maximum value (ie if it is too big for our database) then bugcheck.
+     *  4. "Open" the "file" in the CMA file database.
+     * 5. Return the file descriptor value to the caller.
+     *
+     * FIX-ME: for the time being, if the I/O operation returns EINTR, we 
+     *     simply return it to the caller; eventually, we should catch this 
+     *     and "do the right thing" (if we can figure out what that is).
+     */
+
+/*
+ * This macro is used for all "open"-type functions which return a single file
+ * desciptor by immediate value.
+ */
+#define cma__ts_open(func,arglist,post_process)  {             \
+    int        __fd__;                                                 \
+    TRY {                                                      \
+       cma__int_init ();                                       \
+       cma__int_lock (cma__g_io_data_mutex);                   \
+       __fd__ = func arglist;                                  \
+       cma__int_unlock (cma__g_io_data_mutex);                 \
+       if (__fd__ >= 0 && __fd__ < cma__g_mx_file)             \
+           post_process;                                       \
+       }                                                       \
+    CATCH_ALL                                                  \
+       {                                                       \
+       cma__set_errno (EBADF);                                 \
+       __fd__ = -1;                                            \
+       }                                                       \
+    ENDTRY                                                     \
+    if (__fd__ >= cma__g_mx_file)                              \
+       cma__bugcheck ("cma__ts_open:  fd is too large");       \
+    return __fd__;                                             \
+    }
+/*
+ * This macro is used for all "open"-type functions which return a pair of file
+ * desciptors by reference parameter.
+ */
+#define cma__ts_open2(func,fdpair,arglist,post_process)  {             \
+    int            __res__;                                                    \
+    TRY {                                                              \
+       cma__int_init ();                                               \
+       cma__int_lock (cma__g_io_data_mutex);                           \
+       __res__ = func arglist;                                         \
+       cma__int_unlock (cma__g_io_data_mutex);                         \
+       if (__res__ >= 0 && fdpair[0] < cma__g_mx_file                  \
+               && fdpair[1] < cma__g_mx_file)                          \
+           post_process;                                               \
+       }                                                               \
+    CATCH_ALL                                                          \
+       {                                                               \
+       cma__set_errno (EBADF);                                         \
+       __res__ = -1;                                                   \
+       }                                                               \
+    ENDTRY                                                             \
+    if ((fdpair[0] >= cma__g_mx_file) || (fdpair[1] >= cma__g_mx_file)) \
+       cma__bugcheck ("cma__ts_open2:  one of fd's is too large"); \
+    return __res__;                                                    \
+    }
+
+/*
+ * INTERNAL INTERFACES
+ */
+extern void cma__close_general (int);
+
+extern void
+cma__init_thread_io (void);
+
+extern cma_t_boolean cma__io_available  (cma__t_io_type,int,struct timeval *);
+
+extern void cma__io_epilog  (cma__t_io_type,int);
+
+extern void cma__io_prolog  (cma__t_io_type,int);
+
+extern void cma__io_wait  (cma__t_io_type,int);
+
+extern void cma__open_general  (int);
+
+extern void cma__reinit_thread_io  (int);
+
+extern void cma__set_nonblocking  (int);
+
+extern void cma__set_user_nonblock_flags  (int,int);
+
+extern cma_t_boolean
+cma__is_open (int fd);
+
+
+#endif
+
+
diff --git a/gdb/osf-share/cma_attr.h b/gdb/osf-share/cma_attr.h
new file mode 100644 (file)
index 0000000..389fd6f
--- /dev/null
@@ -0,0 +1,341 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for attributes object
+ */
+
+#ifndef CMA_ATTR
+#define CMA_ATTR
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma_defs.h>
+#include <cma_queue.h>
+#ifdef __hpux
+# include <sys/param.h>
+#endif
+#if _CMA_UNIX_TYPE == _CMA__SVR4
+#include <sys/unistd.h>
+#endif
+/*
+ * CONSTANTS AND MACROS
+ */
+
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     cma__int_attr_get_priority -  Performs the work of cma_attr_get_priority
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *     cma_t_attr          *_att_      - Attribute object to get from
+ *     cma_t_priority      *_setting_  - Current setting
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     priority
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     none
+ */
+#define cma__int_attr_get_priority(_att_,_setting_) { \
+    cma__t_int_attr     *_int_att_; \
+    (_int_att_) = cma__validate_default_attr (_att_); \
+    cma__int_lock ((_int_att_)->mutex); \
+    (*(_setting_)) = (_int_att_)->priority; \
+    cma__int_unlock ((_int_att_)->mutex); \
+    }
+
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     cma__int_attr_get_sched - Performs work of cma_attr_get_sched
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *     cma_t_attr          *_att_      _ Attributes object used
+ *     cma_t_sched_policy  *_setting_  - Current setting
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     scheduling policy
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     none
+ */
+#define cma__int_attr_get_sched(_att_,_setting_) { \
+    cma__t_int_attr     *_int_att_; \
+    (_int_att_) = cma__validate_default_attr (_att_); \
+    cma__int_lock ((_int_att_)->mutex); \
+    (*(_setting_)) = (_int_att_)->policy; \
+    cma__int_unlock ((_int_att_)->mutex); \
+    }
+
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     cma__int_attr_get_inherit_sched - Performs work of 
+ *     cma_attr_get_inherit_sched
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *     cma_t_attr          *_att_      - Attributes object to use
+ *     cma_t_sched_inherit *_setting_  - Current setting
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     Inheritable scheduling policy
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     none
+ */
+#define cma__int_attr_get_inherit_sched(_att_,_setting_) { \
+    cma__t_int_attr    *_int_att_; \
+    (_int_att_) = cma__validate_default_attr (_att_); \
+    cma__int_lock ((_int_att_)->mutex); \
+    (*(_setting_)) \
+        = ((_int_att_)->inherit_sched ? cma_c_sched_inherit : cma_c_sched_use_default); \
+    cma__int_unlock ((_int_att_)->mutex); \
+    }
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     cma__int_attr_set_stacksize - Performs work for cma_attr_set_stacksize
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *      cma_t_attr          *_att_      - Attributes object to use
+ *     cma_t_natural       _setting_   - Setting
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     none
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     Change attribute objects stack size setting
+ */
+#define cma__int_attr_set_stacksize(_att_,_setting_) { \
+    cma__t_int_attr     *_int_att_; \
+    if ((_setting_) <= 0) \
+        cma__error (cma_s_badparam); \
+    _int_att_ = cma__validate_attr (_att_); \
+    cma__int_lock ((_int_att_)->mutex); \
+    _int_att_->stack_size = cma__roundup_chunksize(_setting_); \
+    cma__free_cache (_int_att_, cma__c_obj_tcb); \
+    _int_att_->cache[cma__c_obj_tcb].revision++; \
+    _int_att_->cache[cma__c_obj_stack].revision++; \
+    cma__int_unlock (_int_att_->mutex); \
+    }
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     cma__int_attr_get_stacksize - Performs work of cma_attr_get_stacksize
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *      cma_t_attr          *_att_      - Attributes object to use
+ *     cma_t_natural       *_setting_  - Current setting
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     Attribute objects stack size setting
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     none
+ */
+#define cma__int_attr_get_stacksize(_att_,_setting_) { \
+    cma__t_int_attr     *_int_att_; \
+    (_int_att_) = cma__validate_default_attr (_att_); \
+    cma__int_lock ((_int_att_)->mutex); \
+    (*(_setting_)) = (_int_att_)->stack_size; \
+    cma__int_unlock ((_int_att_)->mutex); \
+    }
+
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     cma__int_attr_set_guardsize - Performs work for cma_attr_set_guardsize
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *      cma_t_attr          *_att_      - Attributes object to use
+ *     cma_t_natural       _setting_   - Setting
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     none
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     Change attribute objects guard size setting
+ */
+#define cma__int_attr_set_guardsize(_att_,_setting_) { \
+    cma__t_int_attr     *_int_att_; \
+    _int_att_ = cma__validate_attr (_att_); \
+    cma__int_lock ((_int_att_)->mutex); \
+    _int_att_->guard_size = cma__roundup_chunksize(_setting_); \
+    cma__free_cache (_int_att_, cma__c_obj_tcb); \
+    _int_att_->cache[cma__c_obj_tcb].revision++; \
+    _int_att_->cache[cma__c_obj_stack].revision++; \
+    cma__int_unlock (_int_att_->mutex); \
+    }
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     cma__int_attr_get_guardsize - Performs work of cma_attr_get_guardsize
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *      cma_t_attr          *_att_      - Attributes object to use
+ *     cma_t_natural       *_setting_  - Current setting
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     Attribute objects guard size setting
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     none
+ */
+#define cma__int_attr_get_guardsize(_att_,_setting_) { \
+    cma__t_int_attr     *_int_att_; \
+    (_int_att_) = cma__validate_default_attr (_att_); \
+    cma__int_lock ((_int_att_)->mutex); \
+    (*(_setting_)) = (_int_att_)->guard_size; \
+    cma__int_unlock ((_int_att_)->mutex); \
+    }
+
+/*
+ * TYPEDEFS
+ */
+#ifndef __STDC__
+struct CMA__T_INT_MUTEX;               /* Avoid circular dependency */
+#endif
+
+typedef struct CMA__T_CACHE {
+    cma_t_natural              revision;       /* Revisions */
+    cma_t_natural              count;
+    cma__t_queue               queue;  /* Cache headers */
+    } cma__t_cache;
+
+typedef struct CMA__T_INT_ATTR {
+    cma__t_object              header;         /* Common header */
+    struct CMA__T_INT_ATTR     *attributes;    /* Point to controlling attr */
+    struct CMA__T_INT_MUTEX    *mutex;         /* Serialize access to object */
+    cma_t_priority             priority;       /* Priority of new thread */
+    cma_t_sched_policy         policy;         /* Sched policy of thread */
+    cma_t_boolean              inherit_sched;  /* Is scheduling inherited? */
+    cma_t_natural              stack_size;     /* Size of stack (bytes) */
+    cma_t_natural              guard_size;     /* Size of guard (bytes) */
+    cma_t_mutex_kind           mutex_kind;     /* Mutex kind */
+    cma__t_cache               cache[cma__c_obj_num];  /* Cache information */
+    cma_t_boolean              delete_pending; /* attr. obj. is deleted */
+    cma_t_natural              refcnt; /* Number of objects using attr. obj */
+    } cma__t_int_attr;
+
+/*
+ *  GLOBAL DATA
+ */
+
+extern cma__t_int_attr cma__g_def_attr;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__destroy_attributes  (cma__t_int_attr *);
+
+extern void cma__free_attributes  (cma__t_int_attr     *);
+
+extern void cma__free_cache  (cma__t_int_attr *,cma_t_natural );
+
+extern cma__t_int_attr *cma__get_attributes  (cma__t_int_attr  *);
+
+extern void cma__init_attr  (void);
+
+extern void cma__reinit_attr  (cma_t_integer);
+
+#endif
diff --git a/gdb/osf-share/cma_deb_core.h b/gdb/osf-share/cma_deb_core.h
new file mode 100644 (file)
index 0000000..f0a9c34
--- /dev/null
@@ -0,0 +1,164 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     This file defines the internal interface to the core of CMA 
+ *     debugging services. (The client interface to debugging services
+ *     is provided by cma_debug_client.h).
+ */
+
+#ifndef CMA_DEB_CORE
+#define CMA_DEB_CORE
+
+/*
+ *  INCLUDE FILES
+ */
+#include <cma.h>
+#include <cma_mutex.h>
+#include <cma_queue.h>
+#include <cma_tcb_defs.h>
+#include <cma_util.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+
+/*
+ * TYPEDEFS
+ */
+
+/*FIX-ME* Need to use sizes that are platform specific */
+typedef long int cma___t_debug_ctx[17];
+
+/*
+ * Type defing the format of known object lists
+ */
+typedef struct CMA__T_KNOWN_OBJECT {
+    cma__t_queue       queue;          /* Queue header for known objects */
+    cma__t_int_mutex   *mutex;         /* Mutex to control access to queue */
+    } cma__t_known_object;
+
+
+/*
+ * Type defining the registration for one debug client (e.g. Ada)
+ */
+typedef struct CMA__T_DEB_REGISTRY {
+    cma_t_address      entry;          /* Client's debug entry point */
+    cma_t_key          key;            /* Client's context key */
+    cma_t_integer      fac;            /* Client's debug facility number */
+    cma_t_boolean      has_prolog;     /* Client's TCBs have std prolog */
+    } cma__t_deb_registry;
+
+#define cma__c_deb_max_clients 10
+
+/* 
+ * Type defining the global debugging state for all threads.
+ */
+typedef struct CMA__T_DEBUG_STATE {
+    /* 
+     * The following flag is set if changes were made while in the
+     * debugger that may make the ready lists inconsistent.  For 
+     * example, if a thread priority is changed in the debugger, the
+     * thread is not moved between queues.  Making things consistent
+     * is deferred to when the dispatcher is next invoked -- which we
+     * try to make very soon.
+     */
+    cma_t_boolean      is_inconsistency;   /* Ready lists are inconsistent */
+
+
+    cma_t_boolean      events_enabled;     /* Set if _any_ event is enabled */
+    cma_t_boolean      flags[cma__c_debevt__dim];      
+                                           /* Which events are enabled */
+    cma__t_int_tcb     *next_to_run;       /* TCB of thread to run next */ 
+
+    cma__t_int_mutex   *mutex;             /* Mutex for registering clients */
+    cma_t_integer      client_count;       /* Count of debug clients */
+    cma__t_deb_registry        clients[cma__c_deb_max_clients+1];
+                                           /* Array of current debug clients */
+    } cma__t_debug_state;
+
+
+/* 
+ * Routine that will symbolize and address and print it.
+ */
+typedef void   (*cma__t_print_symbol) (cma_t_address);
+
+
+/*
+ *  GLOBAL DATA
+ */
+
+/* 
+ * Variable holding the global debugging state 
+ *
+ * (This is primarily written by the debugger interface and read
+ * by the thread dispatcher).
+ */
+extern cma__t_debug_state      cma__g_debug_state;
+
+/* 
+ * Known object queues
+ */
+extern cma__t_known_object     cma__g_known_atts;
+extern cma__t_known_object     cma__g_known_cvs;
+extern cma__t_known_object     cma__g_known_mutexes;
+extern cma__t_known_object     cma__g_known_threads;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+/* Get information while in debugger context */
+extern void cma__deb_get 
+           (cma__t_int_tcb *,cma_t_debug_get,cma_t_address,cma_t_integer,cma_t_integer);
+
+/* Set information while in debugger context */
+extern void cma__deb_set (cma__t_int_tcb *,cma_t_debug_set,cma_t_address,cma_t_integer);
+
+extern void cma__init_debug (void);
+
+extern void cma__reinit_debug (cma_t_integer);
+
+extern void cma__deb_anytcb_to_tcb (cma_t_tcb_header *,cma__t_int_tcb **);
+
+extern void cma__deb_fac_to_client (cma_t_integer,cma_t_key *);
+
+extern void cma__deb_get_client_info (cma_t_key,cma_t_address *,cma_t_boolean *);
+
+extern void cma__deb_get_context (cma__t_int_tcb *,cma_t_key,cma_t_address *);
+
+extern cma__t_int_tcb *cma__deb_get_self_tcb (void);
+
+extern void cma__deb_get_time_slice (cma_t_interval *);
+
+extern cma__t_int_tcb *cma__deb_next_tcb 
+            (cma__t_int_tcb *,cma_t_integer *,cma_t_integer *,cma_t_boolean *);
+
+extern cma_t_boolean cma__deb_set_alert (cma__t_int_tcb *);
+
+extern void cma__deb_set_next_thread (cma__t_int_tcb *);
+       
+extern void cma__deb_set_force_dispatch (cma_t_address );
+
+extern void cma__deb_set_time_slice (cma_t_interval);
+
+extern void cma__deb_show_thread 
+     (cma__t_int_tcb *,cma_t_boolean,cma_t_boolean,cma___t_debug_ctx,cma__t_eol_routine,
+                cma__t_eol_routine,cma__t_print_symbol);
+
+extern void
+cma__deb_show_stats (cma__t_int_tcb *,cma_t_boolean,cma_t_boolean,cma__t_eol_routine,cma__t_eol_routine,cma__t_print_symbol);
+#endif
diff --git a/gdb/osf-share/cma_debug_client.h b/gdb/osf-share/cma_debug_client.h
new file mode 100644 (file)
index 0000000..adb0909
--- /dev/null
@@ -0,0 +1,195 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file providing access to CMA clients that implement
+ *     language run-times to the CMA debugger capabilities.
+ *
+ *     NOTE: the clients that are able to use this interface is
+ *     very limited because clients needing task debugging must have 
+ *     support in the system debugger as well as here (at present).
+ *     The following are the only legitimate clients of this interface:
+ *     ADA runtime, C++ tasking library, and CMA.
+ *
+ *FIX-ME* We shall endeavor to extend these capabilities so that the
+ *     all-platform CMA debugger CMA_DEBUG and any client can layer
+ *     on thread debugging.  But that is still an open design problem.
+ *     The design here does not preclude that extension (for example,
+ *     the identity of the debug-client is indicated in an "open"
+ *     manner by using the CMA context key as the identifier.
+ */
+
+#ifndef CMA_DEBUG_CLIENT
+#define CMA_DEBUG_CLIENT
+
+/*
+ *  INCLUDE FILES
+ */
+#include <cma.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * Type describing constants for a valid TCB sentinel.
+ * Exactly one value is valid, but we provide a symbolic name for
+ * at least one invalid sentinel as a convenience.
+ */
+typedef enum CMA_T_TCB_SENTINEL {
+       cma_c_tcb_sentinel_nogood = 0,  /* Invalid sentinel constant */
+       cma_c_tcb_sentinel = 0x0ACEFACE /* Valid TCB sentinel */
+       } cma_t_tcb_sentinel;
+
+/*
+ * Type describing pad fields needed to align the "standard prolog"
+ * to the right byte at the front of each TCB.  These fields are
+ * free to be put to any use by the client.
+ *
+ * This is 32 bytes long and is fixed at this size for all clients
+ * and CMA, for all time.
+ */
+typedef struct CMA_T_TCB_PRIVATE {
+    cma_t_integer      pad1;           
+    cma_t_integer      pad2;   
+    cma_t_integer      pad3;
+    cma_t_integer      pad4;
+    cma_t_integer      pad5;
+    cma_t_integer      pad6;
+    cma_t_integer      pad7;
+    cma_t_integer      pad8;
+    } cma_t_tcb_private;
+
+/*
+ * Type describing the "standard prolog" that clients should use 
+ * within their task control blocks.  We assume that the client will
+ * store their "task control block" as a per-thread context under
+ * the context key specified here.
+ */
+typedef struct CMA_T_TCB_PROLOG {
+    cma_t_tcb_sentinel sentinel;       /* Validity sentinel */
+    cma_t_thread       client_thread;  /* Thread corresonding to task */
+    cma_t_key          client_key;     /* Context key this is stored under */
+    cma_t_address      reserved1;      /* Must be zero, reserved to CMA */
+    } cma_t_tcb_prolog;
+
+/*
+ * Type defining the layout of all TCBs and TASKS.  This format
+ * ensures that tasks will be self-identifying to the debugger.
+ * this layout must never change as the CMA DEBUG Clients cannot
+ * be changed after CMA ships.
+ */
+typedef struct CMA_T_TCB_HEADER {
+    cma_t_tcb_private  IGNORED;        /* TCB fields private to the client */
+    cma_t_tcb_prolog   prolog;         /* The standard prolog goes here */
+    } cma_t_tcb_header;
+
+
+/*
+ * Type describing the kinds of information that a CMA debug
+ * client can GET about a thread.
+ */
+typedef enum CMA_T_DEBUG_GET {
+       /* 
+        * All of the following items use a buffer whose size is
+        * four bytes.  (That is four must be passed as the buffer_size
+        * parameter to cma_debug_get.)
+        */
+       cma_c_debget_guardsize = 1,     /* Current guard size (bytes) */
+       cma_c_debget_is_held = 2,       /* Is it on hold? */
+       cma_c_debget_is_initial = 3,    /* Is it the initial thread? */
+       cma_c_debget_number = 4,        /* Thread's number */
+       cma_c_debget_stack_ptr = 5,     /* Current stack pointer */
+       cma_c_debget_stack_base = 6,    /* Stack base address */
+       cma_c_debget_stack_top  = 7,    /* Stack top address */
+       cma_c_debget_sched_state = 8,   /* Scheduler state 
+                                        *      0 - run
+                                        *      1 - ready
+                                        *      2 - blocked
+                                        *      3 - terminated
+                                        */
+       cma_c_debget_reserve_size = 9,  /* Size of stack reserve (bytes) */
+       cma_c_debget_base_prio = 10,    /* Base priority */
+       cma_c_debget_priority = 11,     /* Current priority */
+       cma_c_debget_regs = 12,         /* Register set (and proc. state) */
+       cma_c_debget_alt_pending = 13,  /* Alert is pending */
+       cma_c_debget_alt_a_enable = 14, /* Asynch alert delivery enabled */
+       cma_c_debget_alt_g_enable = 15, /* General alert delivery enabled */
+       cma_c_debget_substate = 16,     /* Substate (or wait state) */
+       cma_c_debget_object_addr = 17,  /* Address of thread object */
+       cma_c_debget_thkind = 18,       /* Kind of thread */
+       cma_c_debget_detached   = 19,   /* Thread is detached */
+       cma_c_debget_tcb_size   = 20,   /* TCB size */
+       cma_c_debget_start_pc   = 21,   /* Start address */
+       cma_c_debget_next_pc    = 22,   /* Next instruction */
+       cma_c_debget_policy     = 23,   /* Sched policy */
+       cma_c_debget_stack_yellow = 24, /* Addr of start of guard area */
+       cma_c_debget_stack_default = 25 /* True if on default stack */
+
+       } cma_t_debug_get;
+
+/*
+ * Type describing the kinds of information that a CMA debug
+ * client can SET (or change) about a thread using cma_debug_set.
+ */
+typedef enum CMA_T_DEBUG_SET {
+       /* 
+        * All of the following items use a buffer whose size is
+        * four bytes.  (That is four must be passed as the buffer_size
+        * parameter to cma_debug_set.)
+        */
+       cma_c_debset_priority   = 1,    /* Set the priority */
+       cma_c_debset_policy     = 2,    /* Set the sched policy */
+       cma_c_debset_hold       = 3,    /* Put thread on hold */
+       cma_c_debset_regs       = 4     /* Set the regs and proc. state */
+
+       } cma_t_debug_set;
+
+
+/*
+ *  GLOBAL DATA
+ * 
+ *     none
+ */
+
+/*
+ * EXTERNAL INTERFACES
+ */
+
+/* 
+ * Routine to register with the CMA debug dispatcher.
+ */
+extern void     cma_debug_register (cma_t_address,cma_t_key,cma_t_integer,cma_t_boolean);
+
+/* 
+ * Routine to get get thread state needed by the CMA debug client.
+ */
+extern void     cma_debug_get (cma_t_thread *,cma_t_debug_get,cma_t_address,cma_t_integer);
+
+/* 
+ * Get thread context given an sp and a key 
+ */
+extern void cma_debug_get_sp_context    (cma_t_address,cma_t_key,cma_t_address *);
+
+/* 
+ * Routine to set thread state as needed by the CMA debug client.
+ */
+extern void     cma_debug_set (cma_t_thread *,cma_t_debug_set,cma_t_address,cma_t_integer);
+
+#endif
diff --git a/gdb/osf-share/cma_errors.h b/gdb/osf-share/cma_errors.h
new file mode 100644 (file)
index 0000000..8ac1795
--- /dev/null
@@ -0,0 +1,55 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     This module is the interface between CMA services and 
+ *     the platform-specific error reporting mechanism.
+ */
+
+#ifndef CMA_ERRORS
+#define CMA_ERRORS
+
+/*
+ *  INCLUDE FILES
+ */
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+/*
+ * The cma__bugcheck function will print information to stderr (or sys$error
+ * on VMS), and more extensive information to the file cma_dump.log in the
+ * current working directory.
+ */
+extern void cma__bugcheck  (char *,...);
+
+extern void cma__error  (int);
+
+extern void cma__unimplemented (void);
+
+#endif
diff --git a/gdb/osf-share/cma_handle.h b/gdb/osf-share/cma_handle.h
new file mode 100644 (file)
index 0000000..e63de01
--- /dev/null
@@ -0,0 +1,182 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for handles
+ */
+
+#ifndef CMA_HANDLE
+#define CMA_HANDLE
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma_defs.h>
+#include <cma_attr.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__validate_attr(handle) \
+    ((cma__t_int_attr *)cma__validate_handle ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_attr))
+
+#define cma__validate_cv(handle) \
+    ((cma__t_int_cv *)cma__validate_handle ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_cv))
+
+#define cma__validate_mutex(handle) \
+    ((cma__t_int_mutex *)cma__validate_handle ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_mutex))
+
+#define cma__validate_tcb(handle) \
+    ((cma__t_int_tcb *)cma__validate_handle ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_tcb))
+
+#define cma__validate_stack(handle) \
+    ((cma__t_int_stack *)cma__validate_handle ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_stack))
+
+#define cma__validate_null_attr(handle) \
+    ((cma__t_int_attr *)cma__validate_handle_null ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_attr))
+
+#define cma__validate_null_cv(handle) \
+    ((cma__t_int_cv *)cma__validate_handle_null ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_cv))
+
+#define cma__validate_null_mutex(handle) \
+    ((cma__t_int_mutex *)cma__validate_handle_null ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_mutex))
+
+#define cma__validate_null_tcb(handle) \
+    ((cma__t_int_tcb *)cma__validate_handle_null ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_tcb))
+
+#define cma__validate_null_stack(handle) \
+    ((cma__t_int_stack *)cma__validate_handle_null ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_stack))
+
+#define cma__val_attr_stat(handle,obj) \
+    cma__val_hand_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_attr, \
+           (cma__t_object **)obj)
+
+#define cma__val_cv_stat(handle,obj) \
+    cma__val_hand_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_cv, \
+           (cma__t_object **)obj)
+
+#define cma__val_mutex_stat(handle,obj) \
+    cma__val_hand_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_mutex, \
+           (cma__t_object **)obj)
+
+#define cma__val_tcb_stat(handle) \
+    cma__val_hand_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_tcb, \
+           (cma__t_object **)obj)
+
+#define cma__val_stack_stat(handle,obj) \
+    cma__val_hand_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_stack, \
+           (cma__t_object **)obj)
+
+#define cma__val_nullattr_stat(handle,obj) \
+    cma__val_handnull_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_attr, \
+           (cma__t_object **)obj)
+
+#define cma__val_nullcv_stat(handle,obj) \
+    cma__val_handnull_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_cv, \
+           (cma__t_object **)obj)
+
+#define cma__val_nullmutex_stat(handle,obj) \
+    cma__val_handnull_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_mutex, \
+           (cma__t_object **)obj)
+
+#define cma__val_nulltcb_stat(handle,obj) \
+    cma__val_handnull_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_tcb, \
+           (cma__t_object **)obj)
+
+#define cma__val_nullstack_stat(handle) \
+    cma__val_handnull_stat ( \
+           (cma_t_handle *)(handle), \
+           cma__c_obj_stack, \
+           (cma__t_object **)obj)
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * Internal format of a handle (to the outside world it's an array of two
+ * addresses, but we know better).
+ */
+typedef struct CMA__T_INT_HANDLE {
+    cma__t_object      *pointer;       /* Address of internal structure */
+    cma__t_short       sequence;       /* Sequence number of object */
+    cma__t_short       type;           /* Type code of object */
+    } cma__t_int_handle;
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__clear_handle (cma_t_handle *);
+
+extern void cma__object_to_handle (cma__t_object *,cma_t_handle *);
+
+extern cma__t_int_attr * cma__validate_default_attr (cma_t_handle *);
+
+extern cma_t_status cma__val_defattr_stat (cma_t_handle *,cma__t_int_attr **);
+
+extern cma__t_object * cma__validate_handle (cma_t_handle *,cma_t_natural );
+
+extern cma_t_status cma__val_hand_stat (cma_t_handle *,cma_t_natural,cma__t_object **);
+
+extern         cma__t_object   *cma__validate_handle_null (cma_t_handle *,cma_t_natural);
+
+extern cma_t_status cma__val_handnull_stat (cma_t_handle *,cma_t_natural,cma__t_object **);
+
+#endif
diff --git a/gdb/osf-share/cma_init.h b/gdb/osf-share/cma_init.h
new file mode 100644 (file)
index 0000000..7309736
--- /dev/null
@@ -0,0 +1,114 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for CMA initialization
+ */
+
+#ifndef CMA_INIT
+#define CMA_INIT
+
+/*
+ *  INCLUDE FILES
+ */
+#include <dce/cma_host.h>
+#include <cma_errors.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__c_env_maxattr     0
+#define cma__c_env_minattr     1
+#define cma__c_env_maxcond     2
+#define        cma__c_env_mincond      3
+#define cma__c_env_maxmutex    4
+#define cma__c_env_minmutex    5
+#define cma__c_env_maxthread   6
+#define cma__c_env_minthread   7
+#define cma__c_env_maxcluster  8
+#define cma__c_env_mincluster  9
+#define cma__c_env_maxvp       10
+#define cma__c_env_multiplex   11
+#define cma__c_env_trace       12
+#define cma__c_env_trace_file  13
+
+#define cma__c_env_count       13
+
+
+/*
+ * cma__int_init
+ *
+ * Initialize the main body of CMA exactly once.
+ *
+ * We raise an exception if, for some odd reason, there are already threads
+ * in the environment (e.g. kernel threads), and one of them is trying to
+ * initialize CMA before the  first thread got all the way through the actual
+ * initialization. This code maintains the invariants: "after successfully
+ * calling CMA_INIT, you can call any CMA function", and  "CMA is actually
+ * initialized at most once".
+ */
+/*#ifndef _HP_LIBC_R */
+
+#if  defined _HP_LIBC_R  ||(defined(SNI_SVR4) && !defined(CMA_INIT_NEEDED))
+# define cma__int_init()
+#else
+# define cma__int_init() { \
+    if (!cma__tac_isset(&cma__g_init_started)) { \
+       if (!cma__test_and_set (&cma__g_init_started)) { \
+           cma__init_static (); \
+           cma__test_and_set (&cma__g_init_done); \
+           } \
+       else if (!cma__tac_isset (&cma__g_init_done)) { \
+           cma__error (cma_s_inialrpro); \
+    }}}
+#endif
+
+/*
+ * TYPEDEFS
+ */
+
+typedef enum CMA__T_ENV_TYPE {
+    cma__c_env_type_int,
+    cma__c_env_type_file
+    } cma__t_env_type;
+
+typedef struct CMA__T_ENV {
+    char               *name;          /* Name of environment variable */
+    cma__t_env_type    type;           /* Type of variable */
+    cma_t_integer      value;          /* Numeric value of the variable */
+    } cma__t_env;
+
+/*
+ *  GLOBAL DATA
+ */
+
+extern cma__t_env              cma__g_env[cma__c_env_count];
+extern cma__t_atomic_bit       cma__g_init_started;
+extern cma__t_atomic_bit       cma__g_init_done;
+extern char                    *cma__g_version;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void
+cma__init_static (void);       /* Initialize static data */
+
+#if _CMA_OS_ != _CMA__VMS
+extern void cma__init_atfork (void);
+#endif
+
+#endif
diff --git a/gdb/osf-share/cma_list.h b/gdb/osf-share/cma_list.h
new file mode 100644 (file)
index 0000000..463fa49
--- /dev/null
@@ -0,0 +1,84 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for generic list functions operating on singly linked
+ *     null-terminated lists.  Items may not be REMOVED from the list!  The
+ *     intent is that the list can be traversed (for read-only operations)
+ *     without locking, since insertion is "safe" (though not truely
+ *     atomic).  THIS ASSUMES THAT THE HARDWARE MAKES WRITES VISIBLE TO READS
+ *     IN THE ORDER IN WHICH THEY OCCURRED!  WITHOUT SUCH READ/WRITE
+ *     ORDERING, IT MAY BE NECESSARY TO INSERT "BARRIERS" TO PRODUCE THE
+ *     REQUIRED VISIBILITY!
+ */
+
+#ifndef CMA_LIST
+#define CMA_LIST
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__c_null_list       ((cma__t_list *)cma_c_null_ptr)
+
+/*
+ * Test whether a list is empty.  Return cma_c_true if so, else
+ * cma_c_false.
+ */
+#define cma__list_empty(head)  ((head)->link == cma__c_null_list)
+
+/*
+ * Initialize a queue header to empty.
+ */
+#define cma__list_init(head)   (void)((head)->link = cma__c_null_list)
+
+/*
+ * Insert an element in a list following the specified item (or at the
+ * beginning of the list if "list" is the list head).  NOTE: insertion
+ * operations should be interlocked by the caller!
+ */
+#define cma__list_insert(element,list)    (void)(      \
+    (element)->link            = (list)->link,         \
+    (list)->link               = (element))
+
+/*
+ * Return the next item in a list (or the first, if the address is of the
+ * list header)
+ */
+#define cma__list_next(element)    ((element)->link)
+
+/*
+ * TYPEDEFS
+ */
+
+typedef struct CMA__T_LIST {
+    struct CMA__T_LIST *link;          /* Forward link */
+    } cma__t_list;
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+#endif
diff --git a/gdb/osf-share/cma_mutex.h b/gdb/osf-share/cma_mutex.h
new file mode 100644 (file)
index 0000000..c178630
--- /dev/null
@@ -0,0 +1,230 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for mutex operations
+ */
+
+#ifndef CMA_MUTEX
+#define CMA_MUTEX
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma.h>
+#include <cma_attr.h>
+#include <cma_defs.h>
+#include <cma_semaphore_defs.h>
+#include <cma_sequence.h>
+#include <cma_tcb_defs.h>
+#include <cma_stack.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * TYPEDEFS
+ */
+
+typedef struct CMA__T_INT_MUTEX {
+    cma__t_object      header;         /* Common header (sequence, type) */
+    cma__t_int_attr    *attributes;    /* Back link */
+    cma__t_int_tcb     *owner;         /* Current owner (if any) */
+    cma_t_integer      nest_count;     /* Nesting level for recursive mutex */
+    cma__t_atomic_bit  *unlock;        /* Pointer used for unlock operation */
+    cma__t_atomic_bit  lock;           /* Set if currently locked */
+    struct CMA__T_INT_MUTEX *int_lock; /* Internal protection for mutex */
+    cma__t_atomic_bit  event;          /* Clear when unlock requires action */
+    cma__t_atomic_bit  waiters;        /* Clear when threads are waiting */
+    cma__t_atomic_bit  bitbucket;      /* Fake bit to keep friendlies locked */
+    cma_t_mutex_kind   mutex_kind;     /* Kind of mutex */
+    cma__t_semaphore   semaphore;      /* Semaphore for low-level wait */
+    } cma__t_int_mutex;
+
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     Lock a mutex (internal)
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *     mutex           Pointer to mutex object to lock
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     none
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     none
+ */
+#ifdef NDEBUG
+# define cma__int_lock(mutex) { \
+    if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
+       cma_t_status    res;\
+       res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
+       if (res != cma_s_normal) cma__error (res); \
+       } \
+    }
+#else
+# define cma__int_lock(mutex) { \
+    cma__t_int_tcb *__ltcb__; \
+    __ltcb__ = cma__get_self_tcb (); \
+    if (cma__test_and_set (&((cma__t_int_mutex *)mutex)->lock)) { \
+       cma_t_status    res;\
+       res = cma__int_mutex_block ((cma__t_int_mutex *)mutex); \
+       if (res != cma_s_normal) cma__error (res); \
+       } \
+    ((cma__t_int_mutex *)mutex)->owner = __ltcb__; \
+    }
+#endif
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     Unlock a mutex (internal)
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *     mutex           Pointer to mutex object to unlock
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     none
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     none
+ */
+#ifdef NDEBUG
+# define cma__int_unlock(mutex) { \
+    cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
+    if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
+       cma_t_status    res;\
+       res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
+       if (res != cma_s_normal) cma__error (res); \
+       } \
+    }
+#else
+# define cma__int_unlock(mutex) { \
+    cma__t_int_tcb     *__utcb__; \
+    __utcb__ = cma__get_self_tcb (); \
+    if (((cma__t_int_mutex *)mutex)->mutex_kind == cma_c_mutex_fast) { \
+       cma__assert_warn ( \
+               (__utcb__ == ((cma__t_int_mutex *)mutex)->owner), \
+               "attempt to release mutx owned by another thread"); \
+       ((cma__t_int_mutex *)mutex)->owner = (cma__t_int_tcb *)cma_c_null_ptr; \
+       } \
+    cma__unset (((cma__t_int_mutex *)mutex)->unlock); \
+    if (!cma__test_and_set (&((cma__t_int_mutex *)mutex)->event)) { \
+       cma_t_status    res;\
+       res = cma__int_mutex_unblock ((cma__t_int_mutex *)mutex); \
+       if (res != cma_s_normal) cma__error (res); \
+       } \
+    }
+#endif
+\f
+/*
+ *  FUNCTIONAL DESCRIPTION:
+ *
+ *     cma__int_mutex_delete - Performs work for cma_mutex_delete
+ *
+ *  FORMAL PARAMETERS:
+ *
+ *     cma__t_mutex        _mutex_     - Mutex to be deleted
+ *
+ *  IMPLICIT INPUTS:
+ *
+ *     none
+ *
+ *  IMPLICIT OUTPUTS:
+ *
+ *     none
+ *
+ *  FUNCTION VALUE:
+ *
+ *     none
+ *
+ *  SIDE EFFECTS:
+ *
+ *     none
+ */
+#define cma__int_mutex_delete(_mutex_) { \
+    cma__t_int_mutex    *_int_mutex_; \
+    _int_mutex_ = cma__validate_null_mutex (_mutex_); \
+    if (_int_mutex_ == (cma__t_int_mutex *)cma_c_null_ptr) \
+        return; \
+    if (cma__int_mutex_locked (_int_mutex_)) \
+        cma__error (cma_s_in_use); \
+    cma__free_mutex (_int_mutex_); \
+    cma__clear_handle (_mutex_); \
+    }
+
+
+/*
+ *  GLOBAL DATA
+ */
+
+extern cma__t_sequence cma__g_mutex_seq;
+extern cma__t_int_mutex        *cma__g_global_lock;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__destroy_mutex  (cma__t_int_mutex *);
+
+extern void cma__free_mutex  (cma__t_int_mutex *);
+
+extern void cma__free_mutex_nolock  (cma__t_int_mutex *);
+
+extern cma__t_int_mutex * cma__get_first_mutex  (cma__t_int_attr *);
+
+extern cma__t_int_mutex * cma__get_mutex  (cma__t_int_attr *);
+
+extern void cma__init_mutex  (void);
+
+extern cma_t_status cma__int_mutex_block  (cma__t_int_mutex *);
+
+extern cma_t_boolean cma__int_mutex_locked  (cma__t_int_mutex *);
+
+extern cma_t_boolean cma__int_try_lock  (cma__t_int_mutex *);
+
+extern cma_t_status cma__int_mutex_unblock  (cma__t_int_mutex *);
+
+extern cma_t_boolean cma__mutex_locked  (cma_t_mutex);
+
+extern void cma__reinit_mutex  (cma_t_integer);
+
+#endif
diff --git a/gdb/osf-share/cma_sched.h b/gdb/osf-share/cma_sched.h
new file mode 100644 (file)
index 0000000..6eb7874
--- /dev/null
@@ -0,0 +1,279 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for priority scheduling
+ */
+
+\f
+#ifndef CMA_SCHED
+#define CMA_SCHED
+
+/*
+ *  INCLUDE FILES
+ */
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * Scaling factor for integer priority calculations
+ */
+#define cma__c_prio_scale   8
+
+#if _CMA_VENDOR_ == _CMA__APOLLO
+/*
+ * FIX-ME: Apollo cc 6.8 blows contant folded "<<" and ">>"
+ */
+# define cma__scale_up(exp)  ((exp) * 256)
+# define cma__scale_dn(exp)  ((exp) / 256)
+#else
+# define cma__scale_up(exp)  ((exp) << cma__c_prio_scale)
+# define cma__scale_dn(exp)  ((exp) >> cma__c_prio_scale)
+#endif
+
+
+/*
+ * Min. num. of ticks between self-adjustments for priority adjusting policies.
+ */
+#define cma__c_prio_interval   10
+
+
+/*
+ * Number of queues in each class of queues
+ */
+#define cma__c_prio_n_id    1      /* Very-low-priority class threads */
+#define cma__c_prio_n_bg    8      /* Background class threads */
+#define cma__c_prio_n_0            1       /* Very low priority throughput quartile */
+#define cma__c_prio_n_1            2       /* Low priority throughput quartile */
+#define cma__c_prio_n_2            3       /* Medium priority throughput quartile */
+#define cma__c_prio_n_3            4       /* High priority throughput quartile */
+#define cma__c_prio_n_rt    1      /* Real Time priority queues */
+
+/*
+ * Number of queues to skip (offset) to get to the queues in this section of LA
+ */
+#define cma__c_prio_o_id 0
+#define cma__c_prio_o_bg cma__c_prio_o_id + cma__c_prio_n_id
+#define cma__c_prio_o_0  cma__c_prio_o_bg + cma__c_prio_n_bg
+#define cma__c_prio_o_1  cma__c_prio_o_0  + cma__c_prio_n_0
+#define cma__c_prio_o_2  cma__c_prio_o_1  + cma__c_prio_n_1
+#define cma__c_prio_o_3  cma__c_prio_o_2  + cma__c_prio_n_2
+#define cma__c_prio_o_rt cma__c_prio_o_3  + cma__c_prio_n_3
+
+/*
+ * Ada_low:  These threads are queued in the background queues, thus there
+ * must be enough queues to allow one queue for each Ada priority below the
+ * Ada default.
+ */  
+#define cma__c_prio_o_al cma__c_prio_o_bg
+
+/*
+ * Total number of ready queues, for declaration purposes
+ */
+#define cma__c_prio_n_tot  \
+       cma__c_prio_n_id + cma__c_prio_n_bg + cma__c_prio_n_rt \
+       + cma__c_prio_n_0 + cma__c_prio_n_1 + cma__c_prio_n_2 + cma__c_prio_n_3
+
+/*
+ * Formulae for determining a thread's priority.  Variable priorities (such
+ * as foreground and background) are scaled values.
+ */
+#define cma__sched_priority(tcb)       \
+    ((tcb)->sched.class == cma__c_class_fore  ? cma__sched_prio_fore (tcb)  \
+    :((tcb)->sched.class == cma__c_class_back ? cma__sched_prio_back (tcb)  \
+    :((tcb)->sched.class == cma__c_class_rt   ? cma__sched_prio_rt (tcb)    \
+    :((tcb)->sched.class == cma__c_class_idle ? cma__sched_prio_idle (tcb)  \
+    :(cma__bugcheck ("cma__sched_priority: unrecognized class"), 0) ))))
+
+#define cma__sched_prio_fore(tcb)      cma__sched_prio_fore_var (tcb)
+#define cma__sched_prio_back(tcb)      ((tcb)->sched.fixed_prio        \
+       ? cma__sched_prio_back_fix (tcb) : cma__sched_prio_back_var (tcb) )
+#define cma__sched_prio_rt(tcb)                ((tcb)->sched.priority)
+#define cma__sched_prio_idle(tcb)      ((tcb)->sched.priority)
+
+#define cma__sched_prio_back_fix(tcb)  \
+       (cma__g_prio_bg_min + (cma__g_prio_bg_max - cma__g_prio_bg_min) \
+       * ((tcb)->sched.priority + cma__c_prio_o_al - cma__c_prio_o_bg) \
+       / cma__c_prio_n_bg)
+
+/*
+ * FIX-ME: Enable after modeling (if we like it)
+ */
+#if 1
+# define cma__sched_prio_fore_var(tcb)  \
+       ((cma__g_prio_fg_max + cma__g_prio_fg_min)/2)
+# define cma__sched_prio_back_var(tcb)  \
+       ((cma__g_prio_bg_max + cma__g_prio_bg_min)/2)
+#else
+# define cma__sched_prio_back_var(tcb)  cma__sched_prio_fore_var (tcb)
+
+# if 1
+/*
+ * Re-scale, since the division removes the scale factor.
+ * Scale and multiply before dividing to avoid loss of precision.
+ */
+#  define cma__sched_prio_fore_var(tcb)  \
+       ((cma__g_vp_count * cma__scale_up((tcb)->sched.tot_time)) \
+       / (tcb)->sched.cpu_time)
+# else
+/*
+ * Re-scale, since the division removes the scale factor.
+ * Scale and multiply before dividing to avoid loss of precision.
+ * Left shift the numerator to multiply by two.
+ */
+#  define cma__sched_prio_fore_var(tcb)  \
+    (((cma__g_vp_count * cma__scale_up((tcb)->sched.tot_time)  \
+    * (tcb)->sched.priority * cma__g_init_frac_sum) << 1)  \
+    / ((tcb)->sched.cpu_time * (tcb)->sched.priority * cma__g_init_frac_sum  \
+       + (tcb)->sched.tot_time))
+# endif
+#endif
+
+/*
+ * Update weighted-averaged, scaled tick counters
+ */
+#define cma__sched_update_time(ave, new) \
+    (ave) = (ave) - ((cma__scale_dn((ave)) - (new)) << (cma__c_prio_scale - 4))
+
+#define cma__sched_parameterize(tcb, policy) { \
+    switch (policy) { \
+       case cma_c_sched_fifo : { \
+           (tcb)->sched.rtb =          cma_c_true; \
+           (tcb)->sched.spp =          cma_c_true; \
+           (tcb)->sched.fixed_prio =   cma_c_true; \
+           (tcb)->sched.class =        cma__c_class_rt; \
+           break; \
+           } \
+       case cma_c_sched_rr : { \
+           (tcb)->sched.rtb =          cma_c_false; \
+           (tcb)->sched.spp =          cma_c_true; \
+           (tcb)->sched.fixed_prio =   cma_c_true; \
+           (tcb)->sched.class =        cma__c_class_rt; \
+           break; \
+           } \
+       case cma_c_sched_throughput : { \
+           (tcb)->sched.rtb =          cma_c_false; \
+           (tcb)->sched.spp =          cma_c_false; \
+           (tcb)->sched.fixed_prio =   cma_c_false; \
+           (tcb)->sched.class =        cma__c_class_fore; \
+           break; \
+           } \
+       case cma_c_sched_background : { \
+           (tcb)->sched.rtb =          cma_c_false; \
+           (tcb)->sched.spp =          cma_c_false; \
+           (tcb)->sched.fixed_prio =   cma_c_false; \
+           (tcb)->sched.class =        cma__c_class_back; \
+           break; \
+           } \
+       case cma_c_sched_ada_low : { \
+           (tcb)->sched.rtb =          cma_c_false; \
+           (tcb)->sched.spp =          cma_c_true; \
+           (tcb)->sched.fixed_prio =   cma_c_true; \
+           (tcb)->sched.class =        cma__c_class_back; \
+           break; \
+           } \
+       case cma_c_sched_idle : { \
+           (tcb)->sched.rtb =          cma_c_false; \
+           (tcb)->sched.spp =          cma_c_false; \
+           (tcb)->sched.fixed_prio =   cma_c_false; \
+           (tcb)->sched.class =        cma__c_class_idle; \
+           break; \
+           } \
+       default : { \
+           cma__bugcheck ("cma__sched_parameterize: bad scheduling Policy"); \
+           break; \
+           } \
+       } \
+    }
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ * Scheduling classes
+ */
+typedef enum CMA__T_SCHED_CLASS {
+    cma__c_class_rt,
+    cma__c_class_fore,
+    cma__c_class_back,
+    cma__c_class_idle
+    } cma__t_sched_class;
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * Minimuma and maximum prioirities, for foreground and background threads,
+ * as of the last time the scheduler ran.  (Scaled once.)
+ */
+extern cma_t_integer   cma__g_prio_fg_min;
+extern cma_t_integer   cma__g_prio_fg_max;
+extern cma_t_integer   cma__g_prio_bg_min;
+extern cma_t_integer   cma__g_prio_bg_max;
+
+/*
+ * The "m" values are the slopes of the four sections of linear approximation.
+ *
+ * cma__g_prio_m_I = 4*N(I)/cma__g_prio_range      (Scaled once.)
+ */
+extern cma_t_integer   cma__g_prio_m_0,
+                       cma__g_prio_m_1,
+                       cma__g_prio_m_2,
+                       cma__g_prio_m_3;
+
+/* 
+ * The "b" values are the intercepts of the four sections of linear approx.
+ *  (Not scaled.)
+ *
+ * cma__g_prio_b_I = -N(I)*(I*prio_max + (4-I)*prio_min)/prio_range + prio_o_I
+ */
+extern cma_t_integer   cma__g_prio_b_0,
+                       cma__g_prio_b_1,
+                       cma__g_prio_b_2,
+                       cma__g_prio_b_3;
+
+/* 
+ * The "p" values are the end points of the four sections of linear approx.
+ *
+ * cma__g_prio_p_I = cma__g_prio_fg_min + (I/4)*cma__g_prio_range
+ *
+ * [cma__g_prio_p_0 is not defined since it is not used (also, it is the same
+ *  as cma__g_prio_fg_min).]       (Scaled once.)
+ */
+extern cma_t_integer   cma__g_prio_p_1,
+                       cma__g_prio_p_2,
+                       cma__g_prio_p_3;
+
+/*
+ * Points to the next queue for the dispatcher to check for ready threads.
+ */
+extern cma_t_integer   cma__g_next_ready_queue;
+
+/*
+ * Points to the queues of virtual processors (for preempt victim search)
+ */
+extern cma__t_queue    cma__g_run_vps;
+extern cma__t_queue    cma__g_susp_vps;
+extern cma_t_integer   cma__g_vp_count;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+#endif
diff --git a/gdb/osf-share/cma_semaphore_defs.h b/gdb/osf-share/cma_semaphore_defs.h
new file mode 100644 (file)
index 0000000..e160de3
--- /dev/null
@@ -0,0 +1,46 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for semaphore structure definition.
+ */
+#ifndef CMA_SEMAPHORE_DEFS
+#define CMA_SEMAPHORE_DEFS
+
+/*
+ *  INCLUDE FILES
+ */
+#include <cma.h>
+#include <cma_queue.h>
+#include <cma_defs.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__c_semaphore_timeout 1
+#define cma__c_semaphore_event  0
+#define cma__c_select_timeout   2
+
+/*
+ * TYPEDEFS
+ */
+
+typedef struct CMA__T_SEMAPHORE {
+    cma__t_queue       queue;
+    cma__t_atomic_bit  nopending;
+    } cma__t_semaphore;
+
+#endif
diff --git a/gdb/osf-share/cma_sequence.h b/gdb/osf-share/cma_sequence.h
new file mode 100644 (file)
index 0000000..8d362ed
--- /dev/null
@@ -0,0 +1,56 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for sequence generator functions
+ */
+
+#ifndef CMA_SEQUENCE
+#define CMA_SEQUENCE
+
+/*
+ *  INCLUDE FILES
+ */
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+/*
+ * TYPEDEFS
+ */
+
+#ifndef __STDC__
+struct CMA__T_INT_MUTEX;
+#endif
+
+typedef struct CMA__T_SEQUENCE {
+    struct CMA__T_INT_MUTEX    *mutex; /* Serialize access to counter */
+    cma_t_natural              seq;    /* Sequence number for object */
+    } cma__t_sequence;
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern cma_t_natural cma__assign_sequence (cma__t_sequence *);
+
+extern void cma__init_sequence (cma__t_sequence *);    
+
+#endif
diff --git a/gdb/osf-share/cma_stack.h b/gdb/osf-share/cma_stack.h
new file mode 100644 (file)
index 0000000..97a41fd
--- /dev/null
@@ -0,0 +1,83 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for stack management
+ */
+#ifndef CMA_STACK
+#define CMA_STACK
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma_tcb_defs.h>
+#include <cma.h>
+#include <cma_attr.h>
+#include <cma_queue.h>
+#include <cma_stack_int.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#if _CMA_UNIPROCESSOR_
+# define cma__get_self_tcb()   (cma__g_current_thread)
+#endif
+
+/*
+ * Round the given value (a) upto cma__g_chunk_size
+ */
+#define cma__roundup_chunksize(a)   (cma__roundup(a,cma__g_chunk_size))
+
+/*
+ * TYPEDEFS
+ */
+
+/*
+ *  GLOBAL DATA
+ */
+
+extern cma__t_list     cma__g_stack_clusters;
+extern cma__t_int_tcb  *cma__g_current_thread;
+extern cma_t_integer   cma__g_chunk_size;
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__assign_stack  (cma__t_int_stack *,cma__t_int_tcb *);
+
+extern void cma__free_stack  (cma__t_int_stack *);
+
+extern void cma__free_stack_list  (cma__t_queue *);
+
+#if !_CMA_UNIPROCESSOR_
+extern cma__t_int_tcb * cma__get_self_tcb  (void);
+#endif
+
+extern cma__t_int_tcb * cma__get_sp_tcb  (cma_t_address);
+
+extern cma__t_int_stack * cma__get_stack  (cma__t_int_attr *);
+
+extern void cma__init_stack  (void);
+
+extern void cma__reinit_stack  (cma_t_integer);
+
+#if _CMA_PROTECT_MEMORY_
+extern void cma__remap_stack_holes  (void);
+#endif
+
+#endif
diff --git a/gdb/osf-share/cma_stack_int.h b/gdb/osf-share/cma_stack_int.h
new file mode 100644 (file)
index 0000000..bf76f60
--- /dev/null
@@ -0,0 +1,136 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for stack management (internal to cma_stack.c, but
+ *     separate for convenience, and unit testing).
+ */
+\f
+#ifndef CMA_STACK_INT
+#define CMA_STACK_INT
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma.h>
+#include <cma_queue.h>
+#include <cma_list.h>
+#include <cma_tcb_defs.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma___c_first_free_chunk       0
+#define cma___c_min_count      2       /* Smallest number of chunks to leave */
+#define cma___c_end            (-1)    /* End of free list (flag) */
+#define cma__c_yellow_size     0
+
+/* 
+ * Cluster types
+ */
+#define cma___c_cluster  0     /* Default cluster */
+#define cma___c_bigstack 1     /* Looks like a cluster, but it's a stack */
+
+
+#define cma___c_null_cluster   (cma___t_cluster *)cma_c_null_ptr
+
+
+/*
+ * TYPEDEFS
+ */
+
+#ifndef __STDC__
+struct CMA__T_INT_STACK;
+#endif
+
+typedef cma_t_natural  cma___t_index;  /* Type for chunk index */
+
+typedef struct CMA___T_CLU_DESC {
+    cma__t_list                list;           /* Queue element for cluster list */
+    cma_t_integer      type;           /* Type of cluster */
+    cma_t_address      stacks;
+    cma_t_address      limit;
+    } cma___t_clu_desc;
+
+typedef union CMA___T_MAP_ENTRY {
+    struct {
+       cma__t_int_tcb  *tcb;           /* TCB associated with stack chunk */
+       struct CMA__T_INT_STACK *stack; /* Stack desc. ass. with stack chunk */
+       } mapped;
+    struct {
+       cma___t_index           size;   /* Number of chunks in block */
+       cma___t_index           next;   /* Next free block */
+       } free;
+    } cma___t_map_entry;
+
+/*
+ * NOTE: It is VERY IMPORTANT that both cma___t_cluster and cma___t_bigstack
+ * begin with the cma___t_clu_desc structure, as there is some code in the
+ * stack manager that relies on being able to treat both as equivalent!
+ */
+typedef struct CMA___T_CLUSTER {
+    cma___t_clu_desc   desc;           /* Describe this cluster */
+    cma___t_map_entry  map[cma__c_chunk_count];        /* thread map */
+    cma___t_index      free;           /* First free chunk index */
+    } cma___t_cluster;
+
+/*
+ * NOTE: It is VERY IMPORTANT that both cma___t_cluster and cma___t_bigstack
+ * begin with the cma___t_clu_desc structure, as there is some code in the
+ * stack manager that relies on being able to treat both as equivalent!
+ */
+typedef struct CMA___T_BIGSTACK {
+    cma___t_clu_desc   desc;           /* Describe this cluster */
+    cma__t_int_tcb     *tcb;           /* TCB associated with stack */
+    struct CMA__T_INT_STACK    *stack; /* Stack desc. ass. with stack */
+    cma_t_natural      size;           /* Size of big stack */
+    cma_t_boolean      in_use;         /* Set if allocated */
+    } cma___t_bigstack;
+
+#if _CMA_PROTECT_MEMORY_
+typedef struct CMA___T_INT_HOLE {
+    cma__t_queue       link;           /* Link holes together */
+    cma_t_boolean      protected;      /* Set when pages are protected */
+    cma_t_address      first;          /* First protected byte */
+    cma_t_address      last;           /* Last protected byte */
+    } cma___t_int_hole;
+#endif
+
+typedef struct CMA__T_INT_STACK {
+    cma__t_object      header;         /* Common header (sequence, type info */
+    cma__t_int_attr    *attributes;    /* Backpointer to attr obj */
+    cma___t_cluster    *cluster;       /* Stack's cluster */
+    cma_t_address      stack_base;     /* base address of stack */
+    cma_t_address      yellow_zone;    /* first address of yellow zone */
+    cma_t_address      last_guard;     /* last address of guard pages */
+    cma_t_natural      first_chunk;    /* First chunk allocated */
+    cma_t_natural      chunk_count;    /* Count of chunks allocated */
+    cma__t_int_tcb     *tcb;           /* TCB backpointer */
+#if _CMA_PROTECT_MEMORY_
+    cma___t_int_hole   hole;           /* Description of hole */
+#endif
+    } cma__t_int_stack;
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+#endif
diff --git a/gdb/osf-share/cma_tcb_defs.h b/gdb/osf-share/cma_tcb_defs.h
new file mode 100644 (file)
index 0000000..6622050
--- /dev/null
@@ -0,0 +1,269 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     TCB-related type definitions.
+ */
+
+#ifndef CMA_TCB_DEFS
+#define CMA_TCB_DEFS
+
+/*
+ *  INCLUDE FILES
+ */
+# if !_CMA_THREAD_SYNC_IO_
+#  include <cma_thread_io.h>
+# endif
+#include <cma.h>
+#include <cma_debug_client.h>
+#include <cma_attr.h>
+#include <cma_defs.h>
+#include <cma_handle.h>
+#include <cma_queue.h>
+#if _CMA_OS_ == _CMA__UNIX
+# if defined(SNI_DCOSX)
+#   include <sys/ucontext.h>
+# endif
+# include <signal.h>
+#endif
+#include <cma_sched.h>
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#if _CMA_PLATFORM_ == _CMA__IBMR2_UNIX
+# define cma__c_ibmr2_ctx_stack_size   2048
+# define cma__c_ibmr2_ctx_stack_top    (cma__c_ibmr2_ctx_stack_size - 1)
+#endif
+
+/*
+ * TYPEDEFS
+ */
+
+#ifndef __STDC__
+# if _CMA_HARDWARE_ != _CMA__HPPA
+struct CMA__T_SEMAPHORE;
+# endif
+struct CMA__T_INT_CV;
+struct CMA__T_INT_MUTEX;
+struct CMA__T_INT_TCB;
+#endif
+
+typedef cma_t_address          *cma__t_context_list;
+
+typedef struct CMA__T_TCB_PAD {
+    /* 
+     * Adjust to align the tcb prolog at byte 32.
+     * 12 bytes are required as object header is currently 
+     * 20 bytes long.
+     */
+    cma_t_integer      pad1;           /* pad bytes */
+    cma_t_integer      pad2;           /* pad bytes */
+    cma_t_integer      pad3;           /* pad bytes */
+    } cma__t_tcb_pad;
+
+#if (_CMA_OS_ == _CMA__UNIX) && !_CMA_THREAD_SYNC_IO_
+typedef struct CMA__T_TCB_SELECT {
+    cma__t_queue       queue;
+#if (_CMA_UNIX_TYPE !=  _CMA__SVR4)
+       cma__t_file_mask    *rfds;
+       cma__t_file_mask    *wfds;
+       cma__t_file_mask    *efds;
+#else
+       cma__t_poll_info        poll_info;
+#endif /* (_CMA_UNIX_TYPE !=  _CMA__SVR4) */
+    cma_t_integer      nfound;
+    } cma__t_tcb_select;
+#endif
+
+typedef struct CMA__T_TCB_TIME {
+    cma__t_queue       queue;          /* must be first entry! */
+    cma_t_integer      mode;
+    struct CMA__T_SEMAPHORE *semaphore;        /* used for timed semaphores */
+    cma_t_date_time    wakeup_time;
+    cma_t_integer      quanta_remaining;
+    } cma__t_tcb_time;
+
+typedef enum CMA__T_DEBEVT {
+       cma__c_debevt_activating = 1,   /* First transition to running */
+       cma__c_debevt_running = 2,      /* Any transition to running */
+       cma__c_debevt_preempting = 3,   /* Preemted (replaced) another thread */
+       cma__c_debevt_blocking = 4,     /* Any transition to blocked */
+       cma__c_debevt_terminating = 5,  /* Final state transition */
+       cma__c_debevt_term_alert = 6,   /* Terminated due to alert/cancel */
+       cma__c_debevt_term_exc = 7,     /* Terminated due to exception */
+       cma__c_debevt_exc_handled = 8   /* Exception is being handled */
+       } cma__t_debevt;
+
+#define cma__c_debevt__first ((cma_t_integer)cma__c_debevt_activating)
+#define cma__c_debevt__last  ((cma_t_integer)cma__c_debevt_exc_handled)
+#define cma__c_debevt__dim (cma__c_debevt__last + 1)
+
+/* 
+ * Type defining thread substate, which is used by the debugger.
+ * If the state is blocked, substate indicates WHY the thread is blocked.
+ */
+typedef enum CMA__T_SUBSTATE {
+    cma__c_substa_normal = 0,
+    cma__c_substa_mutex = 1,
+    cma__c_substa_cv = 2,
+    cma__c_substa_timed_cv = 3,
+    cma__c_substa_term_alt = 4,
+    cma__c_substa_term_exc = 5,
+    cma__c_substa_delay =6,
+    cma__c_substa_not_yet_run = 7
+    } cma__t_substate;
+#define cma__c_substa__first ((cma_t_integer)cma__c_substa_normal)
+#define cma__c_substa__last  ((cma_t_integer)cma__c_substa_not_yet_run)
+#define cma__c_substa__dim (cma__c_substa__last + 1)
+
+
+/*
+ * Per-thread state for the debugger
+ */
+typedef struct CMA__T_TCB_DEBUG {
+    cma_t_boolean      on_hold;        /* Thread was put on hold by debugger */
+    cma_t_boolean      activated;      /* Activation event was reported */
+    cma_t_boolean      did_preempt;    /* Thread preempted prior one */
+    cma_t_address      start_pc;       /* Start routine address */
+    cma_t_address      object_addr;    /* Addr of thread object */
+    cma__t_substate    substate;       /* Reason blocked, terminated, etc.*/
+    cma_t_boolean      notify_debugger;/* Notify debugger thread is running */
+    cma_t_address      SPARE2;         /* SPARE */
+    cma_t_address      SPARE3;         /* SPARE */
+    struct CMA__T_INT_TCB      
+                       *preempted_tcb; /* TCB of thread that got preempted */
+    cma_t_boolean      flags[cma__c_debevt__dim];      
+                                       /* Events enabled for this thread */
+    } cma__t_tcb_debug;
+
+typedef struct CMA__T_TCB_SCHED {
+    cma_t_integer      adj_time;       /* Abs. time in ticks of last prio adj */
+    cma_t_integer      tot_time;       /* Weighted ave in ticks (scaled) */
+    cma_t_integer      time_stamp;     /* Abs. time in ticks of last update */
+    cma_t_integer      cpu_time;       /* Weighted average in ticks */
+    cma_t_integer      cpu_ticks;      /* # of ticks while comp. (scaled) */
+    cma_t_integer      q_num;          /* Number of last ready queue on */
+    cma_t_priority     priority;       /* Thread priority */
+    cma_t_sched_policy  policy;         /* Scheduling policy of thread */
+    cma_t_boolean      rtb;            /* "Run 'Till Block" scheduling */
+    cma_t_boolean      spp;            /* "Strict Priority Preemption" sched */
+    cma_t_boolean      fixed_prio;     /* Fixed priority */
+    cma__t_sched_class class;          /* Scheduling class */
+    struct CMA__T_VP   *processor;     /* Current processor (if running) */
+    } cma__t_tcb_sched;
+
+typedef struct CMA__T_INT_ALERT {
+    cma_t_boolean      pending : 1;    /* alert_pending bit */
+    cma_t_boolean      g_enable : 1;   /* general delivery state */
+    cma_t_boolean      a_enable : 1;   /* asynchronous delivery state */
+    cma_t_integer      spare : 29;     /* Pad to longword */
+    cma_t_natural      count;          /* Alert scope nesting count */
+    } cma__t_int_alert;
+
+typedef enum CMA__T_STATE {
+    cma__c_state_running = 0,          /* For consistency with initial TCB */
+    cma__c_state_ready = 1,
+    cma__c_state_blocked = 2,
+    cma__c_state_terminated = 3
+    } cma__t_state;
+#define cma__c_state__first ((cma_t_integer)cma__c_state_running)
+#define cma__c_state__last  ((cma_t_integer)cma__c_state_terminated)
+#define cma__c_state__dim (cma__c_state__last + 1)
+
+typedef enum CMA__T_THKIND {
+    cma__c_thkind_initial = 0,         /* Initial thread */
+    cma__c_thkind_normal = 1,          /* Normal thread */
+    cma__c_thkind_null = 2             /* A null thread */
+    } cma__t_thkind;
+#define cma__c_thkind__first ((cma_t_integer)cma__c_thkind_initial)
+#define cma__c_thkind__last  ((cma_t_integer)cma__c_thkind_null)
+#define cma__c_thkind__dim (cma__c_thkind__last + 1)
+
+typedef enum CMA__T_SYSCALL_STATE {
+       cma__c_syscall_ok = 1,                      /* syscall was not interrupted */
+       cma__c_syscall_intintrpt = 1,       /* syscall was interrupted by VTALRM */
+       cma__c_syscall_extintrpt = 2        /* syscall was interrupted by external signal */
+       } cma__t_syscall_state;
+
+
+typedef struct CMA__T_INT_TCB {
+    /* 
+     * Fixed part of TCB.
+     *   Modifications to the following three fields must be coordinated.  
+     *   The object header must always be first, and the prolog must always 
+     *   remain at the same offset (32) for all time. Thus the object header
+     *   must never grow beyond a maximum of 32 bytes.
+     */
+    cma__t_object      header;         /* Common object header */
+    cma__t_tcb_pad     pad1;           /* Pad required to align prolog */
+    cma_t_tcb_prolog   prolog;         /* Standard prolog for tasks, threads */
+
+    /* 
+     * Floating part of TCB (fields here on are free to be moved and resized).
+     */
+    cma__t_queue       threads;        /* List of all known threads */
+    cma__t_int_attr    *attributes;    /* Backpointer to attr obj */
+    cma__t_state       state;          /* Current state of thread */
+    cma__t_thkind      kind;           /* Which kind of thread */
+    struct CMA__T_INT_MUTEX 
+                       *mutex;         /* Mutex to control TCB access */
+    struct CMA__T_INT_CV 
+                       *term_cv;       /* CV for join */
+    struct CMA__T_INT_MUTEX 
+                       *tswait_mutex;  /* Mutex for thread-synchronous waits */
+    struct CMA__T_INT_CV 
+                       *tswait_cv;     /* CV for thread-synchronous waits */
+    cma_t_start_routine        start_code;     /* Address of start routine */
+    cma_t_address      start_arg;      /* Argument to pass to start_code */
+    cma__t_queue       stack;          /* Queue header for stack descr. */
+    cma_t_natural      context_count;  /* Size of context array */
+    cma__t_context_list        contexts;       /* Context value array pointer */
+    cma_t_exit_status  exit_status;    /* Exit status of thread */
+    cma_t_address      return_value;   /* Thread's return value */
+    cma__t_async_ctx   async_ctx;      /* Asynchronous context switch info */
+    cma__t_static_ctx  static_ctx;     /* Static context switch information */
+    cma_t_integer      event_status;   /* Status of semaphore operation */
+    cma__t_tcb_time    timer;          /* Time info for dispatcher */
+    cma__t_tcb_sched   sched;          /* Scheduler info */
+    cma__t_tcb_debug   debug;          /* Debugger info */
+#if _CMA_OS_ == _CMA__UNIX
+# if !_CMA_THREAD_SYNC_IO_
+    cma__t_tcb_select  select;         /* Select info for timed selects */
+# endif
+    struct sigaction   sigaction_data[NSIG];
+#endif
+    cma_t_natural       syscall_state; /* set if one of the cma wrapped syscalls was interrupted. */
+    cma_t_boolean      detached;       /* Set if already detached */
+    cma_t_boolean      terminated;     /* Set if terminated */
+    cma_t_integer      joiners;        /* Count of joiners, for zombie frees */
+    cma__t_int_alert   alert;          /* Current alert state info */
+    struct CMA__T_INT_CV 
+                       *wait_cv;       /* CV thread is currently waiting on */
+    struct CMA__T_INT_MUTEX 
+                       *wait_mutex;    /* Mutex thread is waiting on */
+    struct EXC_CONTEXT_T
+                       *exc_stack;     /* Top of exception stack */
+#if _CMA_PLATFORM_ == _CMA__IBMR2_UNIX
+    char               ctx_stack[cma__c_ibmr2_ctx_stack_size];
+#endif
+    cma_t_integer      thd_errno;      /* Per-thread errno value */
+#if _CMA_OS_ == _CMA__VMS
+    cma_t_integer      thd_vmserrno;   /* Per-thread VMS errno value */
+#endif
+    } cma__t_int_tcb;
+
+#endif
diff --git a/gdb/osf-share/cma_util.h b/gdb/osf-share/cma_util.h
new file mode 100644 (file)
index 0000000..00451c4
--- /dev/null
@@ -0,0 +1,125 @@
+/* 
+ * (c) Copyright 1990-1996 OPEN SOFTWARE FOUNDATION, INC.
+ * (c) Copyright 1990-1996 HEWLETT-PACKARD COMPANY
+ * (c) Copyright 1990-1996 DIGITAL EQUIPMENT CORPORATION
+ * (c) Copyright 1991, 1992 Siemens-Nixdorf Information Systems
+ * To anyone who acknowledges that this file is provided "AS IS" without
+ * any express or implied warranty: permission to use, copy, modify, and
+ * distribute this file for any purpose is hereby granted without fee,
+ * provided that the above copyright notices and this notice appears in
+ * all source code copies, and that none of the names listed above be used
+ * in advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  None of these organizations
+ * makes any representations about the suitability of this software for
+ * any purpose.
+ */
+/*
+ *     Header file for CMA internal UTIL operations
+ */
+
+#ifndef        CMA_UTIL
+#define CMA_UTIL
+
+/*
+ *  INCLUDE FILES
+ */
+
+#include <cma.h>
+#include <cma_attr.h>
+#include <cma_defs.h>
+
+#if _CMA_OS_ == _CMA__VMS
+# include <cma_rms.h>
+#endif
+
+#if _CMA_VENDOR_ == _CMA__SUN
+# include <sys/time.h>
+#else
+# include <time.h>
+#endif
+
+#if _CMA_OS_ == _CMA__UNIX
+# include <stdio.h>
+#endif
+
+/*
+ * CONSTANTS AND MACROS
+ */
+
+#define cma__c_buffer_size  256                    /* Size of output buffer        */
+
+/*
+ * TYPEDEFS
+ */
+
+/* 
+ * Alternate eol routine
+ */
+typedef void (*cma__t_eol_routine) (char *);
+
+#if _CMA_OS_ == _CMA__VMS
+ typedef struct CMA__T_VMSFILE {
+    struct RAB rab;
+    struct FAB fab;
+    } cma__t_vmsfile,  *cma__t_file;
+#elif  ( _CMA_UNIX_TYPE == _CMA__SVR4 )
+ typedef int           cma__t_file;
+#else
+ typedef FILE          *cma__t_file;
+#endif
+
+/*
+ *  GLOBAL DATA
+ */
+
+/*
+ * INTERNAL INTERFACES
+ */
+
+extern void cma__abort  (void);
+
+extern cma_t_integer cma__atol  (char *);
+
+extern cma_t_integer cma__atoi  (char *);
+
+extern char * cma__getenv  (char *,char *,int);
+
+extern int cma__gettimespec  (struct timespec *);
+
+extern cma__t_file cma__int_fopen  (char *,char *);
+
+#ifndef NDEBUG
+extern void cma__init_trace  (char *_env);
+#endif
+
+extern char * cma__memcpy  (char *,char *,cma_t_integer);
+       
+#ifndef cma__memset
+extern char * cma__memset  (char *,cma_t_integer,cma_t_integer);
+#endif
+
+extern void cma__putformat  (char *,char *,...);
+
+extern void cma__putstring  (char *,char *);
+
+extern void cma__putint  (char *,cma_t_integer);
+
+extern void cma__putint_5  (char *,cma_t_integer);
+
+extern void cma__putint_10  (char *,cma_t_integer);
+
+extern void cma__puthex  (char *,cma_t_integer);
+
+extern void cma__puthex_8  (char *,cma_t_integer);
+
+extern void cma__puteol  (char *);
+
+extern void cma__set_eol_routine  (cma__t_eol_routine,cma__t_eol_routine *);
+
+extern cma_t_integer cma__strlen  (char *);
+
+extern int cma__strncmp  (char *,char *,cma_t_integer);
+
+extern char *cma__gets (char *,char *);
+
+#endif