_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; }
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; }
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); }