Mega-merge of my last 2 weeks hacking.  This basically does the groundwork
for pthread_* support.  Major changes:

* Valgrind now contains a (skeletal!) user-space pthreads
  implementation.  The exciting bits are in new file vg_scheduler.c.
  This contains thread management and scheduling, including nasty crud
  to do with making some syscalls (read,write,nanosleep) nonblocking.
  Also implementation of pthread_ functions: create join
  mutex_{create,destroy,lock,unlock} and cancel.

* As a side effect of the above, major improvements to signal handling
  and to the client-request machinery.  This is now used to intercept
  malloc/free etc too; the hacky way this is done before is gone.
  Another side effect is that vg_dispatch.S is greatly simplified.
  Also, the horrible hacks to do with delivering signals to threads
  blocked in syscalls are gone, since the new mechanisms cover this case
  easily.


git-svn-id: svn://svn.valgrind.org/valgrind/trunk@52 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/vg_mylibc.c b/vg_mylibc.c
index 2ba0753..31f2b18 100644
--- a/vg_mylibc.c
+++ b/vg_mylibc.c
@@ -232,7 +232,7 @@
 
 
 /* ---------------------------------------------------------------------
-   mmap/munmap, exit
+   mmap/munmap, exit, fcntl
    ------------------------------------------------------------------ */
 
 /* Returns -1 on failure. */
@@ -266,6 +266,43 @@
    vg_assert(2+2 == 5);
 }
 
+/* Returns -1 on error. */
+Int VG_(fcntl) ( Int fd, Int cmd, Int arg )
+{
+   Int res = vg_do_syscall3(__NR_fcntl, fd, cmd, arg);
+   return VG_(is_kerror)(res) ? -1 : res;
+}
+
+/* Returns -1 on error. */
+Int VG_(select)( Int n, 
+                 vki_fd_set* readfds, 
+                 vki_fd_set* writefds, 
+                 vki_fd_set* exceptfds, 
+                 struct vki_timeval * timeout )
+{
+   Int res;
+   UInt args[5];
+   args[0] = n;
+   args[1] = (UInt)readfds;
+   args[2] = (UInt)writefds;
+   args[3] = (UInt)exceptfds;
+   args[4] = (UInt)timeout;
+   res = vg_do_syscall1(__NR_select, (UInt)(&(args[0])) );
+   return VG_(is_kerror)(res) ? -1 : res;
+   return res;
+}
+
+/* Returns -1 on error, but 0 if ok or interrupted. */
+Int VG_(nanosleep)( const struct vki_timespec *req, 
+                    struct vki_timespec *rem )
+{
+   Int res;
+   res = vg_do_syscall2(__NR_nanosleep, (UInt)req, (UInt)rem);
+   if (res == -VKI_EINVAL) return -1;
+   return 0;
+}
+
+
 /* ---------------------------------------------------------------------
    printf implementation.  The key function, vg_vprintf(), emits chars 
    into a caller-supplied function.  Distantly derived from:
@@ -809,7 +846,6 @@
                "valgrind", file, line, fn, expr );
    VG_(printf)("Please report this bug to me at: %s\n\n", EMAIL_ADDR);
    VG_(shutdown_logging)();
-   /* vg_restore_SIGABRT(); */
    VG_(exit)(1);
 }
 
@@ -819,7 +855,6 @@
    VG_(printf)("Basic block ctr is approximately %llu\n", VG_(bbs_done) );
    VG_(printf)("Please report this bug to me at: %s\n\n", EMAIL_ADDR);
    VG_(shutdown_logging)();
-   /* vg_restore_SIGABRT(); */
    VG_(exit)(1);
 }
 
@@ -900,6 +935,16 @@
    return res;
 }
 
+/* Read a notional elapsed (wallclock-time) timer, giving a 64-bit
+   microseconds count. */
+ULong VG_(read_microsecond_timer)( void )
+{
+   Int                res;
+   struct vki_timeval tv;
+   res = vg_do_syscall2(__NR_gettimeofday, (UInt)&tv, (UInt)NULL);
+   vg_assert(!VG_(is_kerror)(res));
+   return (1000000ULL * (ULong)(tv.tv_sec)) + (ULong)(tv.tv_usec);
+}
 
 /* ---------------------------------------------------------------------
    Primitive support for bagging memory via mmap.