1*cd711bd2Suwe /* $NetBSD: t_swapcontext.c,v 1.9 2018/02/28 21:36:50 uwe Exp $ */
2bba80928Smanu
3bba80928Smanu /*
4bba80928Smanu * Copyright (c) 2012 Emmanuel Dreyfus. All rights reserved.
5bba80928Smanu *
6bba80928Smanu * Redistribution and use in source and binary forms, with or without
7bba80928Smanu * modification, are permitted provided that the following conditions
8bba80928Smanu * are met:
9bba80928Smanu * 1. Redistributions of source code must retain the above copyright
10bba80928Smanu * notice, this list of conditions and the following disclaimer.
11bba80928Smanu * 2. Redistributions in binary form must reproduce the above copyright
12bba80928Smanu * notice, this list of conditions and the following disclaimer in the
13bba80928Smanu * documentation and/or other materials provided with the distribution.
14bba80928Smanu *
15bba80928Smanu * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16bba80928Smanu * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17bba80928Smanu * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18bba80928Smanu * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19bba80928Smanu * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20bba80928Smanu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21bba80928Smanu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22bba80928Smanu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23bba80928Smanu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24bba80928Smanu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25bba80928Smanu * POSSIBILITY OF SUCH DAMAGE.
26bba80928Smanu */
27bba80928Smanu
28bba80928Smanu #include <sys/cdefs.h>
29*cd711bd2Suwe __RCSID("$NetBSD: t_swapcontext.c,v 1.9 2018/02/28 21:36:50 uwe Exp $");
30bba80928Smanu
31138b5d07Schristos #include <sys/types.h>
32138b5d07Schristos #include <errno.h>
33bba80928Smanu #include <pthread.h>
34bba80928Smanu #include <stdio.h>
35bba80928Smanu #include <stdlib.h>
36138b5d07Schristos #include <string.h>
37138b5d07Schristos #include <ucontext.h>
38bba80928Smanu
39bba80928Smanu #include <atf-c.h>
40bba80928Smanu
41bba80928Smanu #include "h_common.h"
42bba80928Smanu
43bba80928Smanu #define STACKSIZE 65536
44bba80928Smanu
45bba80928Smanu char stack[STACKSIZE];
46bba80928Smanu ucontext_t nctx;
47bba80928Smanu ucontext_t octx;
48bba80928Smanu void *oself;
49bba80928Smanu void *nself;
50bba80928Smanu int val1, val2;
51bba80928Smanu
52bba80928Smanu static void
swapfunc(void)5302b9aeb8Suwe swapfunc(void)
54bba80928Smanu {
55bba80928Smanu /*
56bba80928Smanu * If the test fails, we are very likely to crash
57bba80928Smanu * without the opportunity to report
58bba80928Smanu */
59bba80928Smanu nself = (void *)pthread_self();
60bba80928Smanu printf("after swapcontext self = %p\n", nself);
61bba80928Smanu
62bba80928Smanu ATF_REQUIRE_EQ(oself, nself);
63bba80928Smanu printf("Test succeeded\n");
64bba80928Smanu }
65bba80928Smanu
66bba80928Smanu /* ARGSUSED0 */
67bba80928Smanu static void *
threadfunc(void * arg)68bba80928Smanu threadfunc(void *arg)
69bba80928Smanu {
70bba80928Smanu nctx.uc_stack.ss_sp = stack;
71bba80928Smanu nctx.uc_stack.ss_size = sizeof(stack);
72*cd711bd2Suwe nctx.uc_link = &octx;
73bba80928Smanu
74738b2ab2Suwe makecontext(&nctx, swapfunc, 0);
75bba80928Smanu
76bba80928Smanu oself = (void *)pthread_self();
77bba80928Smanu printf("before swapcontext self = %p\n", oself);
78138b5d07Schristos ATF_REQUIRE_MSG(swapcontext(&octx, &nctx) != -1, "swapcontext failed: %s",
79138b5d07Schristos strerror(errno));
80bba80928Smanu
81bba80928Smanu return NULL;
82bba80928Smanu }
83bba80928Smanu
84bba80928Smanu
85bba80928Smanu ATF_TC(swapcontext1);
ATF_TC_HEAD(swapcontext1,tc)86bba80928Smanu ATF_TC_HEAD(swapcontext1, tc)
87bba80928Smanu {
88bba80928Smanu atf_tc_set_md_var(tc, "descr", "Testing if swapcontext() "
89bba80928Smanu "alters pthread_self()");
90bba80928Smanu }
ATF_TC_BODY(swapcontext1,tc)91bba80928Smanu ATF_TC_BODY(swapcontext1, tc)
92bba80928Smanu {
93bba80928Smanu pthread_t thread;
94bba80928Smanu
95bba80928Smanu oself = (void *)&val1;
96bba80928Smanu nself = (void *)&val2;
97bba80928Smanu
98bba80928Smanu printf("Testing if swapcontext() alters pthread_self()\n");
99bba80928Smanu
100138b5d07Schristos ATF_REQUIRE_MSG(getcontext(&nctx) != -1, "getcontext failed: %s",
101138b5d07Schristos strerror(errno));
102bba80928Smanu PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc, NULL));
10318d94356Sbouyer PTHREAD_REQUIRE(pthread_join(thread, NULL));
104bba80928Smanu }
105bba80928Smanu
ATF_TP_ADD_TCS(tp)106bba80928Smanu ATF_TP_ADD_TCS(tp)
107bba80928Smanu {
108bba80928Smanu ATF_TP_ADD_TC(tp, swapcontext1);
109bba80928Smanu
110bba80928Smanu return atf_no_error();
111bba80928Smanu }
112