xref: /freebsd/contrib/netbsd-tests/lib/libobjc/t_threads.m (revision 9268022b74279434ed6300244e3f977e56a8ceb5)
1*57718be8SEnji Cooper/* $NetBSD: t_threads.m,v 1.2 2013/10/31 21:02:11 christos Exp $ */
2*57718be8SEnji Cooper
3*57718be8SEnji Cooper/*
4*57718be8SEnji Cooper * Copyright (c) 2010 The NetBSD Foundation, Inc.
5*57718be8SEnji Cooper * All rights reserved.
6*57718be8SEnji Cooper *
7*57718be8SEnji Cooper * Redistribution and use in source and binary forms, with or without
8*57718be8SEnji Cooper * modification, are permitted provided that the following conditions
9*57718be8SEnji Cooper * are met:
10*57718be8SEnji Cooper * 1. Redistributions of source code must retain the above copyright
11*57718be8SEnji Cooper *    notice, this list of conditions and the following disclaimer.
12*57718be8SEnji Cooper * 2. Redistributions in binary form must reproduce the above copyright
13*57718be8SEnji Cooper *    notice, this list of conditions and the following disclaimer in the
14*57718be8SEnji Cooper *    documentation and/or other materials provided with the distribution.
15*57718be8SEnji Cooper *
16*57718be8SEnji Cooper * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17*57718be8SEnji Cooper * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18*57718be8SEnji Cooper * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19*57718be8SEnji Cooper * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20*57718be8SEnji Cooper * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21*57718be8SEnji Cooper * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22*57718be8SEnji Cooper * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23*57718be8SEnji Cooper * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24*57718be8SEnji Cooper * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25*57718be8SEnji Cooper * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26*57718be8SEnji Cooper * POSSIBILITY OF SUCH DAMAGE.
27*57718be8SEnji Cooper */
28*57718be8SEnji Cooper
29*57718be8SEnji Cooper/* Originally written by David Wetzel */
30*57718be8SEnji Cooper
31*57718be8SEnji Cooper#include <assert.h>
32*57718be8SEnji Cooper#include <stdio.h>
33*57718be8SEnji Cooper#include <unistd.h>
34*57718be8SEnji Cooper
35*57718be8SEnji Cooper#include <atf-c.h>
36*57718be8SEnji Cooper
37*57718be8SEnji Cooper#include <objc/objc.h>
38*57718be8SEnji Cooper#include <objc/thr.h>
39*57718be8SEnji Cooper#include <objc/Object.h>
40*57718be8SEnji Cooper#if __GNUC_PREREQ__(4,8)
41*57718be8SEnji Cooper#include <objc/runtime.h>
42*57718be8SEnji Cooper#endif
43*57718be8SEnji Cooper
44*57718be8SEnji Cooperstatic int IsMultithreaded = 0;
45*57718be8SEnji Cooperstatic objc_mutex_t Mutex;
46*57718be8SEnji Cooperstatic objc_condition_t Condition;
47*57718be8SEnji Cooper
48*57718be8SEnji Cooper@interface MyClass : Object
49*57718be8SEnji Cooper{
50*57718be8SEnji Cooper}
51*57718be8SEnji Cooper-(void)start;
52*57718be8SEnji Cooper#if __GNUC_PREREQ__(4,8)
53*57718be8SEnji Cooper-init;
54*57718be8SEnji Cooper+new;
55*57718be8SEnji Cooper+alloc;
56*57718be8SEnji Cooper-free;
57*57718be8SEnji Cooper#endif
58*57718be8SEnji Cooper@end
59*57718be8SEnji Cooper
60*57718be8SEnji Cooper@implementation MyClass
61*57718be8SEnji Cooper-(void)start
62*57718be8SEnji Cooper{
63*57718be8SEnji Cooper	printf("detached thread started!\n");
64*57718be8SEnji Cooper
65*57718be8SEnji Cooper	objc_condition_signal(Condition);
66*57718be8SEnji Cooper}
67*57718be8SEnji Cooper#if __GNUC_PREREQ__(4,8)
68*57718be8SEnji Cooper-init
69*57718be8SEnji Cooper{
70*57718be8SEnji Cooper	return self;
71*57718be8SEnji Cooper}
72*57718be8SEnji Cooper
73*57718be8SEnji Cooper+new
74*57718be8SEnji Cooper{
75*57718be8SEnji Cooper	return [[self alloc] init];
76*57718be8SEnji Cooper}
77*57718be8SEnji Cooper
78*57718be8SEnji Cooper+alloc
79*57718be8SEnji Cooper{
80*57718be8SEnji Cooper	return class_createInstance(self, 0);
81*57718be8SEnji Cooper}
82*57718be8SEnji Cooper
83*57718be8SEnji Cooper-free
84*57718be8SEnji Cooper{
85*57718be8SEnji Cooper	return object_dispose(self);
86*57718be8SEnji Cooper}
87*57718be8SEnji Cooper#endif
88*57718be8SEnji Cooper@end
89*57718be8SEnji Cooper
90*57718be8SEnji Cooperstatic void
91*57718be8SEnji CooperbecomeMultiThreaded(void)
92*57718be8SEnji Cooper{
93*57718be8SEnji Cooper	printf("becoming multithreaded!\n");
94*57718be8SEnji Cooper	IsMultithreaded++;
95*57718be8SEnji Cooper}
96*57718be8SEnji Cooper
97*57718be8SEnji CooperATF_TC(thread_callback);
98*57718be8SEnji CooperATF_TC_HEAD(thread_callback, tc)
99*57718be8SEnji Cooper{
100*57718be8SEnji Cooper	atf_tc_set_md_var(tc, "descr", "Checks that the thread callback is only"
101*57718be8SEnji Cooper	    "called once");
102*57718be8SEnji Cooper}
103*57718be8SEnji CooperATF_TC_BODY(thread_callback, tc)
104*57718be8SEnji Cooper{
105*57718be8SEnji Cooper	id o = [MyClass new];
106*57718be8SEnji Cooper	objc_thread_callback cb;
107*57718be8SEnji Cooper	objc_thread_t rv;
108*57718be8SEnji Cooper
109*57718be8SEnji Cooper	cb = objc_set_thread_callback(becomeMultiThreaded);
110*57718be8SEnji Cooper	printf("Old Callback: %p\n", cb);
111*57718be8SEnji Cooper	ATF_CHECK(cb == 0);
112*57718be8SEnji Cooper
113*57718be8SEnji Cooper	Mutex = objc_mutex_allocate();
114*57718be8SEnji Cooper	Condition = objc_condition_allocate();
115*57718be8SEnji Cooper
116*57718be8SEnji Cooper	ATF_CHECK_EQ(0, IsMultithreaded);
117*57718be8SEnji Cooper
118*57718be8SEnji Cooper	rv = objc_thread_detach(@selector(start), o, nil);
119*57718be8SEnji Cooper	printf("detach value: %p\n", rv);
120*57718be8SEnji Cooper	assert(rv != NULL);
121*57718be8SEnji Cooper
122*57718be8SEnji Cooper	objc_mutex_lock(Mutex);
123*57718be8SEnji Cooper	objc_condition_wait(Condition, Mutex);
124*57718be8SEnji Cooper	objc_mutex_unlock(Mutex);
125*57718be8SEnji Cooper
126*57718be8SEnji Cooper	ATF_CHECK_EQ(1, IsMultithreaded);
127*57718be8SEnji Cooper	printf("Shutting down\n");
128*57718be8SEnji Cooper}
129*57718be8SEnji Cooper
130*57718be8SEnji CooperATF_TP_ADD_TCS(tp)
131*57718be8SEnji Cooper{
132*57718be8SEnji Cooper
133*57718be8SEnji Cooper	ATF_TP_ADD_TC(tp, thread_callback);
134*57718be8SEnji Cooper
135*57718be8SEnji Cooper	return atf_no_error();
136*57718be8SEnji Cooper}
137