1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/Coroutines/MYCoroutine.m Tue Apr 29 17:05:32 2008 -0700
1.3 @@ -0,0 +1,173 @@
1.4 +//
1.5 +// MYCoroutine.m
1.6 +// Coroutines
1.7 +//
1.8 +// Created by Jens Alfke on 4/29/08.
1.9 +// Copyright 2008 Jens Alfke. All rights reserved.
1.10 +// License is at the bottom of this file.
1.11 +//
1.12 +
1.13 +#import "MYCoroutine.h"
1.14 +#import "CoroX.h"
1.15 +
1.16 +
1.17 +#ifndef LogTo
1.18 +#define kEnableLog 0 /* 1 enables logging, 0 disables it */
1.19 +#define LogTo(DOMAIN,MSG,...) do{ if(kEnableLog) NSLog(@""#DOMAIN ": " MSG,__VA_ARGS__); }while(0)
1.20 +#endif
1.21 +
1.22 +#ifndef Warn
1.23 +#define Warn(MSG,...) NSLog(@"WARNING: " #MSG,__VA_ARGS__)
1.24 +#endif
1.25 +
1.26 +
1.27 +@implementation MYCoroutine
1.28 +
1.29 +
1.30 +static MYCoroutine *sMain, *sCurrent;
1.31 +
1.32 +
1.33 ++ (void) initialize
1.34 +{
1.35 + if( self == [MYCoroutine class] ) {
1.36 + sMain = [[self alloc] init];
1.37 + Coro_initializeMainCoro(sMain->_coro);
1.38 + sMain.name = @"MAIN";
1.39 + sCurrent = sMain;
1.40 + }
1.41 +}
1.42 +
1.43 +
1.44 +- (id) init
1.45 +{
1.46 + self = [super init];
1.47 + if (self != nil) {
1.48 + _coro = Coro_new();
1.49 + LogTo(Coroutine,@"INIT %@ : _coro=%p",self,_coro);
1.50 + }
1.51 + return self;
1.52 +}
1.53 +
1.54 +
1.55 +- (void) dealloc
1.56 +{
1.57 + LogTo(Coroutine,@"DEALLOC %@",self);
1.58 + Coro_free(_coro);
1.59 + [super dealloc];
1.60 +}
1.61 +
1.62 +
1.63 +- (NSString*) description
1.64 +{
1.65 + if( _name )
1.66 + return [NSString stringWithFormat: @"%@[%@]", [self class],_name];
1.67 + else
1.68 + return [NSString stringWithFormat: @"%@[%p]", [self class],self];
1.69 +}
1.70 +
1.71 +
1.72 +@synthesize name=_name;
1.73 +
1.74 +
1.75 ++ (MYCoroutine*) mainCoroutine {return sMain;}
1.76 ++ (MYCoroutine*) currentCoroutine {return sCurrent;}
1.77 +
1.78 +- (BOOL) isCurrent {return self==sCurrent;}
1.79 +
1.80 +- (const void*) stack {return Coro_stack(_coro);}
1.81 +- (size_t) stackSize {return Coro_stackSize(_coro);}
1.82 +- (void) setStackSize: (size_t)size {Coro_setStackSize_(_coro,size);}
1.83 +
1.84 +- (size_t) bytesLeftOnStack {return Coro_bytesLeftOnStack(_coro);}
1.85 +- (BOOL) stackSpaceAlmostGone {return Coro_stackSpaceAlmostGone(_coro);}
1.86 +
1.87 +
1.88 +static void startWithInvocation( void *context )
1.89 +{
1.90 + [(NSInvocation*)context invoke];
1.91 +}
1.92 +
1.93 +static void startWithMain( void *context )
1.94 +{
1.95 + [(MYCoroutine*)context main];
1.96 +}
1.97 +
1.98 +- (void) startWithInvocation: (NSInvocation*)invocation
1.99 +{
1.100 + LogTo(Coroutine,@"Starting %@ (currently in %@)",self,sCurrent);
1.101 + MYCoroutine *current = sCurrent;
1.102 + sCurrent = self;
1.103 +
1.104 + if( invocation )
1.105 + Coro_startCoro_(current->_coro, _coro, invocation, &startWithInvocation);
1.106 + else
1.107 + Coro_startCoro_(current->_coro, _coro, self, &startWithMain);
1.108 +
1.109 + sCurrent = current;
1.110 + LogTo(Coroutine,@"...resumed %@ after starting %@",sCurrent,self);
1.111 +}
1.112 +
1.113 +- (void) start
1.114 +{
1.115 + [self startWithInvocation: nil];
1.116 +}
1.117 +
1.118 +
1.119 ++ (MYCoroutine*) startWithInvocation: (NSInvocation*)invocation
1.120 +{
1.121 + MYCoroutine *cr = [[self alloc] init];
1.122 + [cr startWithInvocation: invocation];
1.123 + return cr;
1.124 +}
1.125 +
1.126 +
1.127 +- (void) resume
1.128 +{
1.129 + LogTo(Coroutine,@"Resuming %@ (currently in %@)",self,sCurrent);
1.130 + MYCoroutine *current = sCurrent;
1.131 + sCurrent = self;
1.132 + Coro_switchTo_(current->_coro,_coro);
1.133 + sCurrent = current;
1.134 + LogTo(Coroutine,@"...resumed %@",sCurrent);
1.135 +}
1.136 +
1.137 +
1.138 +- (void) main
1.139 +{
1.140 + // subclasses should override this.
1.141 +}
1.142 +
1.143 +
1.144 +@end
1.145 +
1.146 +
1.147 +
1.148 +
1.149 +/*
1.150 + (This is a BSD License)
1.151 +
1.152 + Copyright (c) 2008 Jens Alfke
1.153 + All rights reserved.
1.154 +
1.155 + Redistribution and use in source and binary forms, with or without modification, are
1.156 + permitted provided that the following conditions are met:
1.157 +
1.158 + • Redistributions of source code must retain the above copyright notice, this list of
1.159 + conditions and the following disclaimer.
1.160 + • Redistributions in binary form must reproduce the above copyright notice, this list
1.161 + of conditions and the following disclaimer in the documentation and/or other materials
1.162 + provided with the distribution.
1.163 + • Neither the name of the author nor the names of other contributors may be used to
1.164 + endorse or promote products derived from this software without specific prior written
1.165 + permission.
1.166 +
1.167 + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
1.168 + EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1.169 + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
1.170 + THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1.171 + EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1.172 + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.173 + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
1.174 + TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
1.175 + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1.176 +*/