1 /*- 2 * Copyright (c) 2025 Raptor Computing Systems, LLC 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7 #include <stdio.h> 8 #include <stdlib.h> 9 #include <ucontext.h> 10 #include <errno.h> 11 12 #include <atf-c.h> 13 14 #define STACK_SIZE (64ull << 10) 15 16 static volatile int callback_reached = 0; 17 18 static ucontext_t uctx_save, uctx_switch; 19 20 static void swapcontext_callback() 21 { 22 // Increment callback reached variable 23 // If this is called multiple times, we will fail the test 24 // If this is not called at all, we will fail the test 25 callback_reached++; 26 } 27 28 ATF_TC(swapcontext_basic); 29 ATF_TC_HEAD(swapcontext_basic, tc) 30 { 31 atf_tc_set_md_var(tc, "descr", 32 "Verify basic functionality of swapcontext"); 33 } 34 35 ATF_TC_BODY(swapcontext_basic, tc) 36 { 37 char *stack; 38 int res; 39 40 stack = malloc(STACK_SIZE); 41 ATF_REQUIRE_MSG(stack != NULL, "malloc failed: %s", strerror(errno)); 42 res = getcontext(&uctx_switch); 43 ATF_REQUIRE_MSG(res == 0, "getcontext failed: %s", strerror(errno)); 44 45 uctx_switch.uc_stack.ss_sp = stack; 46 uctx_switch.uc_stack.ss_size = STACK_SIZE; 47 uctx_switch.uc_link = &uctx_save; 48 makecontext(&uctx_switch, swapcontext_callback, 0); 49 50 res = swapcontext(&uctx_save, &uctx_switch); 51 52 ATF_REQUIRE_MSG(res == 0, "swapcontext failed: %s", strerror(errno)); 53 ATF_REQUIRE_MSG(callback_reached == 1, 54 "callback failed, reached %d times", callback_reached); 55 } 56 57 ATF_TP_ADD_TCS(tp) 58 { 59 ATF_TP_ADD_TC(tp, swapcontext_basic); 60 61 return (atf_no_error()); 62 } 63 64