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