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