_ssize_t
write (int fdi, const void *buf, size_t cnt)
{
  if (fdi < 0 || fdi >= _fd_size)
    {
      errno = EBADF;
      return -1;
    }

  ss_mutex_lock (&_fd_lock);

  struct _fd *fd = _fds[fdi];
  if (! fd || ! fd->ops->pwrite)
    {
      errno = EBADF;
      ss_mutex_unlock (&_fd_lock);
      return -1;
    }

  if (cnt == 0)
    {
      ss_mutex_unlock (&_fd_lock);
      return 0;
    }

  ss_mutex_lock (&fd->lock);
  ss_mutex_unlock (&_fd_lock);

  _ssize_t len = fd->ops->pwrite (fd, buf, cnt, fd->pos);
  fd->pos += len;

  ss_mutex_unlock (&fd->lock);

  return len;
}
Exemple #2
0
void *
sbrk (intptr_t inc)
{
  ss_mutex_lock (&lock);

  if (! endds)
    {
      /* sbrk isn't used that much so 16MB of virtual address space
	 should be enough.  */
#define SIZE 16 * 1024 * 1024
      endds = mmap (0, SIZE, PROT_READ | PROT_WRITE,
		    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
      if (endds == MAP_FAILED)
	{
	  ss_mutex_unlock (&lock);
	  errno = ENOMEM;
	  return (void *) -1;
	}

      brk = endds;
    }

  void *p = brk;
  brk += inc;

  assert (brk >= endds);

  if (brk > endds + SIZE)
    {
      brk -= inc;
      errno = ENOMEM;
      p = (void *) -1;
      debug (0, "sbrk: sbrk memory exhausted!");
    }

  ss_mutex_unlock (&lock);

  return p;
}
Exemple #3
0
void
__pthread_thread_halt (struct __pthread *thread, int need_dealloc)
{
  /* We may deallocate THREAD.  First save any data we need.  */

  addr_t exception_area[EXCEPTION_AREA_SIZE / PAGESIZE];
  memcpy (exception_area, thread->exception_area,
	  sizeof (thread->exception_area));
  memset (thread->exception_area, 0, sizeof (thread->exception_area));

  void *va = thread->exception_area_va;

  addr_t object = thread->object;
  l4_thread_id_t tid = thread->threadid;

  if (need_dealloc)
    __pthread_dealloc (thread);

  /* The THREAD data structure is no longer valid.  */
  thread = NULL;

  /* Deallocate any saved object.  */
  ss_mutex_lock (&saved_object_lock);
  if (! ADDR_IS_VOID (saved_object))
    {
      storage_free (saved_object, false);
      saved_object = ADDR_VOID;
    }
  ss_mutex_unlock (&saved_object_lock);

  /* Free the exception area.  */

  /* Clean up the exception page.  */
  exception_page_cleanup
    (ADDR_TO_PTR (addr_extend (exception_area[EXCEPTION_PAGE],
			       0, PAGESIZE_LOG2)));

  /* Free the storage.  */
  int i;
  for (i = 0; i < EXCEPTION_AREA_SIZE / PAGESIZE; i ++)
    {
      assert (! ADDR_IS_VOID (exception_area[i]));
      storage_free (exception_area[i], false);
    }

  /* And the address space.  */
  as_free (addr_chop (PTR_TO_ADDR (va), EXCEPTION_AREA_SIZE_LOG2), false);

  if (tid == l4_myself ())
    /* If we try to storage_free (storage.addr), we will freeze in the
       middle.  That's no good.  We set SAVED_OBJECT to our thread
       object and the next thread in will free us.  */
    {
      ss_mutex_lock (&saved_object_lock);
      saved_object = object;
      ss_mutex_unlock (&saved_object_lock);
    }
  else
    storage_free (object, false);

  if (tid == l4_myself ())
    {
      l4_send_timeout (l4_myself (), L4_NEVER);
      panic ("Failed to stop thread %x.%x!",
	     l4_thread_no (l4_myself ()), l4_version (l4_myself ()));
    }
  else
    thread_stop (object);
}