فهرست منبع

LibPthread: Return errors as positive return values

pthread implementations generally return errors as a positive non-zero
value. Our kernel generally returns errors as negative values. If we
receive a negative value from a system call, turn it into a positive
return value to relay the error appropriately.

Also, fix the tt test utility to not rely on errno, as the pthread
library does not use errno.
Tom 4 سال پیش
والد
کامیت
bcb9363a97
2فایلهای تغییر یافته به همراه22 افزوده شده و 17 حذف شده
  1. 17 11
      Libraries/LibPthread/pthread.cpp
  2. 5 6
      Userland/tt.cpp

+ 17 - 11
Libraries/LibPthread/pthread.cpp

@@ -48,6 +48,9 @@ constexpr size_t required_stack_alignment = 4 * MiB;
 constexpr size_t highest_reasonable_guard_size = 32 * PAGE_SIZE;
 constexpr size_t highest_reasonable_guard_size = 32 * PAGE_SIZE;
 constexpr size_t highest_reasonable_stack_size = 8 * MiB; // That's the default in Ubuntu?
 constexpr size_t highest_reasonable_stack_size = 8 * MiB; // That's the default in Ubuntu?
 
 
+#define __RETURN_PTHREAD_ERROR(rc) \
+    return ((rc) < 0 ? -(rc) : 0)
+
 extern "C" {
 extern "C" {
 
 
 static void* pthread_create_helper(void* (*routine)(void*), void* argument)
 static void* pthread_create_helper(void* (*routine)(void*), void* argument)
@@ -57,7 +60,7 @@ static void* pthread_create_helper(void* (*routine)(void*), void* argument)
     return nullptr;
     return nullptr;
 }
 }
 
 
-static int create_thread(void* (*entry)(void*), void* argument, PthreadAttrImpl* thread_params)
+static int create_thread(pthread_t* thread, void* (*entry)(void*), void* argument, PthreadAttrImpl* thread_params)
 {
 {
     void** stack = (void**)((uintptr_t)thread_params->m_stack_location + thread_params->m_stack_size);
     void** stack = (void**)((uintptr_t)thread_params->m_stack_location + thread_params->m_stack_size);
 
 
@@ -80,7 +83,10 @@ static int create_thread(void* (*entry)(void*), void* argument, PthreadAttrImpl*
     // Push a fake return address
     // Push a fake return address
     push_on_stack(nullptr);
     push_on_stack(nullptr);
 
 
-    return syscall(SC_create_thread, pthread_create_helper, thread_params);
+    int rc = syscall(SC_create_thread, pthread_create_helper, thread_params);
+    if (rc >= 0)
+        *thread = rc;
+    __RETURN_PTHREAD_ERROR(rc);
 }
 }
 
 
 [[noreturn]] static void exit_thread(void* code)
 [[noreturn]] static void exit_thread(void* code)
@@ -124,11 +130,7 @@ int pthread_create(pthread_t* thread, pthread_attr_t* attributes, void* (*start_
         used_attributes->m_stack_location);
         used_attributes->m_stack_location);
 #endif
 #endif
 
 
-    int rc = create_thread(start_routine, argument_to_start_routine, used_attributes);
-    if (rc < 0)
-        return rc;
-    *thread = rc;
-    return 0;
+    return create_thread(thread, start_routine, argument_to_start_routine, used_attributes);
 }
 }
 
 
 void pthread_exit(void* value_ptr)
 void pthread_exit(void* value_ptr)
@@ -138,12 +140,14 @@ void pthread_exit(void* value_ptr)
 
 
 int pthread_join(pthread_t thread, void** exit_value_ptr)
 int pthread_join(pthread_t thread, void** exit_value_ptr)
 {
 {
-    return syscall(SC_join_thread, thread, exit_value_ptr);
+    int rc = syscall(SC_join_thread, thread, exit_value_ptr);
+    __RETURN_PTHREAD_ERROR(rc);
 }
 }
 
 
 int pthread_detach(pthread_t thread)
 int pthread_detach(pthread_t thread)
 {
 {
-    return syscall(SC_detach_thread, thread);
+    int rc = syscall(SC_detach_thread, thread);
+    __RETURN_PTHREAD_ERROR(rc);
 }
 }
 
 
 int pthread_sigmask(int how, const sigset_t* set, sigset_t* old_set)
 int pthread_sigmask(int how, const sigset_t* set, sigset_t* old_set)
@@ -599,12 +603,14 @@ int pthread_setname_np(pthread_t thread, const char* name)
 {
 {
     if (!name)
     if (!name)
         return EFAULT;
         return EFAULT;
-    return syscall(SC_set_thread_name, thread, name, strlen(name));
+    int rc = syscall(SC_set_thread_name, thread, name, strlen(name));
+    __RETURN_PTHREAD_ERROR(rc);
 }
 }
 
 
 int pthread_getname_np(pthread_t thread, char* buffer, size_t buffer_size)
 int pthread_getname_np(pthread_t thread, char* buffer, size_t buffer_size)
 {
 {
-    return syscall(SC_get_thread_name, thread, buffer, buffer_size);
+    int rc = syscall(SC_get_thread_name, thread, buffer, buffer_size);
+    __RETURN_PTHREAD_ERROR(rc);
 }
 }
 
 
 } // extern "C"
 } // extern "C"

+ 5 - 6
Userland/tt.cpp

@@ -162,19 +162,18 @@ int detached_test()
             return nullptr;
             return nullptr;
         },
         },
         nullptr);
         nullptr);
-    if (rc < 0) {
-        perror("pthread_create");
+    if (rc != 0) {
+        printf("pthread_create: %s\n", strerror(rc));
         return 4;
         return 4;
     }
     }
 
 
     void* ret_val;
     void* ret_val;
-    errno = 0;
     rc = pthread_join(thread_id, &ret_val);
     rc = pthread_join(thread_id, &ret_val);
-    if (rc < 0 && errno != EINVAL) {
-        perror("pthread_join");
+    if (rc != 0 && rc != EINVAL) {
+        printf("pthread_join: %s\n", strerror(rc));
         return 5;
         return 5;
     }
     }
-    if (errno != EINVAL) {
+    if (rc != EINVAL) {
         printf("Expected EINVAL! Thread was joinable?\n");
         printf("Expected EINVAL! Thread was joinable?\n");
         return 6;
         return 6;
     }
     }