Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 2902e1b in mainline


Ignore:
Timestamp:
2012-06-13T13:17:46Z (8 years ago)
Author:
Martin Decky <martin@…>
Branches:
master
Children:
1d4024cf, 375e501
Parents:
faba839
Message:

add support for variable uspace stack size
create individual address space areas for stacks of additional threads (instead of allocating the stack from heap)
avoid memory leaks in program_create()

Files:
16 edited

Legend:

Unmodified
Added
Removed
  • abi/include/proc/uarg.h

    rfaba839 r2902e1b  
    4040        void *uspace_entry;
    4141        void *uspace_stack;
     42        size_t uspace_stack_size;
    4243       
    4344        void (* uspace_thread_function)();
  • kernel/arch/amd64/src/userspace.c

    rfaba839 r2902e1b  
    5555        asm volatile (
    5656                "pushq %[udata_des]\n"
    57                 "pushq %[stack_size]\n"
     57                "pushq %[stack_top]\n"
    5858                "pushq %[ipl]\n"
    5959                "pushq %[utext_des]\n"
     
    6565                "iretq\n"
    6666                :: [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
    67                    [stack_size] "r" (kernel_uarg->uspace_stack + STACK_SIZE),
     67                   [stack_top] "r" ((uint8_t *) kernel_uarg->uspace_stack +
     68                       kernel_uarg->uspace_stack_size),
    6869                   [ipl] "r" (ipl),
    6970                   [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
     
    7475       
    7576        /* Unreachable */
    76         while (1)
    77                 ;
     77        while (1);
    7878}
    7979
  • kernel/arch/arm32/src/userspace.c

    rfaba839 r2902e1b  
    9292
    9393        /* set user stack */
    94         ustate.sp = ((uint32_t)kernel_uarg->uspace_stack) + STACK_SIZE;
     94        ustate.sp = ((uint32_t) kernel_uarg->uspace_stack) +
     95            kernel_uarg->uspace_stack_size;
    9596
    9697        /* set where uspace execution starts */
  • kernel/arch/ia32/src/userspace.c

    rfaba839 r2902e1b  
    6363               
    6464                "pushl %[udata_des]\n"
    65                 "pushl %[stack_size]\n"
     65                "pushl %[stack_top]\n"
    6666                "pushl %[ipl]\n"
    6767                "pushl %[utext_des]\n"
     
    7575                :
    7676                : [udata_des] "i" (GDT_SELECTOR(UDATA_DES) | PL_USER),
    77                   [stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + STACK_SIZE),
     77                  [stack_top] "r" ((uint8_t *) kernel_uarg->uspace_stack +
     78                      kernel_uarg->uspace_stack_size),
    7879                  [ipl] "r" (ipl),
    7980                  [utext_des] "i" (GDT_SELECTOR(UTEXT_DES) | PL_USER),
  • kernel/arch/ia64/src/ia64.c

    rfaba839 r2902e1b  
    232232         *
    233233         * When calculating stack addresses, mind the stack split between the
    234          * memory stack and the RSE stack. Each occuppies STACK_SIZE / 2 bytes.
     234         * memory stack and the RSE stack. Each occuppies
     235         * uspace_stack_size / 2 bytes.
    235236         */
    236237        switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
    237             ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE / 2 -
     238            ((uintptr_t) kernel_uarg->uspace_stack) +
     239            kernel_uarg->uspace_stack_size / 2 -
    238240            ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT),
    239             ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE / 2,
     241            ((uintptr_t) kernel_uarg->uspace_stack) +
     242            kernel_uarg->uspace_stack_size / 2,
    240243            (uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value);
    241 
    242         while (1)
    243                 ;
     244       
     245        while (1);
    244246}
    245247
  • kernel/arch/mips32/src/mips32.c

    rfaba839 r2902e1b  
    211211            cp0_status_um_bit | cp0_status_ie_enabled_bit));
    212212        cp0_epc_write((uintptr_t) kernel_uarg->uspace_entry);
    213         userspace_asm(((uintptr_t) kernel_uarg->uspace_stack + STACK_SIZE),
     213        userspace_asm(((uintptr_t) kernel_uarg->uspace_stack +
     214            kernel_uarg->uspace_stack_size),
    214215            (uintptr_t) kernel_uarg->uspace_uarg,
    215216            (uintptr_t) kernel_uarg->uspace_entry);
  • kernel/arch/mips64/src/mips64.c

    rfaba839 r2902e1b  
    188188            cp0_status_um_bit | cp0_status_ie_enabled_bit));
    189189        cp0_epc_write((uintptr_t) kernel_uarg->uspace_entry);
    190         userspace_asm(((uintptr_t) kernel_uarg->uspace_stack + STACK_SIZE),
     190        userspace_asm(((uintptr_t) kernel_uarg->uspace_stack +
     191            kernel_uarg->uspace_stack_size),
    191192            (uintptr_t) kernel_uarg->uspace_uarg,
    192193            (uintptr_t) kernel_uarg->uspace_entry);
  • kernel/arch/ppc32/src/ppc32.c

    rfaba839 r2902e1b  
    269269{
    270270        userspace_asm((uintptr_t) kernel_uarg->uspace_uarg,
    271             (uintptr_t) kernel_uarg->uspace_stack + STACK_SIZE - SP_DELTA,
     271            (uintptr_t) kernel_uarg->uspace_stack +
     272            kernel_uarg->uspace_stack_size - SP_DELTA,
    272273            (uintptr_t) kernel_uarg->uspace_entry);
    273274       
  • kernel/arch/sparc64/src/sun4u/sparc64.c

    rfaba839 r2902e1b  
    156156        (void) interrupts_disable();
    157157        switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
    158             ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE
    159             - (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
     158            ((uintptr_t) kernel_uarg->uspace_stack) +
     159            kernel_uarg->uspace_stack_size -
     160            (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
    160161            (uintptr_t) kernel_uarg->uspace_uarg);
    161 
    162         for (;;)
    163                 ;
    164         /* not reached */
     162       
     163        /* Not reached */
     164        while (1);
    165165}
    166166
  • kernel/arch/sparc64/src/sun4v/sparc64.c

    rfaba839 r2902e1b  
    154154        (void) interrupts_disable();
    155155        switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry,
    156             ((uintptr_t) kernel_uarg->uspace_stack) + STACK_SIZE
    157             - (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
     156            ((uintptr_t) kernel_uarg->uspace_stack) +
     157            kernel_uarg->uspace_stack_size -
     158            (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS),
    158159            (uintptr_t) kernel_uarg->uspace_uarg);
    159 
    160         for (;;)
    161                 ;
    162         /* not reached */
     160       
     161        /* Not reached */
     162        while (1);
    163163}
    164164
  • kernel/generic/src/main/uinit.c

    rfaba839 r2902e1b  
    5656void uinit(void *arg)
    5757{
    58         uspace_arg_t uarg;
    59        
    6058        /*
    6159         * So far, we don't have a use for joining userspace threads so we
     
    7270#endif
    7371       
    74         uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry;
    75         uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack;
    76         uarg.uspace_uarg = ((uspace_arg_t *) arg)->uspace_uarg;
    77         uarg.uspace_thread_function = NULL;
    78         uarg.uspace_thread_arg = NULL;
     72        uspace_arg_t *uarg = (uspace_arg_t *) arg;
     73        uspace_arg_t local_uarg;
    7974       
    80         free((uspace_arg_t *) arg);
     75        local_uarg.uspace_entry = uarg->uspace_entry;
     76        local_uarg.uspace_stack = uarg->uspace_stack;
     77        local_uarg.uspace_stack_size = uarg->uspace_stack_size;
     78        local_uarg.uspace_uarg = uarg->uspace_uarg;
     79        local_uarg.uspace_thread_function = NULL;
     80        local_uarg.uspace_thread_arg = NULL;
    8181       
    82         userspace(&uarg);
     82        free(uarg);
     83       
     84        userspace(&local_uarg);
    8385}
    8486
  • kernel/generic/src/proc/program.c

    rfaba839 r2902e1b  
    7171int program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *prg)
    7272{
    73         uspace_arg_t *kernel_uarg;
    74        
    75         kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
    76         kernel_uarg->uspace_entry = (void *) entry_addr;
    77         kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS;
    78         kernel_uarg->uspace_thread_function = NULL;
    79         kernel_uarg->uspace_thread_arg = NULL;
    80         kernel_uarg->uspace_uarg = NULL;
    81        
    8273        prg->loader_status = EE_OK;
    8374        prg->task = task_create(as, name);
     
    9283            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
    9384            STACK_SIZE, AS_AREA_ATTR_NONE, &anon_backend, NULL, &virt, 0);
    94         if (!area)
     85        if (!area) {
     86                task_destroy(prg->task);
    9587                return ENOMEM;
     88        }
     89       
     90        uspace_arg_t *kernel_uarg = (uspace_arg_t *)
     91            malloc(sizeof(uspace_arg_t), 0);
     92       
     93        kernel_uarg->uspace_entry = (void *) entry_addr;
     94        kernel_uarg->uspace_stack = (void *) virt;
     95        kernel_uarg->uspace_stack_size = STACK_SIZE;
     96        kernel_uarg->uspace_thread_function = NULL;
     97        kernel_uarg->uspace_thread_arg = NULL;
     98        kernel_uarg->uspace_uarg = NULL;
    9699       
    97100        /*
     
    100103        prg->main_thread = thread_create(uinit, kernel_uarg, prg->task,
    101104            THREAD_FLAG_USPACE, "uinit", false);
    102         if (!prg->main_thread)
     105        if (!prg->main_thread) {
     106                free(kernel_uarg);
     107                as_area_destroy(as, virt);
     108                task_destroy(prg->task);
    103109                return ELIMIT;
     110        }
    104111       
    105112        return EOK;
  • kernel/generic/src/proc/thread.c

    rfaba839 r2902e1b  
    854854         * In case of failure, kernel_uarg will be deallocated in this function.
    855855         * In case of success, kernel_uarg will be freed in uinit().
    856          *
    857856         */
    858857        uspace_arg_t *kernel_uarg =
  • uspace/lib/c/arch/ia64/include/fibril.h

    rfaba839 r2902e1b  
    4949#define PFM_MASK  (~0x3fffffffff)
    5050
    51 #define PSTHREAD_INITIAL_STACK_PAGES_NO  2
    52 
    5351/* Stack is divided into two equal parts (for memory stack and register stack). */
    54 #define PSTHREAD_INITIAL_STACK_DIVISION  2
     52#define FIBRIL_INITIAL_STACK_DIVISION  2
    5553
    5654#define context_set(c, _pc, stack, size, tls) \
     
    5856                (c)->pc = (uint64_t) _pc; \
    5957                (c)->bsp = ((uint64_t) stack) + \
    60                     size / PSTHREAD_INITIAL_STACK_DIVISION; \
     58                    size / FIBRIL_INITIAL_STACK_DIVISION; \
    6159                (c)->ar_pfs &= PFM_MASK; \
    6260                (c)->sp = ((uint64_t) stack) + \
    63                     ALIGN_UP((size / PSTHREAD_INITIAL_STACK_DIVISION), STACK_ALIGNMENT) - \
     61                    ALIGN_UP((size / FIBRIL_INITIAL_STACK_DIVISION), STACK_ALIGNMENT) - \
    6462                    SP_DELTA; \
    6563                (c)->tp = (uint64_t) tls; \
  • uspace/lib/c/arch/ia64/include/thread.h

    rfaba839 r2902e1b  
    2727 */
    2828
    29 /** @addtogroup libcia64       
     29/** @addtogroup libcia64
    3030 * @{
    3131 */
     
    3636#define LIBC_ia64_THREAD_H_
    3737
    38 #define THREAD_INITIAL_STACK_PAGES_NO 2
    39 
    4038#endif
    4139
  • uspace/lib/c/generic/thread.c

    rfaba839 r2902e1b  
    4141#include <str.h>
    4242#include <async.h>
     43#include <errno.h>
     44#include <as.h>
    4345#include "private/thread.h"
    4446
    45 #ifndef THREAD_INITIAL_STACK_PAGES_NO
    46 #define THREAD_INITIAL_STACK_PAGES_NO   2
     47#ifndef THREAD_INITIAL_STACK_PAGES
     48        #define THREAD_INITIAL_STACK_PAGES  2
    4749#endif
    4850
     
    6567       
    6668        uarg->uspace_thread_function(uarg->uspace_thread_arg);
    67         /* XXX: we cannot free the userspace stack while running on it
    68                 free(uarg->uspace_stack);
    69                 free(uarg);
    70         */
     69        /*
     70         * XXX: we cannot free the userspace stack while running on it
     71         *
     72         * free(uarg->uspace_stack);
     73         * free(uarg);
     74         */
    7175       
    7276        /* If there is a manager, destroy it */
     
    9296    thread_id_t *tid)
    9397{
    94         char *stack;
    95         uspace_arg_t *uarg;
    96         int rc;
    97 
    98         stack = (char *) malloc(getpagesize() * THREAD_INITIAL_STACK_PAGES_NO);
    99         if (!stack)
    100                 return -1;
    101                
    102         uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
    103         if (!uarg) {
    104                 free(stack);
    105                 return -1;
     98        uspace_arg_t *uarg =
     99            (uspace_arg_t *) malloc(sizeof(uspace_arg_t));
     100        if (!uarg)
     101                return ENOMEM;
     102       
     103        size_t stack_size = getpagesize() * THREAD_INITIAL_STACK_PAGES;
     104        void *stack = as_area_create(AS_AREA_ANY, stack_size,
     105            AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE);
     106        if (stack == AS_MAP_FAILED) {
     107                free(uarg);
     108                return ENOMEM;
    106109        }
    107110       
    108111        uarg->uspace_entry = (void *) FADDR(__thread_entry);
    109         uarg->uspace_stack = (void *) stack;
     112        uarg->uspace_stack = stack;
     113        uarg->uspace_stack_size = stack_size;
    110114        uarg->uspace_thread_function = function;
    111115        uarg->uspace_thread_arg = arg;
    112116        uarg->uspace_uarg = uarg;
    113117       
    114         rc = __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name,
    115             (sysarg_t) str_size(name), (sysarg_t) tid);
     118        int rc = __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg,
     119            (sysarg_t) name, (sysarg_t) str_size(name), (sysarg_t) tid);
    116120       
    117         if (rc) {
     121        if (rc != EOK) {
    118122                /*
    119123                 * Failed to create a new thread.
    120                  * Free up the allocated structures.
     124                 * Free up the allocated data.
    121125                 */
     126                as_area_destroy(stack);
    122127                free(uarg);
    123                 free(stack);
    124128        }
    125 
     129       
    126130        return rc;
    127131}
Note: See TracChangeset for help on using the changeset viewer.