xref: /netbsd-src/tests/lib/libpthread/t_swapcontext.c (revision cd711bd2b96d0e5597ff8b8d7ef7efd4298487e6)
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