xref: /minix3/tests/lib/libobjc/t_threads.m (revision 84d9c625bfea59e274550651111ae9edfdc40fbd)
1*84d9c625SLionel Sambuc/* $NetBSD: t_threads.m,v 1.2 2013/10/31 21:02:11 christos Exp $ */
211be35a1SLionel Sambuc
311be35a1SLionel Sambuc/*
411be35a1SLionel Sambuc * Copyright (c) 2010 The NetBSD Foundation, Inc.
511be35a1SLionel Sambuc * All rights reserved.
611be35a1SLionel Sambuc *
711be35a1SLionel Sambuc * Redistribution and use in source and binary forms, with or without
811be35a1SLionel Sambuc * modification, are permitted provided that the following conditions
911be35a1SLionel Sambuc * are met:
1011be35a1SLionel Sambuc * 1. Redistributions of source code must retain the above copyright
1111be35a1SLionel Sambuc *    notice, this list of conditions and the following disclaimer.
1211be35a1SLionel Sambuc * 2. Redistributions in binary form must reproduce the above copyright
1311be35a1SLionel Sambuc *    notice, this list of conditions and the following disclaimer in the
1411be35a1SLionel Sambuc *    documentation and/or other materials provided with the distribution.
1511be35a1SLionel Sambuc *
1611be35a1SLionel Sambuc * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1711be35a1SLionel Sambuc * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1811be35a1SLionel Sambuc * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1911be35a1SLionel Sambuc * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2011be35a1SLionel Sambuc * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2111be35a1SLionel Sambuc * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2211be35a1SLionel Sambuc * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2311be35a1SLionel Sambuc * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2411be35a1SLionel Sambuc * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2511be35a1SLionel Sambuc * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2611be35a1SLionel Sambuc * POSSIBILITY OF SUCH DAMAGE.
2711be35a1SLionel Sambuc */
2811be35a1SLionel Sambuc
2911be35a1SLionel Sambuc/* Originally written by David Wetzel */
3011be35a1SLionel Sambuc
3111be35a1SLionel Sambuc#include <assert.h>
3211be35a1SLionel Sambuc#include <stdio.h>
3311be35a1SLionel Sambuc#include <unistd.h>
3411be35a1SLionel Sambuc
3511be35a1SLionel Sambuc#include <atf-c.h>
3611be35a1SLionel Sambuc
3711be35a1SLionel Sambuc#include <objc/objc.h>
38*84d9c625SLionel Sambuc#include <objc/thr.h>
3911be35a1SLionel Sambuc#include <objc/Object.h>
40*84d9c625SLionel Sambuc#if __GNUC_PREREQ__(4,8)
41*84d9c625SLionel Sambuc#include <objc/runtime.h>
42*84d9c625SLionel Sambuc#endif
4311be35a1SLionel Sambuc
4411be35a1SLionel Sambucstatic int IsMultithreaded = 0;
4511be35a1SLionel Sambucstatic objc_mutex_t Mutex;
4611be35a1SLionel Sambucstatic objc_condition_t Condition;
4711be35a1SLionel Sambuc
4811be35a1SLionel Sambuc@interface MyClass : Object
4911be35a1SLionel Sambuc{
5011be35a1SLionel Sambuc}
5111be35a1SLionel Sambuc-(void)start;
52*84d9c625SLionel Sambuc#if __GNUC_PREREQ__(4,8)
53*84d9c625SLionel Sambuc-init;
54*84d9c625SLionel Sambuc+new;
55*84d9c625SLionel Sambuc+alloc;
56*84d9c625SLionel Sambuc-free;
57*84d9c625SLionel Sambuc#endif
5811be35a1SLionel Sambuc@end
5911be35a1SLionel Sambuc
6011be35a1SLionel Sambuc@implementation MyClass
6111be35a1SLionel Sambuc-(void)start
6211be35a1SLionel Sambuc{
6311be35a1SLionel Sambuc	printf("detached thread started!\n");
6411be35a1SLionel Sambuc
6511be35a1SLionel Sambuc	objc_condition_signal(Condition);
6611be35a1SLionel Sambuc}
67*84d9c625SLionel Sambuc#if __GNUC_PREREQ__(4,8)
68*84d9c625SLionel Sambuc-init
69*84d9c625SLionel Sambuc{
70*84d9c625SLionel Sambuc	return self;
71*84d9c625SLionel Sambuc}
72*84d9c625SLionel Sambuc
73*84d9c625SLionel Sambuc+new
74*84d9c625SLionel Sambuc{
75*84d9c625SLionel Sambuc	return [[self alloc] init];
76*84d9c625SLionel Sambuc}
77*84d9c625SLionel Sambuc
78*84d9c625SLionel Sambuc+alloc
79*84d9c625SLionel Sambuc{
80*84d9c625SLionel Sambuc	return class_createInstance(self, 0);
81*84d9c625SLionel Sambuc}
82*84d9c625SLionel Sambuc
83*84d9c625SLionel Sambuc-free
84*84d9c625SLionel Sambuc{
85*84d9c625SLionel Sambuc	return object_dispose(self);
86*84d9c625SLionel Sambuc}
87*84d9c625SLionel Sambuc#endif
8811be35a1SLionel Sambuc@end
8911be35a1SLionel Sambuc
9011be35a1SLionel Sambucstatic void
9111be35a1SLionel SambucbecomeMultiThreaded(void)
9211be35a1SLionel Sambuc{
9311be35a1SLionel Sambuc	printf("becoming multithreaded!\n");
9411be35a1SLionel Sambuc	IsMultithreaded++;
9511be35a1SLionel Sambuc}
9611be35a1SLionel Sambuc
9711be35a1SLionel SambucATF_TC(thread_callback);
9811be35a1SLionel SambucATF_TC_HEAD(thread_callback, tc)
9911be35a1SLionel Sambuc{
10011be35a1SLionel Sambuc	atf_tc_set_md_var(tc, "descr", "Checks that the thread callback is only"
10111be35a1SLionel Sambuc	    "called once");
10211be35a1SLionel Sambuc}
10311be35a1SLionel SambucATF_TC_BODY(thread_callback, tc)
10411be35a1SLionel Sambuc{
10511be35a1SLionel Sambuc	id o = [MyClass new];
10611be35a1SLionel Sambuc	objc_thread_callback cb;
10711be35a1SLionel Sambuc	objc_thread_t rv;
10811be35a1SLionel Sambuc
10911be35a1SLionel Sambuc	cb = objc_set_thread_callback(becomeMultiThreaded);
11011be35a1SLionel Sambuc	printf("Old Callback: %p\n", cb);
11111be35a1SLionel Sambuc	ATF_CHECK(cb == 0);
11211be35a1SLionel Sambuc
11311be35a1SLionel Sambuc	Mutex = objc_mutex_allocate();
11411be35a1SLionel Sambuc	Condition = objc_condition_allocate();
11511be35a1SLionel Sambuc
11611be35a1SLionel Sambuc	ATF_CHECK_EQ(0, IsMultithreaded);
11711be35a1SLionel Sambuc
11811be35a1SLionel Sambuc	rv = objc_thread_detach(@selector(start), o, nil);
11911be35a1SLionel Sambuc	printf("detach value: %p\n", rv);
12011be35a1SLionel Sambuc	assert(rv != NULL);
12111be35a1SLionel Sambuc
12211be35a1SLionel Sambuc	objc_mutex_lock(Mutex);
12311be35a1SLionel Sambuc	objc_condition_wait(Condition, Mutex);
12411be35a1SLionel Sambuc	objc_mutex_unlock(Mutex);
12511be35a1SLionel Sambuc
12611be35a1SLionel Sambuc	ATF_CHECK_EQ(1, IsMultithreaded);
12711be35a1SLionel Sambuc	printf("Shutting down\n");
12811be35a1SLionel Sambuc}
12911be35a1SLionel Sambuc
13011be35a1SLionel SambucATF_TP_ADD_TCS(tp)
13111be35a1SLionel Sambuc{
13211be35a1SLionel Sambuc
13311be35a1SLionel Sambuc	ATF_TP_ADD_TC(tp, thread_callback);
13411be35a1SLionel Sambuc
13511be35a1SLionel Sambuc	return atf_no_error();
13611be35a1SLionel Sambuc}
137