Hi, ports

Valgrind does not run Pthread target program.
I made patch to run Pthread target program.

I applied this patch and run attached main.c as:

  $ cc main.c -lpthread
  $ while :; do valgrind ./a.out 32 8; done

for 24 hours.  I got no problem.

ok?

Index: patches/patch-coregrind_m_libcsignal_c
===================================================================
RCS file: patches/patch-coregrind_m_libcsignal_c
diff -N patches/patch-coregrind_m_libcsignal_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-coregrind_m_libcsignal_c      9 Dec 2019 05:30:18 -0000
@@ -0,0 +1,21 @@
+--- coregrind/m_libcsignal.c.orig
++++ coregrind/m_libcsignal.c
+@@ -397,6 +397,7 @@
+ Int VG_(tkill)( Int lwpid, Int signo )
+ {
+ #  if defined(__NR_tkill)
++   PRINT("sys___tfork ( %ld, %ld )",ARG1,ARG2);
+    SysRes res = VG_(mk_SysRes_Error)(VKI_ENOSYS);
+    res = VG_(do_syscall2)(__NR_tkill, lwpid, signo);
+    if (sr_isError(res) && sr_Err(res) == VKI_ENOSYS)
+@@ -415,7 +416,9 @@
+    return sr_isError(res) ? -1 : 0;
+ 
+ #  elif defined(VGO_openbsd)
+-   I_die_here;
++   SysRes res;
++   res = VG_(do_syscall3)(__NR_thrkill, lwpid, signo, NULL);
++   return sr_isError(res) ? -1 : 0;
+ 
+ #  else
+ #    error "Unsupported plat"
Index: patches/patch-coregrind_m_syswrap_priv_syswrap_openbsd_h
===================================================================
RCS file: 
/cvs/ports/devel/valgrind/patches/patch-coregrind_m_syswrap_priv_syswrap_openbsd_h,v
retrieving revision 1.1
diff -u -p -r1.1 patch-coregrind_m_syswrap_priv_syswrap_openbsd_h
--- patches/patch-coregrind_m_syswrap_priv_syswrap_openbsd_h    23 Oct 2019 
02:35:05 -0000      1.1
+++ patches/patch-coregrind_m_syswrap_priv_syswrap_openbsd_h    9 Dec 2019 
05:30:18 -0000
@@ -1,5 +1,14 @@
 --- coregrind/m_syswrap/priv_syswrap-openbsd.h.orig
 +++ coregrind/m_syswrap/priv_syswrap-openbsd.h
+@@ -50,7 +50,7 @@
+ DECL_TEMPLATE(openbsd, sys_open);
+ DECL_TEMPLATE(openbsd, sys_close);
+ DECL_TEMPLATE(openbsd, sys_getentropy);
+-DECL_TEMPLATE(openbsd, sys___tfork);
++DECL_TEMPLATE(openbsd, sys___tfork_thread);
+ DECL_TEMPLATE(openbsd, sys_link);
+ DECL_TEMPLATE(openbsd, sys_unlink);
+ DECL_TEMPLATE(openbsd, sys_wait4);
 @@ -144,6 +144,7 @@
  DECL_TEMPLATE(openbsd, sys_pledge);
  DECL_TEMPLATE(openbsd, sys_ppoll);
Index: patches/patch-coregrind_m_syswrap_syswrap_amd64_openbsd_c
===================================================================
RCS file: patches/patch-coregrind_m_syswrap_syswrap_amd64_openbsd_c
diff -N patches/patch-coregrind_m_syswrap_syswrap_amd64_openbsd_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-coregrind_m_syswrap_syswrap_amd64_openbsd_c   9 Dec 2019 
05:30:18 -0000
@@ -0,0 +1,215 @@
+--- coregrind/m_syswrap/syswrap-amd64-openbsd.c.orig
++++ coregrind/m_syswrap/syswrap-amd64-openbsd.c
+@@ -120,6 +120,212 @@
+ #define PRE(name)       DEFN_PRE_TEMPLATE(openbsd, name)
+ #define POST(name)      DEFN_POST_TEMPLATE(openbsd, name)
+ 
++extern UWord do_syscall_tfork_amd64_openbsd (
++        Addr params,
++        UWord psize,
++        Addr startfunc,
++        Addr startarg);
++asm(
++".text\n"
++".globl do_syscall_tfork_amd64_openbsd\n"
++"do_syscall_tfork_amd64_openbsd:\n"
++      /* Copy %rdx to %r8 and %rcx to %r9.  See:
++         - lib/libc/arch/amd64/sys/tfork_thread.S */
++"     movq    %rdx, %r8\n"
++"     movq    %rcx, %r9\n"
++"     movq    $8, %rax\n"             /* syscall_no */
++"     syscall\n"
++"     jb      5f\n"                   /* error */
++      /*
++       * Check to see if we are in the parent or child
++       */
++"     cmpl    $0, %eax\n"
++"     jz      4f\n"                   /* child */
++"     jmp     5f\n"                   /* parent */
++      /* the retpoline we'll use to call the child's main */
++".align       16, 0xcc\n"                     /* _ALIGN_TRAPS */
++"1:\n"                                        /* JMP_RETPOLINE(r8) --> */
++"     call    3f\n"
++"2:   pause\n"
++"     lfence\n"
++"     jmp     2b\n"
++".align       16, 0xcc\n"                     /* _ALIGN_TRAPS */
++"3:   mov     %r8,(%rsp)\n"
++"     ret\n"
++                                      /* JMP_RETPOLINE(r8) <-- */
++      /*
++       * If we are in the child (new thread), then
++       * set-up the call to the internal subroutine.  If it
++       * returns, then call __threxit.
++       */
++".align       16, 0xcc\n"                     /* _ALIGN_TRAPS */
++"4:\n"
++"     movq    %r9, %rdi\n"
++"     call    1b\n"
++      /*
++       * Thread exit system call
++       */
++"     movl    $302, %eax\n"           /* 302 == SYS___threxit */
++"     xorl    %edi, %edi\n"
++"     syscall\n"
++      /*NOTREACHED*/
++"5:\n"                                        /* parent or error */
++"     ret\n"
++".previous\n"
++);
++
++static void setup_child ( ThreadArchState*, ThreadArchState* );
++
++void setup_child ( /*OUT*/ ThreadArchState *child,
++                   /*IN*/  ThreadArchState *parent )
++{
++   /* We inherit our parent's guest state. */
++   child->vex = parent->vex;
++   child->vex_shadow1 = parent->vex_shadow1;
++   child->vex_shadow2 = parent->vex_shadow2;
++}
++
++/*
++   When a client clones, we need to keep track of the new thread.  This means:
++   1. allocate a ThreadId+ThreadState+stack for the the thread
++
++   2. initialize the thread's new VCPU state
++
++   3. create the thread using the same args as the client requested,
++   but using the scheduler entrypoint for EIP, and a separate stack
++   for ESP.
++
++   This function was implemented with reference to the syswrap-amd64-linux.c:
++   do_clone() function.
++ */
++static SysRes do_tfork_thread ( ThreadId ptid,
++                         Addr params,
++                         ULong psize,
++                         Addr startfunc,
++                         Addr startarg)
++{
++   ThreadId     ctid = VG_(alloc_ThreadState)();
++   ThreadState* ptst = VG_(get_ThreadState)(ptid);
++   ThreadState* ctst = VG_(get_ThreadState)(ctid);
++   UWord*       stack;
++   SysRes       res;
++   Long         rax;
++   vki_sigset_t blockall, savedmask;
++   struct __vki_tfork * tfork;
++
++   VG_(sigfillset)(&blockall);
++
++   vg_assert(params != 0);
++   vg_assert(psize > 0);
++   vg_assert(startfunc != 0);
++   vg_assert(VG_(is_running_thread)(ptid));
++   vg_assert(VG_(is_valid_tid)(ctid));
++
++   stack = (UWord*)ML_(allocstack)(ctid);
++   if (stack == NULL) {
++      res = VG_(mk_SysRes_Error)( VKI_ENOMEM );
++      goto out;
++   }
++
++   /* Copy register state
++
++      Both parent and child return to the same place, and the code
++      following the __tfork_thread syscall works out which is which, so we
++      don't need to worry about it.
++
++      The parent gets the child's new tid returned from clone, but the
++      child gets 0.
++
++      If the clone call specifies a NULL tfork->tf_stack for the new thread,
++      then it actually gets a copy of the parent's rsp.
++   */
++   setup_child( &ctst->arch, &ptst->arch );
++
++   /* Make sys___tfork appear to have returned Success(0) in the
++      child. */
++   ctst->arch.vex.guest_RAX = 0;
++
++   tfork = (struct __vki_tfork *)params;
++   vg_assert(tfork->tf_stack != 0);
++   ctst->arch.vex.guest_RSP = (ULong) tfork->tf_stack;
++   tfork->tf_stack = stack;
++
++   ctst->os_state.parent = ptid;
++
++   /* inherit signal mask */
++   ctst->sig_mask = ptst->sig_mask;
++   ctst->tmp_sig_mask = ptst->sig_mask;
++
++   /* Start the child with its threadgroup being the same as the
++      parent's.  This is so that any exit_group calls that happen
++      after the child is created but before it sets its
++      os_state.threadgroup field for real (in thread_wrapper in
++      syswrap-linux.c), really kill the new thread.  a.k.a this avoids
++      a race condition in which the thread is unkillable (via
++      exit_group) because its threadgroup is not set.  The race window
++      is probably only a few hundred or a few thousand cycles long.
++      See #226116. */
++   ctst->os_state.threadgroup = ptst->os_state.threadgroup;
++
++   ML_(guess_and_register_stack) ((Addr)tfork->tf_stack, ctst);
++
++   /* Assume the clone will succeed, and tell any tool that wants to
++      know that this thread has come into existence.  If the clone
++      fails, we'll send out a ll_exit notification for it at the out:
++      label below, to clean up. */
++   vg_assert(VG_(owns_BigLock_LL)(ptid));
++   VG_TRACK ( pre_thread_ll_create, ptid, ctid );
++
++   /* start the thread with everything blocked */
++#if 1 /* for debug by asou */
++   VG_(sigdelset)(&blockall, VKI_SIGTRAP);
++#endif
++   VG_(sigprocmask)(VKI_SIG_SETMASK, &blockall, &savedmask);
++
++   /* Create the new thread */
++   rax = do_syscall_tfork_amd64_openbsd(
++            params, psize, ML_(start_thread_NORETURN), &VG_(threads)[ctid]);
++   res = VG_(mk_SysRes_amd64_openbsd)( rax, ptst->arch.vex.guest_RDX,
++                                     (rax == -1) ? True : False );
++
++   VG_(sigprocmask)(VKI_SIG_SETMASK, &savedmask, NULL);
++
++  out:
++   if (sr_isError(res)) {
++      /* clone failed */
++      VG_(cleanup_thread)(&ctst->arch);
++      ctst->status = VgTs_Empty;
++      /* oops.  Better tell the tool the thread exited in a hurry :-) */
++      VG_TRACK( pre_thread_ll_exit, ctid );
++   }
++
++   return res;
++}
++
++PRE(sys___tfork_thread)
++{
++   struct __vki_tfork * tfork;
++   PRINT("sys___tfork_thread ( %#lx, %ld, %#lx, %#lx )",ARG1,ARG2,ARG3,ARG4);
++   PRE_REG_READ4(long, "__tfork_thread", struct __tfork *, params, size_t, 
psize,
++               void (*)(void *), startfunc, void *, startarg);
++   PRE_MEM_READ( "__tfork_thread(params, psize)", ARG1, ARG2 );
++   tfork = (struct __vki_tfork *)ARG1;
++   if (tfork->tf_tid != NULL)
++      PRE_MEM_READ("__tfork_thread(params.tf_tid)", (Addr)tfork->tf_tid,
++                 sizeof (pid_t));
++   SET_STATUS_from_SysRes(
++      do_tfork_thread(tid, (Addr)ARG1, (ULong)ARG2, (Addr)ARG3, (Addr)ARG4));
++
++   if (SUCCESS) {
++      POST_MEM_WRITE((Addr)tfork->tf_tcb, sizeof (void *));
++      POST_MEM_WRITE((Addr)tfork->tf_tid, sizeof (pid_t));
++
++      /* Thread creation was successful; let the child have the chance
++         to run */
++      *flags |= SfYieldAfter;
++   }
++}
++
+ #if 0
+ PRE(sys_thr_new)
+ {
Index: patches/patch-coregrind_m_syswrap_syswrap_generic_c
===================================================================
RCS file: patches/patch-coregrind_m_syswrap_syswrap_generic_c
diff -N patches/patch-coregrind_m_syswrap_syswrap_generic_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-coregrind_m_syswrap_syswrap_generic_c 9 Dec 2019 05:30:18 
-0000
@@ -0,0 +1,16 @@
+--- coregrind/m_syswrap/syswrap-generic.c.orig
++++ coregrind/m_syswrap/syswrap-generic.c
+@@ -2240,7 +2240,13 @@
+    /* Otherwise we're OK (so far).  Install aspacem's choice of
+       address, and let the mmap go through.  */
+    sres = VG_(am_do_mmap_NO_NOTIFY)(advised, arg2, arg3,
++#if defined(VGO_openbsd)
++      /* Could not specified VKI_MAP_STACK and VKI_MAP_FIXED at the same
++         time */
++                                    arg4,
++#else
+                                     arg4 | VKI_MAP_FIXED,
++#endif
+                                     arg5, arg6);
+ 
+    /* A refinement: it may be that the kernel refused aspacem's choice
Index: patches/patch-coregrind_m_syswrap_syswrap_openbsd_c
===================================================================
RCS file: 
/cvs/ports/devel/valgrind/patches/patch-coregrind_m_syswrap_syswrap_openbsd_c,v
retrieving revision 1.1
diff -u -p -r1.1 patch-coregrind_m_syswrap_syswrap_openbsd_c
--- patches/patch-coregrind_m_syswrap_syswrap_openbsd_c 23 Oct 2019 02:35:05 
-0000      1.1
+++ patches/patch-coregrind_m_syswrap_syswrap_openbsd_c 9 Dec 2019 05:30:18 
-0000
@@ -1,6 +1,43 @@
 --- coregrind/m_syswrap/syswrap-openbsd.c.orig
 +++ coregrind/m_syswrap/syswrap-openbsd.c
-@@ -575,6 +579,17 @@
+@@ -210,21 +210,21 @@
+       /*    : "n" (VgTs_Empty), "n" (__NR_thr_exit), "m" 
(tst->os_state.exitcode) */
+       /*    : "eax", "ebx" */
+       /* ); */
+-/* #elif defined(VGP_amd64_openbsd) */
+-      /* asm volatile ( */
+-         /* "movl     %1, %0\n"       /\* set tst->status = VgTs_Empty *\/ */
+-         /* "movq     %2, %%rax\n"    /\* set %rax = __NR_thr_exit *\/ */
+-         /* "movq     %3, %%rdi\n"    /\* set %rdi = tst->os_state.exitcode 
*\/ */
+-       /* "pushq      %%rdi\n"        /\* fake return address *\/ */
+-         /* "syscall\n"               /\* thr_exit(tst->os_state.exitcode) 
*\/ */
+-       /* "popq       %%rdi\n"        /\* fake return address *\/ */
+-         /* : "=m" (tst->status) */
+-         /* : "n" (VgTs_Empty), "n" (__NR_thr_exit), "m" 
(tst->os_state.exitcode) */
+-         /* : "rax", "rdi" */
+-      /* ); */
+-/* #else */
+-/* # error Unknown platform */
+-/* #endif */
++#if defined(VGP_amd64_openbsd)
++      asm volatile (
++         "movl        %1, %0\n"       /* set tst->status = VgTs_Empty */
++         "movq        %2, %%rax\n"    /* set %rax = __NR_thr_exit */
++         "movq        %3, %%rdi\n"    /* set %rdi = tst->os_state.exitcode */
++       "pushq %%rdi\n"        /* fake return address */
++         "syscall\n"          /* thr_exit(tst->os_state.exitcode) */
++       "popq  %%rdi\n"        /* fake return address */
++         : "=m" (tst->status)
++         : "n" (VgTs_Empty), "n" (__NR___threxit), "m" 
(tst->os_state.exitcode)
++         : "rax", "rdi"
++      );
++#else
++# error Unknown platform
++#endif
+ 
+       VG_(core_panic)("Thread exit failed?\n");
+    }
+@@ -575,6 +575,17 @@
  // XXXTBD
  }
  
@@ -18,7 +55,154 @@
  PRE(sys_getsockname)
  {
     PRINT("sys_getsockname ( %ld, %#lx, %#lx )",ARG1,ARG2,ARG3);
-@@ -4079,7 +4093,7 @@
+@@ -791,15 +791,6 @@
+    SET_STATUS_Success(0);
+ }
+ 
+-PRE(sys___tfork)
+-{
+-// XXXTBD
+-}
+-POST(sys___tfork)
+-{
+-// XXXTBD
+-}
+-
+ PRE(sys_getlogin)
+ {
+    PRINT("sys_getlogin ( %#lx, %ld )",ARG1,ARG2);
+@@ -2787,17 +2778,40 @@
+ 
+ PRE(sys___thrsleep)
+ {
+-// XXXTBD
++   *flags |= SfMayBlock;
++   PRINT("__thrsleep( %#lx, %ld, %#lx, %#lx, %#lx )", 
ARG1,ARG2,ARG3,ARG4,ARG5);
++   PRE_REG_READ5(int, "__thrsleep",
++                 void *, id,
++                 int, clock_id,
++                 struct timespec *, abstime,
++                 void *, lock,
++                 int *, abort);
++   if (ARG3 != 0)
++      PRE_MEM_READ(" __thrsleep(abstime)", ARG3, sizeof(struct timespec));
++   if (ARG5 != 0)
++      PRE_MEM_READ(" __thrsleep(abort)", ARG5, sizeof (int));
+ }
+ 
+ PRE(sys___thrwakeup)
+ {
+-// XXXTBD
++   PRINT("__thrwakeup( %#lx, %ld, %#lx, %#lx, %#lx )", 
ARG1,ARG2,ARG3,ARG4,ARG5);
++   PRE_REG_READ2(int, "__thrwakeup",
++                 void *, id,
++                 int, count);
+ }
+ 
+ PRE(sys___threxit)
+ {
+-// XXXTBD
++   ThreadState* tst;
++   /* simple; just make this thread exit */
++   PRINT("__threxit( %#lx )", ARG1);
++   PRE_REG_READ1(void, "__threxit", void *, value_ptr);
++   tst = VG_(get_ThreadState)(tid);
++   /* Set the thread's status to be exiting, then claim that the
++      syscall succeeded. */
++   tst->exitreason = VgSrc_ExitThread;
++   /* tst->os_state.exitcode = ARG1; */
++   SET_STATUS_Success(0);
+ }
+ 
+ PRE(sys___thrsigdivert)
+@@ -2830,6 +2843,68 @@
+ // XXXTBD
+ }
+ 
++PRE(sys_futex)
++{
++   /*
++      arg    param                              used by ops
++
++      ARG1 - uint32_t *uaddr                  all
++      ARG2 - int op
++      ARG3 - int val                          WAIT,WAKE,REQUEUE
++      ARG4 - struct timespec *utime           WAIT,     REQUEUE
++      ARG5 - uint32_t *uaddr2                           REQUEUE
++    */
++   PRINT("sys_futex ( %#lx, %ld, %ld, %#lx, %#lx )", 
ARG1,ARG2,ARG3,ARG4,ARG5);
++   switch(ARG2 & ~VKI_FUTEX_PRIVATE_FLAG) {
++   case VKI_FUTEX_WAIT:
++      PRE_REG_READ4(long, "futex",
++                    vki_uint32_t *, uaddr, int, op, int, val,
++                    struct timespec *, utime);
++      break;
++   case VKI_FUTEX_WAKE:
++      PRE_REG_READ3(long, "futex",
++                    vki_uint32_t *, uaddr, int, op, int, val);
++      break;
++   case VKI_FUTEX_REQUEUE:
++      PRE_REG_READ5(long, "futex",
++                    vki_uint32_t *, uaddr, int, op, int, val,
++                    struct timespec *, utime, vki_uint32_t *, uaddr2);
++      break;
++   default:
++      PRE_REG_READ2(long, "futex", vki_uint32_t *, uaddr, int, op);
++      break;
++   }
++
++   *flags |= SfMayBlock;
++
++   switch(ARG2 & ~VKI_FUTEX_PRIVATE_FLAG) {
++   case VKI_FUTEX_WAIT:
++      PRE_MEM_READ( "futex(uaddr)", ARG1, sizeof(Int) );
++      if (ARG4 != 0)
++       PRE_MEM_READ( "futex(timeout)", ARG4, sizeof(struct vki_timespec) );
++      break;
++
++   case VKI_FUTEX_WAKE:
++      /* no additional pointers */
++      break;
++
++   case VKI_FUTEX_REQUEUE:
++      PRE_MEM_READ( "futex(uaddr)", ARG1, sizeof(Int) );
++      PRE_MEM_READ( "futex(val2)", ARG4, sizeof(Int) );
++      PRE_MEM_READ( "futex(uaddr2)", ARG5, sizeof(Int) );
++      break;
++
++   default:
++      SET_STATUS_Failure( VKI_ENOSYS );   // some futex function we don't 
understand
++      break;
++   }
++}
++POST(sys_futex)
++{
++   vg_assert(SUCCESS);
++   POST_MEM_WRITE( ARG1, sizeof(int) );
++}
++
+ PRE(sys_utimensat)
+ {
+ // XXXTBD
+@@ -3961,7 +4036,7 @@
+   
+   GENXY(__NR_close,           sys_close),             // 6
+   BSDXY(__NR_getentropy,      sys_getentropy),        // 7
+-  BSDXY(__NR___tfork,         sys___tfork),           // 8
++  BSDX_(__NR___tfork_thread,  sys___tfork_thread),    // 8
+   GENX_(__NR_link,            sys_link),              // 9
+   GENX_(__NR_unlink,          sys_unlink),            // 10
+   
+@@ -4053,7 +4128,7 @@
+ 
+   GENX_(__NR_getpgrp,         sys_getpgrp),           // 81
+   GENX_(__NR_setpgid,         sys_setpgid),           // 82
+-  BSDX_(__NR_osendsyslog,     sys_sendsyslog),        // 83
++  BSDXY(__NR_futex,           sys_futex),             // 83
+   BSDX_(__NR_utimensat,               sys_utimensat),         // 84
+   BSDX_(__NR_futimens,                sys_futimens),          // 85
+ 
+@@ -4079,7 +4094,7 @@
    BSDX_(__NR_sigsuspend,      sys_sigsuspend),        // 111
    BSDX_(__NR_sendsyslog,      sys_sendsyslog),        // 112
    // obsol orecvmsg                                   // 113
@@ -27,4 +211,3 @@
    // obsol vtrace                                     // 115
  
    BSDX_(__NR_getsockopt,      sys_getsockopt),        // 118
-Only in pobj/valgrind-3.10.1/valgrind-3.10.1/coregrind/m_syswrap: 
syswrap-openbsd.c.orig
Index: patches/patch-coregrind_m_syswrap_syswrap_x86_openbsd_c
===================================================================
RCS file: patches/patch-coregrind_m_syswrap_syswrap_x86_openbsd_c
diff -N patches/patch-coregrind_m_syswrap_syswrap_x86_openbsd_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-coregrind_m_syswrap_syswrap_x86_openbsd_c     9 Dec 2019 
05:30:18 -0000
@@ -0,0 +1,18 @@
+--- coregrind/m_syswrap/syswrap-x86-openbsd.c.orig
++++ coregrind/m_syswrap/syswrap-x86-openbsd.c
+@@ -525,6 +525,15 @@
+ #define PRE(name)       DEFN_PRE_TEMPLATE(openbsd, name)
+ #define POST(name)      DEFN_POST_TEMPLATE(openbsd, name)
+ 
++PRE(sys___tfork_thread)
++{
++// XXXTBD
++}
++POST(sys___tfork_thread)
++{
++// XXXTBD
++}
++
+ #if 0
+ struct thr_param {
+     void        (*start_func)(void *);  /* thread entry function. */
Index: patches/patch-include_vki_vki-openbsd_h
===================================================================
RCS file: /cvs/ports/devel/valgrind/patches/patch-include_vki_vki-openbsd_h,v
retrieving revision 1.1
diff -u -p -r1.1 patch-include_vki_vki-openbsd_h
--- patches/patch-include_vki_vki-openbsd_h     2 Oct 2019 17:19:29 -0000       
1.1
+++ patches/patch-include_vki_vki-openbsd_h     9 Dec 2019 05:30:18 -0000
@@ -1,5 +1,21 @@
 --- include/vki/vki-openbsd.h.orig
 +++ include/vki/vki-openbsd.h
+@@ -76,6 +76,15 @@
+ 
+ 
+ //----------------------------------------------------------------------
++// From linux-2.6.31-rc4/include/linux/futex.h
++//----------------------------------------------------------------------
++
++#define VKI_FUTEX_WAIT (1)
++#define VKI_FUTEX_WAKE (2)
++#define VKI_FUTEX_REQUEUE (3)
++#define VKI_FUTEX_PRIVATE_FLAG (128)
++
++//----------------------------------------------------------------------
+ // From sys/select.h
+ //----------------------------------------------------------------------
+ 
 @@ -1544,9 +1544,9 @@
  #define VKI_MAP_PRIVATE       0x02            /* Changes are private */
  #define VKI_MAP_FIXED 0x10            /* Interpret addr exactly */
@@ -11,3 +27,16 @@
 
  //----------------------------------------------------------------------
  // From sys/stat.h
+@@ -1650,6 +1659,12 @@
+ #define VKI_X_OK      0x01    /* test for execute or search permission */
+ #define VKI_W_OK      0x02    /* test for write permission */
+ #define VKI_R_OK      0x04    /* test for read permission */
++
++struct __vki_tfork {
++      void    *tf_tcb;
++      pid_t   *tf_tid;
++      void    *tf_stack;
++};
+ 
+ //----------------------------------------------------------------------
+ // From sys/msg.h
Index: patches/patch-include_vki_vki_scnums_openbsd_h
===================================================================
RCS file: 
/cvs/ports/devel/valgrind/patches/patch-include_vki_vki_scnums_openbsd_h,v
retrieving revision 1.1
diff -u -p -r1.1 patch-include_vki_vki_scnums_openbsd_h
--- patches/patch-include_vki_vki_scnums_openbsd_h      23 Oct 2019 02:35:05 
-0000      1.1
+++ patches/patch-include_vki_vki_scnums_openbsd_h      9 Dec 2019 05:30:18 
-0000
@@ -1,5 +1,23 @@
 --- include/vki/vki-scnums-openbsd.h.orig
 +++ include/vki/vki-scnums-openbsd.h
+@@ -41,7 +41,7 @@
+ #define       __NR_open               5
+ #define       __NR_close              6
+ #define       __NR_getentropy         7
+-#define       __NR___tfork            8
++#define       __NR___tfork_thread     8
+ #define       __NR_link               9
+ #define       __NR_unlink             10
+ #define       __NR_wait4              11
+@@ -116,7 +116,7 @@
+ #define       __NR_setgroups          80
+ #define       __NR_getpgrp            81
+ #define       __NR_setpgid            82
+-#define       __NR_osendsyslog        83
++#define       __NR_futex              83
+ #define __NR_utimensat                84
+ #define __NR_futimens         85
+ #define __NR_kbind            86
 @@ -146,6 +146,7 @@
  #define       __NR_pselect            110
  #define       __NR_sigsuspend         111
--
ASOU Masato
#include <err.h>
#include <limits.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <unistd.h>

#define MAX_NTHREADS 64

static void *
sub(void *arg)
{
        static int retval[MAX_NTHREADS];
        struct timeval tv;
        int id = *(int *)arg;
        int i;

        for (i = 0; i < 5; i++) {
                printf("Thread: %d: %d\n", id, i);
                usleep(100 * 1000);
        }

        gettimeofday(&tv, NULL);
        retval[id] = tv.tv_usec % ((id + 1) * 1000);
        printf("Thread: %d: retval = %d\n", id, retval[id]);
        return &retval[id];
}

pthread_t thread[MAX_NTHREADS];
int thrid[MAX_NTHREADS];
int result[MAX_NTHREADS];
void *value[MAX_NTHREADS];

static void
th_create(int id)
{
        thrid[id] = id;
        result[id] = -1;
        value[id] = NULL;

        result[id] = pthread_create(&thread[id], NULL, sub, &thrid[id]);
        if (result[id] != 0) {
                fprintf(stderr, "pthread_create: %d: error = %d\n",
                    thrid[id], result[0]);
        }
}

static void
th_join(int id)
{
        int *val;

        if (result[id] == 0) {
                pthread_join(thread[id], &value[id]);
                val = value[id];
                if (val != NULL)
                        printf("Thread: %d: value = %d\n", thrid[id], *val);
        }
}

int
main(int argc, char *argv[])
{
        int nthreads = 4;
        int count = 1;
        int icnt, ith, idx;

        if (argc >= 2) {
                int nthrs;

                nthrs = strtol(argv[1], NULL, 0);
                if (nthrs > 0 && nthrs <= MAX_NTHREADS)
                        nthreads = nthrs;
        }
        if (argc >= 3) {
                int cnt;

                cnt = strtol(argv[2], NULL, 0);
                if (cnt > 0)
                        count = cnt;
        }

        idx = 0;
        for (icnt = 0; icnt < count; icnt++) {
                for (ith = 0; ith < nthreads; ith++)
                        th_create(idx + ith);
                for (ith = 0; ith < nthreads; ith++)
                        th_join(idx + ith);
                idx += ith;

                if (idx >= MAX_NTHREADS)
                        idx = 0;
        }

        return (0);
}

Reply via email to