Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

working

  • Loading branch information...
commit 84f39a8b25ace12862c699aa9dc61dfe18a6b396 1 parent d41eeac
@stevedekorte authored
View
BIN  .DS_Store
Binary file not shown
View
84 ActorKit.xcodeproj/project.pbxproj
@@ -8,30 +8,23 @@
/* Begin PBXBuildFile section */
AA2726621411886500FE0A43 /* ActorKit.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DA5140E0C220020BA06 /* ActorKit.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ AA9A97881419785000A2994E /* NSThread+Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = AA9A97861419785000A2994E /* NSThread+Actor.h */; settings = {ATTRIBUTES = (Public, ); }; };
+ AA9A97891419785000A2994E /* NSThread+Actor.m in Sources */ = {isa = PBXBuildFile; fileRef = AA9A97871419785000A2994E /* NSThread+Actor.m */; };
AABB5D99140E0C220020BA06 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABB5D98140E0C220020BA06 /* Cocoa.framework */; };
AABB5DA3140E0C220020BA06 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = AABB5DA1140E0C220020BA06 /* InfoPlist.strings */; };
- AABB5DD4140EED090020BA06 /* 386-ucontext.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DC7140EED090020BA06 /* 386-ucontext.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AABB5DD5140EED090020BA06 /* amd64-ucontext.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DC8140EED090020BA06 /* amd64-ucontext.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AABB5DD6140EED090020BA06 /* asm.S in Sources */ = {isa = PBXBuildFile; fileRef = AABB5DC9140EED090020BA06 /* asm.S */; };
- AABB5DD7140EED090020BA06 /* Common.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DCA140EED090020BA06 /* Common.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AABB5DD8140EED090020BA06 /* context.c in Sources */ = {isa = PBXBuildFile; fileRef = AABB5DCB140EED090020BA06 /* context.c */; };
- AABB5DD9140EED090020BA06 /* Coro.c in Sources */ = {isa = PBXBuildFile; fileRef = AABB5DCC140EED090020BA06 /* Coro.c */; };
- AABB5DDA140EED090020BA06 /* Coro.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DCD140EED090020BA06 /* Coro.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AABB5DDB140EED090020BA06 /* power-ucontext.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DCE140EED090020BA06 /* power-ucontext.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AABB5DDC140EED090020BA06 /* taskimpl.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DCF140EED090020BA06 /* taskimpl.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AABB5DDD140EED090020BA06 /* Coroutine.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DD0140EED090020BA06 /* Coroutine.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AABB5DDE140EED090020BA06 /* Coroutine.m in Sources */ = {isa = PBXBuildFile; fileRef = AABB5DD1140EED090020BA06 /* Coroutine.m */; };
AABB5DDF140EED090020BA06 /* Future.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DD2140EED090020BA06 /* Future.h */; settings = {ATTRIBUTES = (Public, ); }; };
AABB5DE0140EED090020BA06 /* Future.m in Sources */ = {isa = PBXBuildFile; fileRef = AABB5DD3140EED090020BA06 /* Future.m */; };
AABB5DE2140EF4090020BA06 /* bsd_license.txt in Resources */ = {isa = PBXBuildFile; fileRef = AABB5DE1140EF4090020BA06 /* bsd_license.txt */; };
AABB5DEF140F16280020BA06 /* NSObject+Actor.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DED140F16280020BA06 /* NSObject+Actor.h */; settings = {ATTRIBUTES = (Public, ); }; };
AABB5DF0140F16280020BA06 /* NSObject+Actor.m in Sources */ = {isa = PBXBuildFile; fileRef = AABB5DEE140F16280020BA06 /* NSObject+Actor.m */; };
AABB5DF2140F196E0020BA06 /* IOKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AABB5DF1140F196E0020BA06 /* IOKit.framework */; };
- AABB5DF9140F357A0020BA06 /* NSURLConnection+Coroutine.h in Headers */ = {isa = PBXBuildFile; fileRef = AABB5DF7140F357A0020BA06 /* NSURLConnection+Coroutine.h */; settings = {ATTRIBUTES = (Public, ); }; };
- AABB5DFA140F357A0020BA06 /* NSURLConnection+Coroutine.m in Sources */ = {isa = PBXBuildFile; fileRef = AABB5DF8140F357A0020BA06 /* NSURLConnection+Coroutine.m */; };
+ AAD00991141F0ED200566C36 /* Mutex.h in Headers */ = {isa = PBXBuildFile; fileRef = AAD0098F141F0ED200566C36 /* Mutex.h */; };
+ AAD00992141F0ED200566C36 /* Mutex.m in Sources */ = {isa = PBXBuildFile; fileRef = AAD00990141F0ED200566C36 /* Mutex.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ AA9A97861419785000A2994E /* NSThread+Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSThread+Actor.h"; sourceTree = "<group>"; };
+ AA9A97871419785000A2994E /* NSThread+Actor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSThread+Actor.m"; sourceTree = "<group>"; };
AABB5D95140E0C220020BA06 /* ActorKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ActorKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
AABB5D98140E0C220020BA06 /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
AABB5D9B140E0C220020BA06 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
@@ -41,25 +34,14 @@
AABB5DA2140E0C220020BA06 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
AABB5DA4140E0C220020BA06 /* ActorKit-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "ActorKit-Prefix.pch"; sourceTree = "<group>"; };
AABB5DA5140E0C220020BA06 /* ActorKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ActorKit.h; sourceTree = "<group>"; };
- AABB5DC7140EED090020BA06 /* 386-ucontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "386-ucontext.h"; sourceTree = "<group>"; };
- AABB5DC8140EED090020BA06 /* amd64-ucontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "amd64-ucontext.h"; sourceTree = "<group>"; };
- AABB5DC9140EED090020BA06 /* asm.S */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.asm; path = asm.S; sourceTree = "<group>"; };
- AABB5DCA140EED090020BA06 /* Common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Common.h; sourceTree = "<group>"; };
- AABB5DCB140EED090020BA06 /* context.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = context.c; sourceTree = "<group>"; };
- AABB5DCC140EED090020BA06 /* Coro.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Coro.c; sourceTree = "<group>"; };
- AABB5DCD140EED090020BA06 /* Coro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Coro.h; sourceTree = "<group>"; };
- AABB5DCE140EED090020BA06 /* power-ucontext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "power-ucontext.h"; sourceTree = "<group>"; };
- AABB5DCF140EED090020BA06 /* taskimpl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = taskimpl.h; sourceTree = "<group>"; };
- AABB5DD0140EED090020BA06 /* Coroutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Coroutine.h; sourceTree = "<group>"; };
- AABB5DD1140EED090020BA06 /* Coroutine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = Coroutine.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
AABB5DD2140EED090020BA06 /* Future.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Future.h; sourceTree = "<group>"; };
AABB5DD3140EED090020BA06 /* Future.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = Future.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
AABB5DE1140EF4090020BA06 /* bsd_license.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = bsd_license.txt; path = license/bsd_license.txt; sourceTree = SOURCE_ROOT; };
AABB5DED140F16280020BA06 /* NSObject+Actor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Actor.h"; sourceTree = "<group>"; };
AABB5DEE140F16280020BA06 /* NSObject+Actor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Actor.m"; sourceTree = "<group>"; };
AABB5DF1140F196E0020BA06 /* IOKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = IOKit.framework; path = System/Library/Frameworks/IOKit.framework; sourceTree = SDKROOT; };
- AABB5DF7140F357A0020BA06 /* NSURLConnection+Coroutine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURLConnection+Coroutine.h"; sourceTree = "<group>"; };
- AABB5DF8140F357A0020BA06 /* NSURLConnection+Coroutine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLConnection+Coroutine.m"; sourceTree = "<group>"; };
+ AAD0098F141F0ED200566C36 /* Mutex.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Mutex.h; sourceTree = "<group>"; };
+ AAD00990141F0ED200566C36 /* Mutex.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Mutex.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -115,16 +97,15 @@
AABB5D9E140E0C220020BA06 /* ActorKit */ = {
isa = PBXGroup;
children = (
- AABB5DBD140EED090020BA06 /* coroutine */,
+ AAD0098F141F0ED200566C36 /* Mutex.h */,
+ AAD00990141F0ED200566C36 /* Mutex.m */,
AABB5DA5140E0C220020BA06 /* ActorKit.h */,
- AABB5DD0140EED090020BA06 /* Coroutine.h */,
- AABB5DD1140EED090020BA06 /* Coroutine.m */,
AABB5DD2140EED090020BA06 /* Future.h */,
AABB5DD3140EED090020BA06 /* Future.m */,
AABB5DED140F16280020BA06 /* NSObject+Actor.h */,
AABB5DEE140F16280020BA06 /* NSObject+Actor.m */,
- AABB5DF7140F357A0020BA06 /* NSURLConnection+Coroutine.h */,
- AABB5DF8140F357A0020BA06 /* NSURLConnection+Coroutine.m */,
+ AA9A97861419785000A2994E /* NSThread+Actor.h */,
+ AA9A97871419785000A2994E /* NSThread+Actor.m */,
AABB5D9F140E0C220020BA06 /* Supporting Files */,
);
path = ActorKit;
@@ -141,30 +122,6 @@
name = "Supporting Files";
sourceTree = "<group>";
};
- AABB5DBD140EED090020BA06 /* coroutine */ = {
- isa = PBXGroup;
- children = (
- AABB5DC6140EED090020BA06 /* source */,
- );
- path = coroutine;
- sourceTree = "<group>";
- };
- AABB5DC6140EED090020BA06 /* source */ = {
- isa = PBXGroup;
- children = (
- AABB5DC7140EED090020BA06 /* 386-ucontext.h */,
- AABB5DC8140EED090020BA06 /* amd64-ucontext.h */,
- AABB5DC9140EED090020BA06 /* asm.S */,
- AABB5DCA140EED090020BA06 /* Common.h */,
- AABB5DCB140EED090020BA06 /* context.c */,
- AABB5DCC140EED090020BA06 /* Coro.c */,
- AABB5DCD140EED090020BA06 /* Coro.h */,
- AABB5DCE140EED090020BA06 /* power-ucontext.h */,
- AABB5DCF140EED090020BA06 /* taskimpl.h */,
- );
- path = source;
- sourceTree = "<group>";
- };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@@ -173,16 +130,10 @@
buildActionMask = 2147483647;
files = (
AA2726621411886500FE0A43 /* ActorKit.h in Headers */,
- AABB5DD4140EED090020BA06 /* 386-ucontext.h in Headers */,
- AABB5DD5140EED090020BA06 /* amd64-ucontext.h in Headers */,
- AABB5DD7140EED090020BA06 /* Common.h in Headers */,
- AABB5DDA140EED090020BA06 /* Coro.h in Headers */,
- AABB5DDB140EED090020BA06 /* power-ucontext.h in Headers */,
- AABB5DDC140EED090020BA06 /* taskimpl.h in Headers */,
- AABB5DDD140EED090020BA06 /* Coroutine.h in Headers */,
AABB5DDF140EED090020BA06 /* Future.h in Headers */,
+ AA9A97881419785000A2994E /* NSThread+Actor.h in Headers */,
AABB5DEF140F16280020BA06 /* NSObject+Actor.h in Headers */,
- AABB5DF9140F357A0020BA06 /* NSURLConnection+Coroutine.h in Headers */,
+ AAD00991141F0ED200566C36 /* Mutex.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -246,13 +197,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- AABB5DD6140EED090020BA06 /* asm.S in Sources */,
- AABB5DD8140EED090020BA06 /* context.c in Sources */,
- AABB5DD9140EED090020BA06 /* Coro.c in Sources */,
- AABB5DDE140EED090020BA06 /* Coroutine.m in Sources */,
AABB5DE0140EED090020BA06 /* Future.m in Sources */,
AABB5DF0140F16280020BA06 /* NSObject+Actor.m in Sources */,
- AABB5DFA140F357A0020BA06 /* NSURLConnection+Coroutine.m in Sources */,
+ AA9A97891419785000A2994E /* NSThread+Actor.m in Sources */,
+ AAD00992141F0ED200566C36 /* Mutex.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
5,190 ActorKit.xcodeproj/project.xcworkspace/xcuserdata/steve.xcuserdatad/UserInterfaceState.xcuserstate
2,667 additions, 2,523 deletions not shown
View
3  ActorKit/ActorKit.h
@@ -6,7 +6,6 @@
// Copyright 2011 Steve Dekorte. BSD licensed.
//
-#import "Coroutine.h"
#import "Future.h"
#import "NSObject+Actor.h"
-#import "NSURLConnection+Coroutine.h"
+#import "NSThread+Actor.h"
View
54 ActorKit/Coroutine.h
@@ -1,54 +0,0 @@
-//
-// Coroutine.h
-// CoroutineKit
-//
-// Created by Steve Dekorte on 20110830.
-// Copyright 2011 Steve Dekorte. BSD licensed.
-//
-// I recommend using the NSObject Actor category instead of this Class directly
-
-#import <Foundation/Foundation.h>
-#import "Coro.h"
-
-@interface Coroutine : NSObject
-{
- Coro *coro;
- id target;
- SEL action;
- BOOL hasStarted;
- Coroutine *next;
- Coroutine *previous;
- id waitingOnFuture;
- NSString *name;
-}
-
-// careful with this non-retains...
-
-@property (assign, nonatomic) id target;
-@property (assign, nonatomic) SEL action;
-@property (readonly, nonatomic) BOOL hasStarted;
-@property (assign, nonatomic) Coroutine *next;
-@property (assign, nonatomic) Coroutine *previous;
-@property (assign, nonatomic) id waitingOnFuture;
-@property (retain, nonatomic) NSString *name;
-
-+ (Coroutine *)mainCoroutine;
-+ (Coroutine *)currentCoroutine;
-
-- (void)scheduleFirst;
-- (void)scheduleLast;
-- (void)unschedule;
-- (void)yield;
-
-// private
-
-- (id)initAsMain;
-
-- (size_t)stackSize;
-- (void)setStackSize:(size_t)size;
-- (size_t)bytesLeftOnStack;
-
-- (NSString *)nameId;
-- (void)showCoroutineList;
-
-@end
View
362 ActorKit/Coroutine.m
@@ -1,362 +0,0 @@
-//
-// Coroutine.m
-// CoroutineKit
-//
-// Created by Steve Dekorte on 20110830.
-// Copyright 2011 Steve Dekorte. BSD licensed.
-
-#import "Coroutine.h"
-
-@implementation Coroutine
-
-static Coroutine *mainCoroutine = nil;
-static Coroutine *currentCoroutine = nil;
-
-@synthesize target;
-@synthesize action;
-@synthesize hasStarted;
-@synthesize next;
-@synthesize previous;
-@synthesize waitingOnFuture;
-@synthesize name;
-
-static long activeCoroutineCount = 0;
-static NSTimer *activeCoroutineTimer = nil;
-
-+ (void)incrementActiveCoroutineCount
-{
- activeCoroutineCount ++;
-
- if(!activeCoroutineTimer)
- {
- activeCoroutineTimer = [NSTimer timerWithTimeInterval:1.0/30.0
- target:mainCoroutine
- selector:@selector(timer:)
- userInfo:nil
- repeats:YES];
- [activeCoroutineTimer retain];
- }
-
- if([activeCoroutineTimer isValid])
- {
- [activeCoroutineTimer fire];
- }
-}
-
-+ (void)decrementActiveCoroutineCount
-{
- activeCoroutineCount --;
-
- if(activeCoroutineCount == 0 && [activeCoroutineTimer isValid])
- {
- [activeCoroutineTimer invalidate];
- }
-}
-
-- (void)timer:userInfo
-{
- [mainCoroutine yield];
-}
-
-- (Coro *)coro
-{
- return coro;
-}
-
-+ (Coroutine *)currentCoroutine
-{
- return currentCoroutine;
-}
-
-+ (Coroutine *)mainCoroutine
-{
- if(!mainCoroutine)
- {
- mainCoroutine = [[Coroutine alloc] initAsMain];
- currentCoroutine = mainCoroutine;
- }
-
- return mainCoroutine;
-}
-
-- (id)initAsMain
-{
- self = [super init];
-
- if (self)
- {
- coro = Coro_new();
- Coro_initializeMainCoro(coro);
- hasStarted = YES;
- [self setNext:self];
- [self setPrevious:self];
- [self setName:@"MainCoroutine"];
- }
-
- return self;
-}
-
-- (id)init
-{
- self = [super init];
-
- if (self)
- {
- coro = Coro_new();
- [self setName:@"unnamed"];
- [Coroutine mainCoroutine];
- }
-
- [[self class] incrementActiveCoroutineCount];
- return self;
-}
-
-- (void)dealloc
-{
- [[self class] decrementActiveCoroutineCount];
- [self setTarget:nil]; // just to cleanup
- [self setNext:nil]; // just to cleanup
- [self setPrevious:nil]; // just to cleanup
- [self setName:nil];
- Coro_free(coro);
- [super dealloc];
-}
-
-- (size_t)stackSize
-{
- return Coro_stackSize(coro);
-}
-
-- (void)setStackSize:(size_t)size
-{
- Coro_setStackSize_(coro, size);
-}
-
-- (size_t)bytesLeftOnStack
-{
- return Coro_bytesLeftOnStack(coro);
-}
-
-//typedef void (CoroStartCallback)(void *);
-
-- (void)startup
-{
- [target performSelector:action];
-}
-
-static void callback(void *aCoroutine)
-{
- Coroutine *self = (Coroutine *)aCoroutine;
- [self startup];
-}
-
-- (void)start
-{
- #ifdef COROUTINE_DEBUG
- printf("%s start\n", [[self nameId] UTF8String]);
- #endif
-
- if(!hasStarted)
- {
- hasStarted = YES;
- Coroutine *lastCoroutine = currentCoroutine;
- currentCoroutine = self;
- Coro_startCoro_([lastCoroutine coro], [self coro], (void *)self, callback);
- }
- else
- {
- [NSException raise:@"Coroutine" format:@"attempt to start a Coroutine twice"];
- }
-}
-
-- (void)resume
-{
-
- if(!hasStarted)
- {
- [self start];
- }
- else
- {
-#ifdef COROUTINE_DEBUG
- printf("%s resume\n", [[self nameId] UTF8String]);
-#endif
- Coroutine *lastCoroutine = currentCoroutine;
- currentCoroutine = self;
- Coro_switchTo_([lastCoroutine coro], [self coro]);
- }
-}
-
-- (void)remove
-{
- Coroutine *n = next;
- Coroutine *p = previous;
-
- [p setNext:n];
- [n setPrevious:p];
-
- [self setNext:nil];
- [self setPrevious:nil];
-}
-
-- (void)checkLinkedList
-{
- if(next == nil)
- {
- [NSException raise:@"Coroutine" format:@"missing next"];
- }
-
- if(previous == nil)
- {
- [NSException raise:@"Coroutine" format:@"missing previous"];
- }
-}
-
-- (void)insertFirst:(Coroutine *)aCoroutine
-{
-#ifdef COROUTINE_DEBUG
- [self checkLinkedList];
- printf("%s insertFirst: %s\n", [[self nameId] UTF8String], [[aCoroutine nameId] UTF8String]);
-#endif
-
- if(aCoroutine == self)
- {
- return;
- }
-
- Coroutine *n = next;
- //Coroutine *p = previous;
-
- [aCoroutine remove];
- [aCoroutine setNext:n];
- [aCoroutine setPrevious:self];
- [n setPrevious:aCoroutine];
- [self setNext:aCoroutine];
-
-#ifdef COROUTINE_DEBUG
- [self showCoroutineList];
-#endif
-}
-
-- (void)insertLast:(Coroutine *)aCoroutine
-{
-#ifdef COROUTINE_DEBUG
- [self checkLinkedList];
- printf("%s insertLast: %s\n", [[self nameId] UTF8String], [[aCoroutine nameId] UTF8String]);
-#endif
- if(aCoroutine == self)
- {
- return;
- }
-
-
- [aCoroutine remove];
-
- //Coroutine *n = next;
- Coroutine *p = previous;
- [self setPrevious:aCoroutine];
-
- [aCoroutine setNext:self];
- [aCoroutine setPrevious:p];
- [p setNext:aCoroutine];
-
-#ifdef COROUTINE_DEBUG
- [self showCoroutineList];
- printf("done insertLast\n");
-#endif
-}
-
-- (void)scheduleFirst
-{
-#ifdef COROUTINE_DEBUG
- printf("%s scheduleFirst\n", [[self nameId] UTF8String]);
-#endif
- [currentCoroutine insertFirst:self];
-}
-
-- (void)scheduleLast
-{
-#ifdef COROUTINE_DEBUG
- printf("%s scheduleLast\n", [[self nameId] UTF8String]);
-#endif
- [currentCoroutine insertLast:self];
-}
-
-- (void)yield
-{
-#ifdef COROUTINE_DEBUG
- printf("%s yield\n", [[self nameId] UTF8String]);
-#endif
- if(currentCoroutine == self)
- {
- return;
- }
-
- [[currentCoroutine next] resume];
-}
-
-- (void)unschedule
-{
- if(currentCoroutine == self)
- {
- /*
- if(currentCoroutine == mainCoroutine)
- {
- // yield
- [NSException raise:@"Coroutine" format:@"attempt to unschedule main coroutine"];
- return;
- }
- */
-
-#ifdef COROUTINE_DEBUG
- printf("%s unschedule current\n", [[self nameId] UTF8String]);
-#endif
- Coroutine *nextCoroutine = [self next];
-
- if(nextCoroutine != currentCoroutine)
- {
- [self remove];
- [nextCoroutine resume];
- }
- else
- {
- printf("only one coroutine, so resuming instead of unscheduling it!\n");
- }
- }
- else
- {
-#ifdef COROUTINE_DEBUG
- printf("%s unschedule non-current\n", [[self nameId] UTF8String]);
-#endif
- [self remove];
- }
-}
-
-- (NSString *)nameId
-{
- return [self name];
- //return [NSString stringWithFormat:@"Coroutine-%@-%p", [self name], (void *)self];
-}
-
-- (void)showCoroutineListUntil:aCoroutine
-{
-#ifdef COROUTINE_DEBUG
- printf(" %s\n", [[self nameId] UTF8String]);
-#endif
-
- if(next == aCoroutine)
- {
- return;
- }
-
- [next showCoroutineListUntil:aCoroutine];
-}
-
-- (void)showCoroutineList
-{
- printf("Coroutine list:\n");
- [self showCoroutineListUntil:self];
- printf("\n");
-}
-
-@end
View
11 ActorKit/Future.h
@@ -5,7 +5,7 @@
// Created by Steve Dekorte on 20110830.
// Copyright 2011 Steve Dekorte. BSD licensed.
-
+#import "Mutex.h"
@interface Future : NSObject
{
@@ -15,20 +15,25 @@
id value;
id nextFuture;
BOOL done;
- NSMutableSet *waitingCoroutines;
+ NSMutableSet *waitingThreads;
NSException *exception;
NSError *error;
+ Mutex *lock;
+ id delegate;
+ SEL action;
}
// private
+@property (assign, nonatomic) Mutex *lock;
@property (assign, nonatomic) id actor;
@property (assign, nonatomic) SEL selector;
@property (retain, nonatomic) id argument;
@property (retain, nonatomic) id value;
@property (retain, nonatomic) id nextFuture;
-@property (retain, nonatomic) NSMutableSet *waitingCoroutines;
+@property (retain, nonatomic) NSMutableSet *waitingThreads;
@property (retain, nonatomic) NSError *error;
+@property (assign, nonatomic) id delegate;
- (void)append:(Future *)aFuture;
- (void)send;
View
71 ActorKit/Future.m
@@ -7,18 +7,20 @@
//
#import "Future.h"
-#import "Coroutine.h"
+#import "NSThread+Actor.h"
@implementation Future
+@synthesize lock;
@synthesize actor;
@synthesize selector;
@synthesize argument;
@synthesize value;
@synthesize nextFuture;
-@synthesize waitingCoroutines;
+@synthesize waitingThreads;
@synthesize exception;
@synthesize error;
+@synthesize delegate;
- (id)init
{
@@ -26,8 +28,9 @@ - (id)init
if (self)
{
- [self setWaitingCoroutines:[NSMutableSet set]];
- // Initialization code here.
+ done = NO;
+ [self setLock:[[[Mutex alloc] init] autorelease]];
+ [self setWaitingThreads:[NSMutableSet set]];
}
return self;
@@ -39,9 +42,11 @@ - (void)dealloc
[self setArgument:nil];
[self setValue:nil];
[self setNextFuture:nil];
- [self setWaitingCoroutines:nil];
+ [self setWaitingThreads:nil];
[self setException:nil];
[self setError:nil];
+ [self setDelegate:nil];
+ [self setLock:nil];
[super dealloc];
}
@@ -61,41 +66,55 @@ - (void)send
{
@try
{
- printf("Future send [%s %s %s]\n",
+ /*
+ printf("Future send [%s %s%s]\n",
[[actor className] UTF8String],
[NSStringFromSelector(selector) UTF8String],
[[argument className] UTF8String]);
+ */
id r = [actor performSelector:selector withObject:argument];
[self setResult:r];
}
@catch (NSException *e)
{
+ printf("exception\n");
[self setException:e];
[self setResult:nil];
}
+
+ for(NSThread *waitingThread in waitingThreads)
+ {
+ [waitingThread setWaitingOnFuture:nil];
+ }
+
+ [waitingThreads removeAllObjects];
+ [lock resumeThread];
}
- (void)setResult:(id)anObject
{
- [self setValue:anObject];
+ if(done)
+ {
+ return;
+ }
+
done = YES;
+
+ [self setValue:anObject];
- for(Coroutine *waitingCoroutine in waitingCoroutines)
+ if (delegate && action)
{
- [waitingCoroutine setWaitingOnFuture:nil];
- [waitingCoroutine scheduleLast];
+ [delagate performSelector:action withObject:self];
}
-
- [waitingCoroutines removeAllObjects];
}
-- (BOOL)isWaitingOnCurrentCoroutine
+- (BOOL)isWaitingOnCurrentThread
{
- // recursion should void loop since the deadlock detection prevents loops
+ // thie recursion should avoid loop since the deadlock detection prevents loops
- for(Coroutine *waitingCoroutine in waitingCoroutines)
+ for(NSThread *waitingThread in waitingThreads)
{
- if([[waitingCoroutine waitingOnFuture] isWaitingOnCurrentCoroutine])
+ if([[waitingThread waitingOnFuture] isWaitingOnCurrentThread])
{
return YES;
}
@@ -110,23 +129,17 @@ - (BOOL)isWaitingOnCurrentCoroutine
{
return value;
}
-
- while([self isWaitingOnCurrentCoroutine]) // loop in case exception is resumed
+
+ [waitingThreads addObject:[NSThread currentThread]];
+
+ if([self isWaitingOnCurrentThread])
{
[NSException raise:@"Future" format:@"waiting for result on this coroutine would cause a deadlock"];
+ return nil;
}
- [waitingCoroutines addObject:[Coroutine currentCoroutine]];
- [[Coroutine currentCoroutine] setWaitingOnFuture:self];
-
- [[Coroutine currentCoroutine] unschedule];
-
- while(!done) // loop in case exception is resumed
- {
- [NSException raise:@"Future" format:@"attempt to resume coroutine waiting on future before result is ready"];
- [[Coroutine currentCoroutine] unschedule];
- }
-
+ [lock pauseThread];
+
if(exception)
{
// guessing we have to wrap the exception so the stack info of original will be available
View
25 ActorKit/Mutex.h
@@ -0,0 +1,25 @@
+//
+// Mutex.h
+// ActorKit
+//
+// Created by Steve Dekorte on 20110830.
+// Copyright 2011 Steve Dekorte. BSD licensed.
+
+
+
+@interface Mutex : NSObject
+{
+ pthread_mutexattr_t mutexAttributes;
+ pthread_mutex_t mutex;
+
+ pthread_condattr_t conditionAttributes;
+ pthread_cond_t condition;
+
+ BOOL isPaused;
+}
+
+- (BOOL)isPaused;
+- (void)pauseThread;
+- (void)resumeThread;
+
+@end
View
88 ActorKit/Mutex.m
@@ -0,0 +1,88 @@
+//
+// Mutex.m
+// ActorKit
+//
+// Created by Steve Dekorte on 20110830.
+// Copyright 2011 Steve Dekorte. BSD licensed.
+//
+
+#import "Mutex.h"
+#import <pthread.h>
+
+@implementation Mutex
+
+- (id)init
+{
+ self = [super init];
+
+ if (self)
+ {
+ pthread_mutexattr_init(&mutexAttributes);
+ pthread_mutexattr_settype(&mutexAttributes, PTHREAD_MUTEX_RECURSIVE);
+ pthread_mutex_init(&mutex, &mutexAttributes);
+
+ pthread_condattr_init(&conditionAttributes);
+ pthread_cond_init(&condition, &conditionAttributes);
+ }
+
+ return self;
+}
+
+- (void)dealloc
+{
+ pthread_mutexattr_destroy(&mutexAttributes);
+ pthread_mutex_destroy(&mutex);
+ pthread_cond_destroy(&condition);
+ pthread_condattr_destroy(&conditionAttributes);
+ [super dealloc];
+}
+
+/*
+- (void)lock
+{
+ pthread_mutex_lock(&mutex);
+}
+
+- (void)unlock
+{
+ pthread_mutex_unlock(&mutex);
+}
+
+- (BOOL)tryLock
+{
+ return pthread_mutex_trylock(&mutex) == 0; // 0 means we got the lock
+}
+*/
+
+- (BOOL)isPaused
+{
+ return isPaused;
+}
+
+- (void)pauseThread
+{
+ //printf("%p pauseThread\n", (void *)[NSThread currentThread]);
+
+ isPaused = YES;
+ pthread_mutex_lock(&mutex);
+ while (isPaused)
+ {
+ pthread_cond_wait( &condition, &mutex);
+ }
+ pthread_mutex_unlock(&mutex);
+}
+
+- (void)resumeThread
+{
+ //printf("%p resumeThread\n", (void *)[NSThread currentThread]);
+
+ if(isPaused)
+ {
+ isPaused = NO;
+ pthread_mutex_lock(&mutex);
+ pthread_cond_broadcast(&condition);
+ pthread_mutex_unlock(&mutex);
+ }
+}
+
+@end
View
3  ActorKit/NSObject+Actor.h
@@ -6,14 +6,13 @@
// Copyright 2011 Steve Dekorte. BSD licensed.
//
-#import "Coroutine.h"
#import "Future.h"
@interface NSObject (NSObject_Actor)
// private
-- (void)actorRunLoop;
+- (void)actorRunLoop:sender;
// public
View
111 ActorKit/NSObject+Actor.m
@@ -7,12 +7,21 @@
//
#import "NSObject+Actor.h"
+#import "NSThread+Actor.h"
#import <objc/runtime.h>
-
@implementation NSObject (NSObject_Actor)
-static long activeActorCount = 0;
+- (void)setMutex:(Mutex *)aMutex
+{
+ objc_setAssociatedObject(self, "mutex", aMutex, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (Mutex *)mutex
+{
+ return (Mutex *)objc_getAssociatedObject(self, "mutex");
+}
+
- (void)setFirstFuture:(Future *)aFuture
{
@@ -24,35 +33,51 @@ - (Future *)firstFuture
return (Future *)objc_getAssociatedObject(self, "firstFuture");
}
-- (void)setActorCoroutine:(Coroutine *)aCoroutine
+- (void)setActorThread:(NSThread *)aThread
{
- objc_setAssociatedObject(self, "actorCoroutine", aCoroutine, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+ objc_setAssociatedObject(self, "actorThread", aThread, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
+}
+
+- (NSThread *)actorThread
+{
+ return (NSThread *)objc_getAssociatedObject(self, "actorThread");;
}
-- (Coroutine *)actorCoroutine
+- (NSThread *)actorThreadCreateOrResumeIfNeeded
{
- Coroutine *c = (Coroutine *)objc_getAssociatedObject(self, "actorCoroutine");
-
- if(!c)
+ NSThread *thread = [self actorThread];
+
+ if(!thread)
{
- c = [[[Coroutine alloc] init] autorelease];
- [c setTarget:self];
- [c setAction:@selector(actorRunLoop)];
- [self setActorCoroutine:c];
- [c setName:[NSString stringWithFormat:@"%@", [self className]]];
+ [self setMutex:[[[Mutex alloc] init] autorelease]];
+ thread = [[[NSThread alloc] initWithTarget:self selector:@selector(actorRunLoop:) object:nil] autorelease];
+ [self setActorThread:thread];
+ [thread setName:[NSString stringWithFormat:@"%@", [self className]]];
+ [thread start];
+ }
+ else
+ {
+ [[self mutex] resumeThread];
}
- return c;
+ return thread;
}
+// still need to implement dealloc
+
/*
- (void)dealloc
{
- // coros retain the Future's they are waiting on, which retains the actor
+ // threads retain the Future's they are waiting on, which retains the actor
// so dealloc should only occur when it's safe of dependencies
- [self setFirstFuture:nil];
- [self setCoroutine:nil];
- [super dealloc];
+
+ if([self actorThread])
+ {
+ [[self actorThread] cancel];
+ }
+
+ [self setFirstFuture:nil];
+ [self setActorThread:nil];
}
*/
@@ -60,14 +85,6 @@ - (Future *)newFuture
{
Future *future = [[[Future alloc] init] autorelease];
- if([self firstFuture])
- {
- [[self firstFuture] append:future];
- }
- else
- {
- [self setFirstFuture:future];
- }
return future;
}
@@ -79,37 +96,55 @@ - (void)asyncPerformSelector:(SEL)selector withObject:anObject
- (Future *)futurePerformSelector:(SEL)selector withObject:anObject
{
+ NSLock *lock = [[self actorThread] lock];
+ [lock lock];
+
Future *future = [self newFuture];
[future setActor:self];
[future setSelector:selector];
[future setArgument:anObject];
- [[self actorCoroutine] scheduleLast];
+
+ if([self firstFuture])
+ {
+ [[self firstFuture] append:future];
+ }
+ else
+ {
+ [self setFirstFuture:future];
+ }
+
+ [self actorThreadCreateOrResumeIfNeeded];
+ [lock unlock];
return future;
}
-- (void)actorRunLoop
+- (void)actorRunLoop:sender
{
- while(YES) // coroutines never return, they are only unscheduled
+ NSLock *lock = [[self actorThread] lock];
+
+ if([NSThread currentThread] != [self actorThread])
+ {
+ [NSException raise:@"Actor" format:@"attempt to start actor loop from another thread"];
+ }
+
+ while(![[NSThread currentThread] isCancelled])
{
- activeActorCount ++;
-
- if([Coroutine currentCoroutine] != [self actorCoroutine])
- {
- [NSException raise:@"Actor" format:@"actorRunLoop not running from actor coroutine!"];
- }
+ NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool
while([self firstFuture])
{
Future *f = [self firstFuture];
[f send]; // exceptions are caught within the send method
+ [lock lock];
[self setFirstFuture:[f nextFuture]];
- [[self actorCoroutine] yield];
+ [lock unlock];
}
- activeActorCount --;
- [[self actorCoroutine] unschedule];
+ [pool release];
+
+ [[self mutex] pauseThread];
}
}
View
16 ActorKit/NSURLConnection+Coroutine.h
@@ -1,16 +0,0 @@
-//
-// NSURLConnection+Future.h
-// ActorKit
-//
-// Created by Steve Dekorte on 20110831.
-// Copyright 2011 Steve Dekorte. BSD licensed.
-//
-
-
-
-@interface NSURLConnection (NSURLConnection_Coroutine)
-
-+ (NSDictionary *)requestURLString:(NSString *)urlString;
-+ (NSDictionary *)sendRequest:(NSURLRequest *)request;
-
-@end
View
50 ActorKit/NSURLConnection+Coroutine.m
@@ -1,50 +0,0 @@
-//
-// NSURLConnection+Future.m
-// ActorKit
-//
-// Created by Steve Dekorte on 20110831.
-// Copyright 2011 Steve Dekorte. BSD licensed.
-//
-
-#import "NSURLConnection+Coroutine.h"
-#import "Coroutine.h"
-
-@implementation NSURLConnection (NSURLConnection_Coroutine)
-
-+ (NSDictionary *)requestURLString:(NSString *)urlString
-{
- NSURL *url = [NSURL URLWithString:urlString];
-
- NSURLRequest *theRequest = [NSURLRequest requestWithURL:url
- cachePolicy:NSURLRequestUseProtocolCachePolicy
- timeoutInterval:60.0];
- return [self sendRequest:theRequest];
-}
-
-+ (NSDictionary *)sendRequest:(NSURLRequest *)request
-{
- Coroutine *coroutine = [Coroutine currentCoroutine];
- __block NSURLResponse *theResponse = nil;
- __block NSData *theData = nil;
- __block NSError *theError = nil;
-
- [NSURLConnection sendAsynchronousRequest:request
- queue:[NSOperationQueue mainQueue]
- completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
- {
- theResponse = response;
- theData = data;
- theError = error;
- [coroutine scheduleLast];
- }];
-
- [coroutine unschedule]; // pauses coroutine until completionHandler resumes it
-
- NSMutableDictionary *dict = [NSMutableDictionary dictionary];
- [dict setObject:theResponse forKey:@"response"];
- [dict setObject:theData forKey:@"data"];
- [dict setObject:theError forKey:@"error"];
- return dict;
-}
-
-@end
View
121 ActorKit/coroutine/source/386-ucontext.h
@@ -1,121 +0,0 @@
-#define setcontext(u) setmcontext(&(u)->uc_mcontext)
-#define getcontext(u) getmcontext(&(u)->uc_mcontext)
-typedef struct mcontext mcontext_t;
-typedef struct ucontext ucontext_t;
-
-extern int swapcontext(ucontext_t*, const ucontext_t*);
-extern void makecontext(ucontext_t*, void(*)(void), int, ...);
-extern int getmcontext(mcontext_t*);
-extern void setmcontext(const mcontext_t*);
-
-/*-
- * Copyright (c) 1999 Marcel Moolenaar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/sys/ucontext.h,v 1.4 1999/10/11 20:33:17 luoqi Exp $
- */
-
-/* #include <machine/ucontext.h> */
-
-/*-
- * Copyright (c) 1999 Marcel Moolenaar
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer
- * in this position and unchanged.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/i386/include/ucontext.h,v 1.4 1999/10/11 20:33:09 luoqi Exp $
- */
-
-struct mcontext {
- /*
- * The first 20 fields must match the definition of
- * sigcontext. So that we can support sigcontext
- * and ucontext_t at the same time.
- */
- int mc_onstack; /* XXX - sigcontext compat. */
- int mc_gs;
- int mc_fs;
- int mc_es;
- int mc_ds;
- int mc_edi;
- int mc_esi;
- int mc_ebp;
- int mc_isp;
- int mc_ebx;
- int mc_edx;
- int mc_ecx;
- int mc_eax;
- int mc_trapno;
- int mc_err;
- int mc_eip;
- int mc_cs;
- int mc_eflags;
- int mc_esp; /* machine state */
- int mc_ss;
-
- int mc_fpregs[28]; /* env87 + fpacc87 + u_long */
- int __spare__[17];
-};
-
-struct ucontext {
- /*
- * Keep the order of the first two fields. Also,
- * keep them the first two fields in the structure.
- * This way we can have a union with struct
- * sigcontext and ucontext_t. This allows us to
- * support them both at the same time.
- * note: the union is not defined, though.
- */
- sigset_t uc_sigmask;
- mcontext_t uc_mcontext;
-
- struct __ucontext *uc_link;
- stack_t uc_stack;
- int __spare__[8];
-};
-
-
View
226 ActorKit/coroutine/source/Common.h
@@ -1,226 +0,0 @@
-
-//metadoc Common copyright Steve Dekorte 2002
-//metadoc Common license BSD revised
-/*metadoc Common description
-This is a header that all other source files should include.
-These defines are helpful for doing OS specific checks in the code.
- */
-
-
-#ifndef IOCOMMON_DEFINED
-#define IOCOMMON_DEFINED 1
-
-/*#define LOW_MEMORY_SYSTEM 1*/
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-
-
-#if defined (__SVR4) && defined (__sun)
-#include <inttypes.h>
-#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
-#include <inttypes.h>
-#elif !defined(__SYMBIAN32__) && !defined(_MSC_VER) && !defined(__NeXT__)
-#include <stdint.h>
-#else
-typedef unsigned char uint8_t;
-typedef signed char int8_t;
-typedef unsigned short uint16_t;
-typedef signed short int16_t;
-typedef unsigned long uint32_t;
-typedef signed long int32_t;
-/*
- typedef unsigned long uint64_t;
- typedef signed long int64_t;
- */
-typedef unsigned long long uint64_t;
-typedef long long int64_t;
-#endif
-
-/* Windows stuff */
-
-/*
-#if defined _WIN32 || defined __WINS__ || defined _MSC_VER
-# define inline __inline
-# define snprintf _snprintf
-# ifndef __MINGW32__
-# define usleep(x) Sleep(((x)+999)/1000)
-# endif
-
-# define HAS_FIBERS 1
-
-# define ON_WINDOWS 1
-
-// Enable fibers.
-# ifndef _WIN32_WINNT
-# define _WIN32_WINNT 0x0400
-# endif
-
-// This also includes windows.h.
-# include <winsock2.h>
-
-# if !defined __MINGW32__
-# if defined BUILDING_BASEKIT_DLL || defined BUILDING_IOVMALL_DLL
-# define BASEKIT_API __declspec(dllexport)
-# else
-# define BASEKIT_API __declspec(dllimport)
-# endif
-# else
-# define BASEKIT_API
-# endif
-*/
-#if defined(WIN32) || defined(__WINS__) || defined(__MINGW32__) || defined(_MSC_VER)
-#define inline __inline
-#define snprintf _snprintf
-#ifndef __MINGW32__
-#define usleep(x) Sleep(((x)+999)/1000)
-#endif
-#define ssize_t SSIZE_T
-
-#define HAS_FIBERS 1
-
-#define ON_WINDOWS 1
-
-// this also includes windows.h
-#include <winsock2.h>
-
-//#if !defined(__MINGW32__)
-#if defined(BUILDING_BASEKIT_DLL) || defined(BUILDING_IOVMALL_DLL)
-#define BASEKIT_API __declspec(dllexport)
-#else
-#define BASEKIT_API __declspec(dllimport)
-#endif
-//#else
-//#define BASEKIT_API
-//#endif
-
-/*
-# ifndef _SYS_STDINT_H_
-# include "PortableStdint.h"
-# endif
- */
-
-# if !defined __MINGW32__
-/* disable compile warnings which are always treated
-as errors in my dev settings */
-
-# pragma warning( disable : 4244 )
-/* warning C4244: 'function' : conversion from 'double ' to 'int ', possible loss of data */
-
-# pragma warning( disable : 4996 )
-/* warning C4996: 'function' : This function or variable may be unsafe. Consider using 'function_s' instead */
-
-# pragma warning( disable : 4018 )
-/* warning C4018: 'operator' : signed/unsigned mismatch */
-
-/*# pragma warning( disable : 4090 ) */
-/* warning C4090: 'function' : different 'const' qualifiers */
-
-/*# pragma warning( disable : 4024 )*/
-/* warning C4024: different types for formal and actual parameter */
-
-/*# pragma warning( disable : 4761 ) */
-/* warning C4761: integral size mismatch in argument; conversion supplied */
-
-/*# pragma warning( disable : 4047 ) */
-/* warning C4047: '=' : 'char *' differs in levels of indirection from 'int ' */
-# define ARCHITECTURE_x86 1
-# endif
-
-/* io_malloc, io_realloc, io_free undefined */
-# if !defined __SYMBIAN32__
-# include <memory.h>
-
-/* strlen undefined */
-# include <string.h>
-# include <malloc.h> /* for calloc */
-# endif
-#else
-
-// Not on windows so define this away
-# define BASEKIT_API
-
-#endif
-
-/*
- [DBCS Enabling]
-
- DBCS (Short for Double-Byte Character Set), a character set that uses two-byte (16-bit) characters. Some languages, such as Chinese, Japanese and Korean (CJK), have writing schemes with many different characters that cannot be represented with single-byte codes such as ASCII and EBCDIC.
-
- In CJK world, CES (Character Encoding Scheme) and CCS (Coded Character Set) are actually different concept(one CES may contain multiple CCS).
- For example, EUC-JP is a CES which includes CCS of ASCII and JIS X 0208 (optionally JIS X 0201 Kana and JIS X 0212).
-
- In Japanese (because I am Japanese),
- While EUC-JP and UTF-8 Map ASCII unchanged, ShiftJIS not (However ShiftJIS is de facto standard in Japan). For example, {0x95, 0x5c} represents one character. in ASCII, second byte(0x5c) is back slash character.
- */
-
-/*
- check whether double-byte character. supported only ShiftJIS.
- if you want to use ShiftJIS characters in string literal, set compiler option -DDBCS_ENABLED=1.
- */
-
-#if DBCS_ENABLED
-#define ismbchar(c) ISSJIS((unsigned char)c)
-#define mbcharlen(c) 2
-#define ISSJIS(c) ((c >= 0x81 && c <= 0x9f) || (c >= 0xe0 && c <= 0xfc))
-#else
-#define ismbchar(c) 0
-#define mbcharlen(c) 1
-#endif /* DBCS_ENABLED */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-//#define IO_CHECK_ALLOC
-
-#ifdef IO_CHECK_ALLOC
- BASEKIT_API size_t io_memsize(void *ptr);
-
- #define io_malloc(size) io_real_malloc(size, __FILE__, __LINE__)
- BASEKIT_API void *io_real_malloc(size_t size, char *file, int line);
-
- #define io_calloc(count, size) io_real_calloc(count, size, __FILE__, __LINE__)
- BASEKIT_API void *io_real_calloc(size_t count, size_t size, char *file, int line);
-
- #define io_realloc(ptr, size) io_real_realloc(ptr, size, __FILE__, __LINE__)
- BASEKIT_API void *io_real_realloc(void *ptr, size_t newSize, char *file, int line);
-
- BASEKIT_API void io_free(void *ptr);
- BASEKIT_API void io_show_mem(char *s);
- BASEKIT_API size_t io_maxAllocatedBytes(void);
- BASEKIT_API void io_resetMaxAllocatedBytes(void);
- BASEKIT_API size_t io_frees(void);
- BASEKIT_API size_t io_allocs(void);
- BASEKIT_API size_t io_allocatedBytes(void);
-
- BASEKIT_API void io_showUnfreed(void);
-#else
- #define io_memsize
- #define io_malloc malloc
- #define io_calloc calloc
- #define io_realloc io_freerealloc
- #define io_free free
- #define io_show_mem
-
- #define io_maxAllocatedBytes() 0
- #define io_frees() 0
- #define io_allocs() 0
- #define io_allocatedBytes() 0
- #define io_resetMaxAllocatedBytes()
-#endif
-
-BASEKIT_API void *cpalloc(const void *p, size_t size);
-BASEKIT_API void *io_freerealloc(void *p, size_t size);
-
-int io_isBigEndian(void);
-BASEKIT_API uint32_t io_uint32InBigEndian(uint32_t i);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
-
-
View
859 ActorKit/coroutine/source/Coro.c
@@ -1,859 +0,0 @@
-/*
- Credits
-
- Originally based on Edgar Toernig's Minimalistic cooperative multitasking
- http://www.goron.de/~froese/
- reorg by Steve Dekorte and Chis Double
- Symbian and Cygwin support by Chis Double
- Linux/PCC, Linux/Opteron, Irix and FreeBSD/Alpha, ucontext support by Austin Kurahone
- FreeBSD/Intel support by Faried Nawaz
- Mingw support by Pit Capitain
- Visual C support by Daniel Vollmer
- Solaris support by Manpreet Singh
- Fibers support by Jonas Eschenburg
- Ucontext arg support by Olivier Ansaldi
- Ucontext x86-64 support by James Burgess and Jonathan Wright
- Russ Cox for the newer portable ucontext implementions.
- Mac OS X support by Jorge Acereda
- Guessed setjmp support (Android/Mac OS X/others?) by Jorge Acereda
-
- Notes
-
- This is the system dependent coro code.
- Setup a jmp_buf so when we longjmp, it will invoke 'func' using 'stack'.
- Important: 'func' must not return!
-
- Usually done by setting the program counter and stack pointer of a new, empty stack.
- If you're adding a new platform, look in the setjmp.h for PC and SP members
- of the stack structure
-
- If you don't see those members, Kentaro suggests writting a simple
- test app that calls setjmp and dumps out the contents of the jmp_buf.
- (The PC and SP should be in jmp_buf->__jmpbuf).
-
- Using something like GDB to be able to peek into register contents right
- before the setjmp occurs would be helpful also.
- */
-
-//#include "Base.h"
-#include "Coro.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stddef.h>
-#include "taskimpl.h"
-
-#ifdef USE_VALGRIND
-#include <valgrind/valgrind.h>
-#define STACK_REGISTER(coro) \
-{ \
- Coro *c = (coro); \
- c->valgrindStackId = \
- VALGRIND_STACK_REGISTER(c->stack, \
- (char*) c->stack + c->requestedStackSize); \
-}
-
-#define STACK_DEREGISTER(coro) \
-VALGRIND_STACK_DEREGISTER((coro)->valgrindStackId)
-
-#else
-#define STACK_REGISTER(coro)
-#define STACK_DEREGISTER(coro)
-#endif
-
-typedef struct CallbackBlock
-{
- void *context;
- CoroStartCallback *func;
-#ifdef USE_FIBERS
- Coro* associatedCoro;
-#endif
-} CallbackBlock;
-
-
-Coro *Coro_new(void)
-{
- Coro *self = (Coro *)io_calloc(1, sizeof(Coro));
- self->requestedStackSize = CORO_DEFAULT_STACK_SIZE;
- self->allocatedStackSize = 0;
-
-#ifdef USE_FIBERS
- self->fiber = NULL;
-#else
- self->stack = NULL;
-#endif
- return self;
-}
-
-void Coro_allocStackIfNeeded(Coro *self);
-
-#ifndef USE_FIBERS
-void Coro_allocStackIfNeeded(Coro *self)
-{
- if (self->stack && self->requestedStackSize < self->allocatedStackSize)
- {
- io_free(self->stack);
- self->stack = NULL;
- self->requestedStackSize = 0;
- }
-
- if (!self->stack)
- {
- self->stack = (void *)io_calloc(1, self->requestedStackSize + 16);
- self->allocatedStackSize = self->requestedStackSize;
- //printf("Coro_%p allocating stack size %i\n", (void *)self, self->requestedStackSize);
- STACK_REGISTER(self);
- }
-}
-#endif
-
-void Coro_free(Coro *self)
-{
-#ifdef USE_FIBERS
- // If this coro has a fiber, delete it.
- // Don't delete the main fiber. We don't want to commit suicide.
- if (self->fiber && !self->isMain)
- {
- DeleteFiber(self->fiber);
- }
-#else
- STACK_DEREGISTER(self);
- if (self->stack)
- {
- io_free(self->stack);
- }
-#endif
-
- //printf("Coro_%p io_free\n", (void *)self);
-
- io_free(self);
-}
-
-// stack
-
-void *Coro_stack(Coro *self)
-{
- return self->stack;
-}
-
-size_t Coro_stackSize(Coro *self)
-{
- return self->requestedStackSize;
-}
-
-void Coro_setStackSize_(Coro *self, size_t sizeInBytes)
-{
- self->requestedStackSize = sizeInBytes;
- //self->stack = (void *)io_realloc(self->stack, sizeInBytes);
- //printf("Coro_%p io_reallocating stack size %i\n", (void *)self, sizeInBytes);
-}
-
-#if __GNUC__ == 4
-uint8_t *Coro_CurrentStackPointer(void) __attribute__ ((noinline));
-#endif
-
-uint8_t *Coro_CurrentStackPointer(void)
-{
- uint8_t a;
- uint8_t *b = &a; // to avoid compiler warning about unused variables
- return b;
-}
-
-size_t Coro_bytesLeftOnStack(Coro *self)
-{
- unsigned char dummy;
- ptrdiff_t p1 = (ptrdiff_t)(&dummy);
- ptrdiff_t p2 = (ptrdiff_t)Coro_CurrentStackPointer();
- int stackMovesUp = p2 > p1;
- ptrdiff_t start = ((ptrdiff_t)self->stack);
- ptrdiff_t end = start + self->requestedStackSize;
-
- if (stackMovesUp) // like PPC
- return end - p1;
- else // like x86
- return p1 - start;
-}
-
-int Coro_stackSpaceAlmostGone(Coro *self)
-{
- return Coro_bytesLeftOnStack(self) < CORO_STACK_SIZE_MIN;
-}
-
-void Coro_initializeMainCoro(Coro *self)
-{
- self->isMain = 1;
-#ifdef USE_FIBERS
- // We must convert the current thread into a fiber if it hasn't already been done.
- if ((LPVOID) 0x1e00 == GetCurrentFiber()) // value returned when not a fiber
- {
- // Make this thread a fiber and set its data field to the main coro's address
- ConvertThreadToFiber(self);
- }
- // Make the main coro represent the current fiber
- self->fiber = GetCurrentFiber();
-#endif
-}
-
-void Coro_startCoro_(Coro *self, Coro *other, void *context, CoroStartCallback *callback)
-{
- CallbackBlock sblock;
- CallbackBlock *block = &sblock;
- //CallbackBlock *block = malloc(sizeof(CallbackBlock)); // memory leak
- block->context = context;
- block->func = callback;
-
-#ifdef USE_FIBERS
- block->associatedCoro = other;
-#else
- Coro_allocStackIfNeeded(other);
-#endif
- Coro_setup(other, block);
- Coro_switchTo_(self, other);
-}
-
-/*
-void Coro_startCoro_(Coro *self, Coro *other, void *context, CoroStartCallback *callback)
-{
- globalCallbackBlock.context = context;
- globalCallbackBlock.func = callback;
-#ifndef USE_FIBERS
- Coro_allocStackIfNeeded(other);
-#endif
- Coro_setup(other, &globalCallbackBlock);
- Coro_switchTo_(self, other);
-}
-*/
-
-void Coro_StartWithArg(unsigned int hiArg, unsigned int loArg);
-
-#if defined(USE_UCONTEXT) && defined(__x86_64__)
-void Coro_StartWithArg(unsigned int hiArg, unsigned int loArg)
-{
- CallbackBlock *block = (CallbackBlock*)(((long long)hiArg << 32) | (long long)loArg);
- (block->func)(block->context);
- printf("Scheduler error: returned from coro start function\n");
- exit(-1);
-}
-
-/*
-void Coro_Start(void)
-{
- CallbackBlock block = globalCallbackBlock;
- unsigned int hiArg = (unsigned int)(((long long)&block) >> 32);
- unsigned int loArg = (unsigned int)(((long long)&block) & 0xFFFFFFFF);
- Coro_StartWithArg(hiArg, loArg);
-}
-*/
-#else
-void Coro_StartWithArg(CallbackBlock *block)
-{
-#ifdef USE_FIBERS
- MEMORY_BASIC_INFORMATION meminfo;
- if (block->associatedCoro->fiber != GetCurrentFiber())
- abort();
- // Set the start of the stack for future comparaison. According to
- // http://msdn.microsoft.com/en-us/library/ms686774(VS.85).aspx,
- // some part of the stack is reserved for running an handler if
- // the fiber exhaust its stack, but we have no way of retrieving
- // this information (SetThreadStackGuarantee() is not supported
- // on WindowsXP), so we have to assume that it is the default
- // 64kB.
-
- // Look at the descriptors of the meminfo structure, which is
- // conveniently located on the stack we are interested into.
- VirtualQuery(&meminfo, &meminfo, sizeof meminfo);
- block->associatedCoro->stack =
- (char*)meminfo.AllocationBase + 64 * 1024;
-#endif
- (block->func)(block->context);
- printf("Scheduler error: returned from coro start function\n");
- exit(-1);
-}
-
-static CallbackBlock globalCallbackBlock;
-
-
-void Coro_Start(void)
-{
- CallbackBlock block = globalCallbackBlock;
- Coro_StartWithArg(&block);
-}
-
-#endif
-
-// --------------------------------------------------------------------
-
-void Coro_UnsupportedPlatformError(void);
-
-void Coro_UnsupportedPlatformError(void)
-{
- printf("Io Scheduler error: no Coro_setupJmpbuf entry for this platform\n.");
- exit(1);
-}
-
-
-void Coro_switchTo_(Coro *self, Coro *next)
-{
-#if defined(__SYMBIAN32__)
- ProcessUIEvent();
-#elif defined(USE_FIBERS)
- SwitchToFiber(next->fiber);
-#elif defined(USE_UCONTEXT)
- swapcontext(&self->env, &next->env);
-#elif defined(USE_SETJMP) || defined USE_GUESSED_SETJMP
- if (setjmp(self->env) == 0)
- {
- longjmp(next->env, 1);
- }
-#endif
-}
-
-// ---- setup ------------------------------------------
-#if defined USE_GUESSED_SETJMP
-// This isn't bulletproof, but seems to work Well Enough (TM)
-void Coro_setup(Coro *self, void *arg)
-{
- uintptr_t stackend = Coro_stackSize(self) + (uintptr_t)Coro_stack(self);
- uintptr_t start = (uintptr_t)Coro_Start;
- /* since ucontext seems to be broken on amd64 */
- globalCallbackBlock.context=((CallbackBlock*)arg)->context;
- globalCallbackBlock.func=((CallbackBlock*)arg)->func;
- setjmp(self->env);
-end:
- {
- uintptr_t i;
- uintptr_t * sav = (uintptr_t*)self->env;
- size_t sz = sizeof(self->env)/sizeof(sav[0]);
-
- // Try to guess PC index
- i = sz;
- while (i--)
- if (sav[i] == (uintptr_t)&&end)
- break;
- assert(i < sz);
- sav[i] = start;
-
- // Try to guess SP index
- i = sz;
- while (i--)
- if (64 > (- sav[i] + (uintptr_t)&i))
- break;
- assert(i < sz);
- sav[i] = stackend - sizeof(uintptr_t) - 128;
- }
-}
-
-#elif defined(USE_SETJMP) && defined(__x86_64__)
-
-void Coro_setup(Coro *self, void *arg)
-{
- uintptr_t stackend = Coro_stackSize(self) + (uintptr_t)Coro_stack(self);
- uintptr_t start = (uintptr_t)Coro_Start;
- /* since ucontext seems to be broken on amd64 */
- globalCallbackBlock.context=((CallbackBlock*)arg)->context;
- globalCallbackBlock.func=((CallbackBlock*)arg)->func;
-
- setjmp(self->env);
- /* This is probably not nice in that it deals directly with
- * something with __ in front of it.
- *
- * Anyhow, Coro.h makes the member env of a struct Coro a
- * jmp_buf. A jmp_buf, as defined in the amd64 setjmp.h
- * is an array of one struct that wraps the actual __jmp_buf type
- * which is the array of longs (on a 64 bit machine) that
- * the programmer below expected. This struct begins with
- * the __jmp_buf array of longs, so I think it was supposed
- * to work like he originally had it, but for some reason
- * it didn't. I don't know why.
- * - Bryce Schroeder, 16 December 2006
- *
- * Explaination of `magic' numbers: 6 is the stack pointer
- * (RSP, the 64 bit equivalent of ESP), 7 is the program counter.
- * This information came from this file on my Gentoo linux
- * amd64 computer:
- * /usr/include/gento-multilib/amd64/bits/setjmp.h
- * Which was ultimatly included from setjmp.h in /usr/include. */
-
-#if defined(__APPLE__) && defined(__x86_64__)
- *(uintptr_t*)(self->env+4) = stackend - 8;
- *(uintptr_t*)(self->env+14) = start;
-#elif defined(__APPLE__)
- *(uintptr_t*)(self->env+9) = stackend - 4;
- *(uintptr_t*)(self->env+12) = start;
-#elif defined(_MSC_VER)
- // Broken, use fibers
- *(uintptr_t*)(self->env+4) = stackend - 8;
- *(uintptr_t*)(self->env+5) = start;
-#else
- self->env[0].__jmpbuf[6] = ((unsigned long)(Coro_stack(self)));
- self->env[0].__jmpbuf[7] = ((long)Coro_Start);
-#endif
-}
-
-#elif defined(HAS_UCONTEXT_ON_PRE_SOLARIS_10)
-
-typedef void (*makecontext_func)(void);
-
-void Coro_setup(Coro *self, void *arg)
-{
- ucontext_t *ucp = (ucontext_t *) &self->env;
-
- getcontext(ucp);
-
- ucp->uc_stack.ss_sp = Coro_stack(self) + Coro_stackSize(self) - 8;
- ucp->uc_stack.ss_size = Coro_stackSize(self);
- ucp->uc_stack.ss_flags = 0;
- ucp->uc_link = NULL;
-
- makecontext(ucp, (makecontext_func)Coro_StartWithArg, 1, arg); }
-
-
-#elif defined(USE_UCONTEXT)
-
-typedef void (*makecontext_func)(void);
-
-void Coro_setup(Coro *self, void *arg)
-{
- ucontext_t *ucp = (ucontext_t *) &self->env;
-
- getcontext(ucp);
-
- ucp->uc_stack.ss_sp = Coro_stack(self);
- ucp->uc_stack.ss_size = Coro_stackSize(self);
-#if !defined(__APPLE__)
- ucp->uc_stack.ss_flags = 0;
- ucp->uc_link = NULL;
-#endif
-
-#if defined(__x86_64__)
- unsigned int hiArg = (unsigned int)((long long)arg >> 32);
- unsigned int loArg = (unsigned int)((long long)arg & 0xFFFFFFFF);
- makecontext(ucp, (makecontext_func)Coro_StartWithArg, 2, hiArg, loArg);
-#else
- makecontext(ucp, (makecontext_func)Coro_StartWithArg, 1, arg);
-#endif
-}
-
-#elif defined(USE_FIBERS)
-
-void Coro_setup(Coro *self, void *arg)
-{
- // If this coro was recycled and already has a fiber, delete it.
- // Don't delete the main fiber. We don't want to commit suicide.
-
- if (self->fiber && !self->isMain)
- {
- DeleteFiber(self->fiber);
- }
-
- self->fiber = CreateFiber(Coro_stackSize(self),
- (LPFIBER_START_ROUTINE)Coro_StartWithArg,
- (LPVOID)arg);
- if (!self->fiber) {
- DWORD err = GetLastError();
- exit(err);
- }
-}
-
-#elif defined(__CYGWIN__)
-
-#define buf (self->env)
-
-void Coro_setup(Coro *self, void *arg)
-{
- setjmp(buf);
- buf[7] = (long)(Coro_stack(self) + Coro_stackSize(self) - 16);
- buf[8] = (long)Coro_Start;
- globalCallbackBlock.context=((CallbackBlock*)arg)->context;
- globalCallbackBlock.func=((CallbackBlock*)arg)->func;
-}
-
-#elif defined(__SYMBIAN32__)
-
-void Coro_setup(Coro *self, void *arg)
-{
- /*
- setjmp/longjmp is flakey under Symbian.
- If the setjmp is done inside the call then a crash occurs.
- Inlining it here solves the problem
- */
-
- setjmp(self->env);
- self->env[0] = 0;
- self->env[1] = 0;
- self->env[2] = 0;
- self->env[3] = (unsigned long)(Coro_stack(self))
- + Coro_stackSize(self) - 64;
- self->env[9] = (long)Coro_Start;
- self->env[8] = self->env[3] + 32;
-}
-
-#elif defined(_BSD_PPC_SETJMP_H_)
-
-#define buf (self->env)
-#define setjmp _setjmp
-#define longjmp _longjmp
-
-void Coro_setup(Coro *self, void *arg)
-{
- size_t *sp = (size_t *)(((intptr_t)Coro_stack(self)
- + Coro_stackSize(self) - 64 + 15) & ~15);
-
- setjmp(buf);
-
- //printf("self = %p\n", self);
- //printf("sp = %p\n", sp);
- buf[0] = (long)sp;
- buf[21] = (long)Coro_Start;
- globalCallbackBlock.context=((CallbackBlock*)arg)->context;
- globalCallbackBlock.func=((CallbackBlock*)arg)->func;
- //sp[-4] = (size_t)self; // for G5 10.3
- //sp[-6] = (size_t)self; // for G4 10.4
-
- //printf("self = %p\n", (void *)self);
- //printf("sp = %p\n", sp);
-}
-
-/*
-void Coro_setup(Coro *self, void *arg)
-{
- size_t *sp = (size_t *)(((intptr_t)Coro_stack(self)
- + Coro_stackSize(self) - 64 + 15) & ~15);
-
- setjmp(buf);
-
- //printf("self = %p\n", self);
- //printf("sp = %p\n", sp);
- buf[0] = (long)sp;
- buf[21] = (long)Coro_Start;
- //sp[-4] = (size_t)self; // for G5 10.3
- //sp[-6] = (size_t)self; // for G4 10.4
-
- //printf("self = %p\n", (void *)self);
- //printf("sp = %p\n", sp);
-}
-*/
-
-#elif defined(__DragonFly__)
-
-#define buf (self->env)
-
-void Coro_setup(Coro *self, void *arg)
-{
- void *stack = Coro_stack(self);
- size_t stacksize = Coro_stackSize(self);
- void *func = (void *)Coro_Start;
-
- setjmp(buf);
-
- buf->_jb[2] = (long)(stack + stacksize);
- buf->_jb[0] = (long)func;
- return;
-}
-
-#elif defined(__arm__)
-// contributed by Peter van Hardenberg
-
-#define buf (self->env)
-
-void Coro_setup(Coro *self, void *arg)
-{
- setjmp(buf);
- buf[8] = (int)Coro_stack(self) + (int)Coro_stackSize(self) - 16;
- buf[9] = (int)Coro_Start;
-}
-
-
-// NLB ... guessing. Check data from here
-// http://state-threads.sourceforge.net/docs/notes.html
-// It appears 2 is the SP and probably 0 is the PC just like on DragonFly
-// /usr/src/lib/libc/arch/i386/gen/setjmp.S appears to confirm this...
-// but I'm segfaulting to an address of 0000, so obviously I'm a but wrong
-// somewhere...
-// Current problem looks like "func" is off by 143 bytes/whatever, and I'm
-// landing in the
-// wrong spot after the return! So my structure is right, but somehow I have
-// the wrong *func
-
-#elif defined(__OpenBSD__)
-
-#define buf (self->env)
-
-void Coro_setup(Coro *self, void *arg)
-{
- void *stack = Coro_stack(self);
- size_t stacksize = Coro_stackSize(self);
- void *func = (void *)Coro_Start;
-
- setjmp(buf);
-
- buf[2] = (long)(stack + stacksize);
- buf[0] = (long)Coro_Start;
- // it would seem this needs to have some value??
- globalCallbackBlock.context=((CallbackBlock*)arg)->context;
- globalCallbackBlock.func=((CallbackBlock*)arg)->func;
- return;
-}
-
-#else
-
-#error "Coro.c Error: Coro_setup() function needs to be defined for this platform."
-
-#endif
-
-
-// old code
-
-/*
- // APPLE coros are handled by PortableUContext now
-#elif defined(_BSD_PPC_SETJMP_H_)
-
-#define buf (self->env)
-#define setjmp _setjmp
-#define longjmp _longjmp
-
- void Coro_setup(Coro *self, void *arg)
- {
- size_t *sp = (size_t *)(((intptr_t)Coro_stack(self) + Coro_stackSize(self) - 64 + 15) & ~15);
-
- setjmp(buf);
-
- //printf("self = %p\n", self);
- //printf("sp = %p\n", sp);
- buf[0] = (int)sp;
- buf[21] = (int)Coro_Start;
- //sp[-4] = (size_t)self; // for G5 10.3
- //sp[-6] = (size_t)self; // for G4 10.4
-
- //printf("self = %p\n", (void *)self);
- //printf("sp = %p\n", sp);
- }
-
-#elif defined(_BSD_I386_SETJMP_H)
-
-#define buf (self->env)
-
- void Coro_setup(Coro *self, void *arg)
- {
- size_t *sp = (size_t *)((intptr_t)Coro_stack(self) + Coro_stackSize(self));
-
- setjmp(buf);
-
- buf[9] = (int)(sp); // esp
- buf[12] = (int)Coro_Start; // eip
- //buf[8] = 0; // ebp
- }
- */
-
-/* Solaris supports ucontext - so we don't need this stuff anymore
-
-void Coro_setup(Coro *self, void *arg)
-{
- // this bit goes before the setjmp call
- // Solaris 9 Sparc with GCC
-#if defined(__SVR4) && defined (__sun)
-#if defined(_JBLEN) && (_JBLEN == 12) && defined(__sparc)
-#if defined(_LP64) || defined(_I32LPx)
-#define JBTYPE long
- JBTYPE x;
-#else
-#define JBTYPE int
- JBTYPE x;
- asm("ta 3"); // flush register window
-#endif
-
-#define SUN_STACK_END_INDEX 1
-#define SUN_PROGRAM_COUNTER 2
-#define SUN_STACK_START_INDEX 3
-
- // Solaris 9 i386 with GCC
-#elif defined(_JBLEN) && (_JBLEN == 10) && defined(__i386)
-#if defined(_LP64) || defined(_I32LPx)
-#define JBTYPE long
- JBTYPE x;
-#else
-#define JBTYPE int
- JBTYPE x;
-#endif
-#define SUN_PROGRAM_COUNTER 5
-#define SUN_STACK_START_INDEX 3
-#define SUN_STACK_END_INDEX 4
-#endif
-#endif
- */
-
-/* Irix supports ucontext - so we don't need this stuff anymore
-
-#elif defined(sgi) && defined(_IRIX4_SIGJBLEN) // Irix/SGI
-
-void Coro_setup(Coro *self, void *arg)
-{
- setjmp(buf);
- buf[JB_SP] = (__uint64_t)((char *)stack + stacksize - 8);
- buf[JB_PC] = (__uint64_t)Coro_Start;
-}
-*/
-
-/* Linux supports ucontext - so we don't need this stuff anymore
-
-#elif defined(linux)
-// Various flavors of Linux.
-#if defined(JB_GPR1)
-// Linux/PPC
-buf->__jmpbuf[JB_GPR1] = ((int) stack + stacksize - 64 + 15) & ~15;
-buf->__jmpbuf[JB_LR] = (int) Coro_Start;
-return;
-
-#elif defined(JB_RBX)
-// Linux/Opteron
-buf->__jmpbuf[JB_RSP] = (long int )stack + stacksize;
-buf->__jmpbuf[JB_PC] = Coro_Start;
-return;
-
-#elif defined(JB_SP)
-
-// Linux/x86 with glibc2
-buf->__jmpbuf[JB_SP] = (int)stack + stacksize;
-buf->__jmpbuf[JB_PC] = (int)Coro_StartWithArg;
-// Push the argument on the stack (stack grows downwards)
-// note: stack is stacksize + 16 bytes long
-((int *)stack)[stacksize/sizeof(int) + 1] = (int)self;
-return;
-
-#elif defined(_I386_JMP_BUF_H)
-// x86-linux with libc5
-buf->__sp = (int)stack + stacksize;
-buf->__pc = Coro_Start;
-return;
-
-#elif defined(__JMP_BUF_SP)
-// arm-linux on the sharp zauras
-buf->__jmpbuf[__JMP_BUF_SP] = (int)stack + stacksize;
-buf->__jmpbuf[__JMP_BUF_SP+1] = (int)Coro_Start;
-return;
-
-#else
-
-*/
-
-
-/* Windows supports fibers - so we don't need this stuff anymore
-
-#elif defined(__MINGW32__)
-
-void Coro_setup(Coro *self, void *arg)
-{
- setjmp(buf);
- buf[4] = (int)((unsigned char *)stack + stacksize - 16); // esp
- buf[5] = (int)Coro_Start; // eip
-}
-
-#elif defined(_MSC_VER)
-
-void Coro_setup(Coro *self, void *arg)
-{
- setjmp(buf);
- // win32 visual c
- // should this be the same as __MINGW32__?
- buf[4] = (int)((unsigned char *)stack + stacksize - 16); // esp
- buf[5] = (int)Coro_Start; // eip
-}
-*/
-
-
-/* FreeBSD supports ucontext - so we don't need this stuff anymore
-
-#elif defined(__FreeBSD__)
-// FreeBSD.
-#if defined(_JBLEN) && (_JBLEN == 81)
-// FreeBSD/Alpha
-buf->_jb[2] = (long)Coro_Start; // sc_pc
-buf->_jb[26+4] = (long)Coro_Start; // sc_regs[R_RA]
-buf->_jb[27+4] = (long)Coro_Start; // sc_regs[R_T12]
-buf->_jb[30+4] = (long)(stack + stacksize); // sc_regs[R_SP]
-return;
-
-#elif defined(_JBLEN)
-// FreeBSD on IA32
-buf->_jb[2] = (long)(stack + stacksize);
-buf->_jb[0] = (long)Coro_Start;
-return;
-
-#else
-Coro_UnsupportedPlatformError();
-#endif
-*/
-
-/* NetBSD supports ucontext - so we don't need this stuff anymore
-
-#elif defined(__NetBSD__)
-
-void Coro_setup(Coro *self, void *arg)
-{
- setjmp(buf);
-#if defined(_JB_ATTRIBUTES)
- // NetBSD i386
- buf[2] = (long)(stack + stacksize);
- buf[0] = (long)Coro_Start;
-#else
- Coro_UnsupportedPlatformError();
-#endif
-}
-*/
-
-/* Sun supports ucontext - so we don't need this stuff anymore
-
-// Solaris supports ucontext - so we don't need this stuff anymore
-
-void Coro_setup(Coro *self, void *arg)
-{
- // this bit goes before the setjmp call
- // Solaris 9 Sparc with GCC
-#if defined(__SVR4) && defined (__sun)
-#if defined(_JBLEN) && (_JBLEN == 12) && defined(__sparc)
-#if defined(_LP64) || defined(_I32LPx)
-#define JBTYPE long
- JBTYPE x;
-#else
-#define JBTYPE int
- JBTYPE x;
- asm("ta 3"); // flush register window
-#endif
-
-#define SUN_STACK_END_INDEX 1
-#define SUN_PROGRAM_COUNTER 2
-#define SUN_STACK_START_INDEX 3
-
- // Solaris 9 i386 with GCC
-#elif defined(_JBLEN) && (_JBLEN == 10) && defined(__i386)
-#if defined(_LP64) || defined(_I32LPx)
-#define JBTYPE long
- JBTYPE x;
-#else
-#define JBTYPE int
- JBTYPE x;
-#endif
-#define SUN_PROGRAM_COUNTER 5
-#define SUN_STACK_START_INDEX 3
-#define SUN_STACK_END_INDEX 4
-#endif
-#endif
-
-
-#elif defined(__SVR4) && defined(__sun)
- // Solaris
-#if defined(SUN_PROGRAM_COUNTER)
- // SunOS 9
- buf[SUN_PROGRAM_COUNTER] = (JBTYPE)Coro_Start;
-
- x = (JBTYPE)stack;
- while ((x % 8) != 0) x --; // align on an even boundary
- buf[SUN_STACK_START_INDEX] = (JBTYPE)x;
- x = (JBTYPE)((JBTYPE)stack-stacksize / 2 + 15);
- while ((x % 8) != 0) x ++; // align on an even boundary
- buf[SUN_STACK_END_INDEX] = (JBTYPE)x;
-
- */
-
-
-
View
131 ActorKit/coroutine/source/Coro.h
@@ -1,131 +0,0 @@
-#ifndef CORO_DEFINED
-#define CORO_DEFINED 1
-
-#if defined(__linux__)
- #define HAS_UCONTEXT 1
-#endif
-
-#if defined(__APPLE__) && defined(__i386__)
- #define USE_UCONTEXT 1
-#endif
-
-#if defined(__FreeBSD__)
- #define HAS_UCONTEXT 1
-#endif
-
-#if defined(__OpenBSD__)
-#undef HAS_UCONTEXT
-#undef USE_UCONTEXT
-#undef USE_FIBERS
-#endif
-
-#if defined(__amd64__) && !defined(__x86_64__)
- #define __x86_64__ 1
-#endif
-
-#include "Common.h"
-//#include "PortableUContext.h"
-#include "taskimpl.h"
-
-#if defined(__SYMBIAN32__)
- #define CORO_STACK_SIZE 8192
- #define CORO_STACK_SIZE_MIN 1024
-#else
- //#define CORO_DEFAULT_STACK_SIZE (65536/2)
- //#define CORO_DEFAULT_STACK_SIZE (65536*4)
-
- //128k needed on PPC due to parser
- #define CORO_DEFAULT_STACK_SIZE (128*1024)
- //#define CORO_DEFAULT_STACK_SIZE (256*1024)
- #define CORO_STACK_SIZE_MIN 8192
-#endif
-
-#if defined(WIN32)
-#if defined(BUILDING_CORO_DLL) || defined(BUILDING_IOVMALL_DLL)
-#define CORO_API __declspec(dllexport)
-#else
-#define CORO_API __declspec(dllimport)
-#endif
-
-#else
-#define CORO_API
-#endif
-
-
-// Pick which coro implementation to use
-// The make file can set -DUSE_FIBERS, -DUSE_UCONTEXT or -DUSE_SETJMP to force this choice.
-#if !defined(USE_FIBERS) && !defined(USE_UCONTEXT) && !defined(USE_SETJMP)
-
-#if defined(WIN32) && defined(HAS_FIBERS)
-# define USE_FIBERS
-#elif defined(HAS_UCONTEXT)
-//#elif defined(HAS_UCONTEXT) && !defined(__x86_64__)
-# if !defined(USE_UCONTEXT)
-# define USE_UCONTEXT
-# endif
-#else
-# define USE_SETJMP
-#endif
-
-#endif
-
-#if defined(USE_FIBERS)
- #define CORO_IMPLEMENTATION "fibers"
-#elif defined(USE_UCONTEXT)
- #include <sys/ucontext.h>
- #define CORO_IMPLEMENTATION "ucontext"
-#elif defined(USE_SETJMP)
- #include <setjmp.h>
- #define CORO_IMPLEMENTATION "setjmp"
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct Coro Coro;
-
-struct Coro
-{
- size_t requestedStackSize;
- size_t allocatedStackSize;
- void *stack;
-
-#ifdef USE_VALGRIND
- unsigned int valgrindStackId;
-#endif
-
-#if defined(USE_FIBERS)
- void *fiber;
-#elif defined(USE_UCONTEXT)
- ucontext_t env;
-#elif defined(USE_SETJMP)
- jmp_buf env;
-#endif
-
- unsigned char isMain;
-};
-
-CORO_API Coro *Coro_new(void);
-CORO_API void Coro_free(Coro *self);
-
-// stack
-
-CORO_API void *Coro_stack(Coro *self);
-CORO_API size_t Coro_stackSize(Coro *self);
-CORO_API void Coro_setStackSize_(Coro *self, size_t sizeInBytes);
-CORO_API size_t Coro_bytesLeftOnStack(Coro *self);
-CORO_API int Coro_stackSpaceAlmostGone(Coro *self);