Changeset 615e83d in mainline


Ignore:
Timestamp:
2018-03-08T18:25:31Z (6 years ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Children:
55f068c
Parents:
e0a4686
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-08 17:43:06)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-08 18:25:31)
Message:

Turn context_save/context_restore into standard setjmp/longjmp.

Location:
uspace/lib/c
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/arch/abs32le/src/fibril.c

    re0a4686 r615e83d  
    3030 */
    3131
    32 #include <fibril.h>
     32#include <setjmp.h>
    3333#include <stdbool.h>
    3434
    35 int context_save(context_t *ctx)
     35int setjmp(context_t *ctx)
    3636{
    37         return 1;
     37        return 0;
    3838}
    3939
    40 void context_restore(context_t *ctx)
     40void __longjmp(context_t *ctx, int val)
    4141{
    4242        while (true);
  • uspace/lib/c/arch/amd64/src/fibril.S

    re0a4686 r615e83d  
    3535#
    3636# Save CPU context to context_t variable
    37 # pointed by the 1st argument. Returns 1 in EAX.
     37# pointed by the 1st argument. Returns 0 in EAX.
    3838#
    39 FUNCTION_BEGIN(context_save)
     39FUNCTION_BEGIN(setjmp)
    4040        movq (%rsp), %rdx     # the caller's return %eip
    4141
     
    5454        movq %rax, CONTEXT_OFFSET_TLS(%rdi)
    5555
    56         xorl %eax, %eax                      # context_save returns 1
    57         incl %eax
     56        xorq %rax, %rax                      # setjmp returns 0
    5857        ret
    59 FUNCTION_END(context_save)
     58FUNCTION_END(setjmp)
    6059
    6160## Restore current CPU context
    6261#
    6362# Restore CPU context from context_t variable
    64 # pointed by the 1st argument. Returns 0 in EAX.
     63# pointed by the 1st argument. Returns RSI in EAX.
    6564#
    66 FUNCTION_BEGIN(context_restore)
     65FUNCTION_BEGIN(__longjmp)
    6766        movq CONTEXT_OFFSET_R15(%rdi), %r15
    6867        movq CONTEXT_OFFSET_R14(%rdi), %r14
     
    8180        movq %rdi, %fs:0
    8281
    83         xorl %eax, %eax                      # context_restore returns 0
     82        movq %rsi, %rax                      # __longjmp returns second argument
    8483        ret
    85 FUNCTION_END(context_restore)
     84FUNCTION_END(__longjmp)
    8685
  • uspace/lib/c/arch/arm32/src/fibril.S

    re0a4686 r615e83d  
    3131.text
    3232
    33 FUNCTION_BEGIN(context_save)
     33FUNCTION_BEGIN(setjmp)
    3434        stmia r0!, {sp, lr}
    3535        stmia r0!, {r4-r11}
    36 
    37         # return 1
    38         mov r0, #1
    39         mov pc, lr
    40 FUNCTION_END(context_save)
    41 
    42 FUNCTION_BEGIN(context_restore)
    43         ldmia r0!, {sp, lr}
    44         ldmia r0!, {r4-r11}
    4536
    4637        # return 0
    4738        mov r0, #0
    4839        mov pc, lr
    49 FUNCTION_END(context_restore)
     40FUNCTION_END(setjmp)
    5041
     42FUNCTION_BEGIN(__longjmp)
     43        ldmia r0!, {sp, lr}
     44        ldmia r0!, {r4-r11}
     45
     46        # return second argument
     47        mov r0, r1
     48        mov pc, lr
     49FUNCTION_END(__longjmp)
     50
  • uspace/lib/c/arch/ia32/src/fibril.S

    re0a4686 r615e83d  
    3535#
    3636# Save CPU context to the context_t variable
    37 # pointed by the 1st argument. Returns 1 in EAX.
     37# pointed by the 1st argument. Returns 0 in EAX.
    3838#
    39 FUNCTION_BEGIN(context_save)
     39FUNCTION_BEGIN(setjmp)
    4040        movl 0(%esp), %eax  # the caller's return %eip
    4141        movl 4(%esp), %edx  # address of the context variable to save context to
     
    5353        movl %eax, CONTEXT_OFFSET_TLS(%edx)     # tls -> ctx->tls
    5454
    55         xorl %eax, %eax         # context_save returns 1
    56         incl %eax
     55        xorl %eax, %eax         # setjmp returns 0
    5756        ret
    58 FUNCTION_END(context_save)
     57FUNCTION_END(setjmp)
    5958
    6059## Restore saved CPU context
    6160#
    6261# Restore CPU context from context_t variable
    63 # pointed by the 1st argument. Returns 0 in EAX.
     62# pointed by the 1st argument. Returns second argument in EAX.
    6463#
    65 FUNCTION_BEGIN(context_restore)
     64FUNCTION_BEGIN(__longjmp)
    6665        movl 4(%esp), %eax  # address of the context variable to restore context from
     66        movl 8(%esp), %ecx  # return value
    6767
    6868        # restore registers from the context structure
     
    8080        movl %edx, %gs:0
    8181
    82         xorl %eax, %eax         # context_restore returns 0
     82        movl %ecx, %eax
    8383        ret
    84 FUNCTION_END(context_restore)
     84FUNCTION_END(__longjmp)
    8585
  • uspace/lib/c/arch/ia64/include/libarch/fibril.h

    re0a4686 r615e83d  
    4343
    4444/*
    45  * context_save() and context_restore() are both leaf procedures.
     45 * setjmp() and __longjmp() are both leaf procedures.
    4646 * No need to allocate scratch area.
    4747 */
  • uspace/lib/c/arch/ia64/src/fibril.S

    re0a4686 r615e83d  
    3232.text
    3333
    34 FUNCTION_BEGIN(context_save)
     34FUNCTION_BEGIN(setjmp)
    3535        alloc loc0 = ar.pfs, 1, 49, 0, 0
    3636        mov loc1 = ar.unat ;;
     
    178178        mov ar.unat = loc1
    179179
    180         add r8 = r0, r0, 1      /* context_save returns 1 */
     180        mov r8 = 0      /* setjmp returns 0 */
    181181        br.ret.sptk.many b0
    182 FUNCTION_END(context_save)
    183 
    184 FUNCTION_BEGIN(context_restore)
    185         alloc loc0 = ar.pfs, 1, 50, 0, 0        ;;
     182FUNCTION_END(setjmp)
     183
     184FUNCTION_BEGIN(__longjmp)
     185        alloc loc0 = ar.pfs, 2, 51, 0, 0        ;;
    186186
    187187        add loc9 = CONTEXT_OFFSET_AR_PFS, in0
     
    230230        add loc47 = CONTEXT_OFFSET_F29, in0
    231231        add loc48 = CONTEXT_OFFSET_F30, in0
    232         add loc49 = CONTEXT_OFFSET_F31, in0 ;;
     232        add loc49 = CONTEXT_OFFSET_F31, in0
     233        mov loc50 = in1 ;;
    233234
    234235        ld8 loc0 = [loc9]       /* load ar.pfs */
     
    335336        mov ar.unat = loc1
    336337
    337         mov r8 = r0                     /* context_restore returns 0 */
     338        mov r8 = loc50                  /* __longjmp returns second argument */
    338339        br.ret.sptk.many b0
    339 FUNCTION_END(context_restore)
     340FUNCTION_END(__longjmp)
  • uspace/lib/c/arch/mips32/src/fibril.S

    re0a4686 r615e83d  
    3535#include <libarch/fibril_context.h>
    3636
    37 FUNCTION_BEGIN(context_save)
     37FUNCTION_BEGIN(setjmp)
    3838        sw $s0, CONTEXT_OFFSET_S0($a0)
    3939        sw $s1, CONTEXT_OFFSET_S1($a0)
     
    8787        sw $sp, CONTEXT_OFFSET_SP($a0)
    8888
    89         # context_save returns 1
     89        # setjmp returns 0
    9090        j $ra
    91         li $v0, 1
    92 FUNCTION_END(context_save)
     91        li $v0, 0
     92FUNCTION_END(setjmp)
    9393
    94 FUNCTION_BEGIN(context_restore)
     94FUNCTION_BEGIN(__longjmp)
    9595        lw $s0, CONTEXT_OFFSET_S0($a0)
    9696        lw $s1, CONTEXT_OFFSET_S1($a0)
     
    147147        move $t9, $ra
    148148
    149         # context_restore returns 0
     149        # __longjmp returns second argument
    150150        j $ra
    151         xor $v0, $v0
    152 FUNCTION_END(context_restore)
     151        move $v0, $a1
     152FUNCTION_END(__longjmp)
  • uspace/lib/c/arch/ppc32/src/fibril.S

    re0a4686 r615e83d  
    3333#include <libarch/fibril_context.h>
    3434
    35 FUNCTION_BEGIN(context_save)
     35FUNCTION_BEGIN(setjmp)
    3636        stw sp, CONTEXT_OFFSET_SP(r3)
    3737        stw r2, CONTEXT_OFFSET_TLS(r3)
     
    6262        stw r4, CONTEXT_OFFSET_CR(r3)
    6363
    64         # context_save returns 1
    65         li r3, 1
     64        # setjmp returns 0
     65        li r3, 0
    6666        blr
    67 FUNCTION_END(context_save)
     67FUNCTION_END(setjmp)
    6868
    69 FUNCTION_BEGIN(context_restore)
     69FUNCTION_BEGIN(__longjmp)
    7070        lwz sp, CONTEXT_OFFSET_SP(r3)
    7171        lwz r2, CONTEXT_OFFSET_TLS(r3)
     
    9090        lwz r31, CONTEXT_OFFSET_R31(r3)
    9191
    92         lwz r4, CONTEXT_OFFSET_CR(r3)
    93         mtcr r4
     92        lwz r5, CONTEXT_OFFSET_CR(r3)
     93        mtcr r5
    9494
    95         lwz r4, CONTEXT_OFFSET_PC(r3)
    96         mtlr r4
     95        lwz r5, CONTEXT_OFFSET_PC(r3)
     96        mtlr r5
    9797
    98         # context_restore returns 0
    99         li r3, 0
     98        # __longjmp returns second argument
     99        li r3, r4
    100100        blr
    101 FUNCTION_END(context_restore)
     101FUNCTION_END(__longjmp)
  • uspace/lib/c/arch/riscv64/src/fibril.c

    re0a4686 r615e83d  
    3333#include <stdbool.h>
    3434
    35 int context_save(context_t *ctx)
     35int setjmp(context_t *ctx)
    3636{
    37         return 1;
     37        return 0;
    3838}
    3939
    40 void context_restore(context_t *ctx)
     40void __longjmp(context_t *ctx, int ret)
    4141{
    4242        while (true);
  • uspace/lib/c/arch/sparc64/src/fibril.S

    re0a4686 r615e83d  
    3232.text
    3333
    34 FUNCTION_BEGIN(context_save)
     34FUNCTION_BEGIN(setjmp)
    3535        #
    3636        # We rely on the kernel to flush our active register windows to memory
     
    5757        stx %g7, [%o0 + CONTEXT_OFFSET_TP]
    5858        retl
    59         mov 1, %o0              ! context_save_arch returns 1
    60 FUNCTION_END(context_save)
     59        mov 0, %o0              ! setjmp returns 0
     60FUNCTION_END(setjmp)
    6161
    62 FUNCTION_BEGIN(context_restore)
     62FUNCTION_BEGIN(__longjmp)
    6363        #
    6464        # Flush all active windows.
     
    8989        ldx [%o0 + CONTEXT_OFFSET_TP], %g7
    9090        retl
    91         xor %o0, %o0, %o0       ! context_restore_arch returns 0
    92 FUNCTION_END(context_restore)
     91        mov %o1, %o0    ! __longjmp returns second argument
     92FUNCTION_END(__longjmp)
  • uspace/lib/c/generic/context.c

    re0a4686 r615e83d  
    2828
    2929#include <context.h>
     30#include <setjmp.h>
    3031#include <libarch/tls.h>
    3132#include <libarch/fibril.h>
     
    4243void context_swap(context_t *self, context_t *other)
    4344{
    44         if (context_save(self))
    45                 context_restore(other);
     45        if (!setjmp(self))
     46                __longjmp(other, 1);
    4647}
    4748
    4849void context_create(context_t *context, const context_create_t *arg)
    4950{
    50         context_save(context);
     51        setjmp(context);
    5152        context_set(context, FADDR(arg->fn), arg->stack_base,
    5253            arg->stack_size, arg->tls);
  • uspace/lib/c/generic/setjmp.c

    re0a4686 r615e83d  
    11/*
    22 * Copyright (c) 2013 Vojtech Horky
     3 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    34 * All rights reserved.
    45 *
     
    3031 * @{
    3132 */
    32 /** @file Long jump implementation.
    33  *
    34  * Implementation inspired by Jiri Zarevucky's code from
    35  * http://bazaar.launchpad.net/~zarevucky-jiri/helenos/stdc/revision/1544/uspace/lib/posix/setjmp.h
    36  */
    3733
    3834#include <setjmp.h>
    3935#include <context.h>
    4036
    41 // TODO: setjmp/longjmp are basically a stronger version of
    42 // context_save/context_restore. It would be preferable to turn
    43 // those two into setjmp/longjmp (all it would need is preserving the
    44 // return value).
    45 
    46 /**
    47  * Restore environment previously stored by setjmp.
    48  *
    49  * This function never returns.
    50  *
    51  * @param env Variable with the environment previously stored by call
    52  * to setjmp.
    53  * @param val Value to fake when returning from setjmp (0 is transformed to 1).
    54  */
    55 void longjmp(jmp_buf env, int val) {
    56         env[0].return_value = (val == 0) ? 1 : val;
    57         context_restore(&env[0].context);
     37/** Standard function implementation. */
     38void longjmp(jmp_buf env, int val)
     39{
     40        /* __longjmp defined in assembly doesn't "correct" the value. */
     41        __longjmp(env, val == 0 ? 1 : val);
    5842}
    5943
  • uspace/lib/c/include/context.h

    re0a4686 r615e83d  
    4646extern uintptr_t context_get_pc(context_t *ctx);
    4747
    48 // TODO: These should go away.
    49 
    50 extern int context_save(context_t *ctx) __attribute__((returns_twice));
    51 extern void context_restore(context_t *ctx) __attribute__((noreturn));
    52 
    5348#endif
    5449
  • uspace/lib/c/include/setjmp.h

    re0a4686 r615e83d  
    11/*
    2  * Copyright (c) 2008 Josef Cejka
    3  * Copyright (c) 2013 Vojtech Horky
     2 * Copyright (c) 2018 CZ.NIC, z.s.p.o.
    43 * All rights reserved.
    54 *
     
    3130 * @{
    3231 */
    33 /** @file Long jump implementation.
    34  *
    35  * Implementation inspired by Jiri Zarevucky's code from
    36  * http://bazaar.launchpad.net/~zarevucky-jiri/helenos/stdc/revision/1544/uspace/lib/posix/setjmp.h
    37  */
    3832
    3933#ifndef LIBC_SETJMP_H_
    4034#define LIBC_SETJMP_H_
    4135
    42 #include <libarch/fibril.h>
     36#include <libarch/fibril_context.h>
    4337
    44 struct jmp_buf_interal {
    45         context_t context;
    46         int return_value;
    47 };
    48 typedef struct jmp_buf_interal jmp_buf[1];
     38typedef context_t jmp_buf[1];
    4939
    50 /*
    51  * Specified as extern to minimize number of included headers
    52  * because this file is used as is in libposix too.
    53  */
    54 extern int context_save(context_t *ctx) __attribute__((returns_twice));
    55 
    56 /**
    57  * Save current environment (registers).
    58  *
    59  * This function may return twice.
    60  *
    61  * @param env Variable where to save the environment (of type jmp_buf).
    62  * @return Whether the call returned after longjmp.
    63  * @retval 0 Environment was saved, normal execution.
    64  * @retval other longjmp was executed and returned here.
    65  */
    66 #define setjmp(env) \
    67         ((env)[0].return_value = 0, \
    68         context_save(&(env)[0].context), \
    69         (env)[0].return_value)
    70 
    71 extern void longjmp(jmp_buf env, int val) __attribute__((noreturn));
     40extern int setjmp(jmp_buf) __attribute__((returns_twice));
     41extern void longjmp(jmp_buf, int) __attribute__((noreturn));
     42extern void __longjmp(jmp_buf, int) __attribute__((noreturn));
    7243
    7344#endif
Note: See TracChangeset for help on using the changeset viewer.