sync.m
Hi! I am doing something like: @synchronized(self) { if ( MY_SINGLETON_VARIABLE == nil ) { [[ self alloc ] init ]; } } Looks like in sync.m:initLockObject my objects ISA pointer gets changed. So, at the time "alloc" is called the message lookup simply fails. TOM ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Thanks for the report, I'll take a look. I don't think I'd tested @synchronized() with a class as an argument - it seems like a very strange thing to do when there are safe ways of achieving the same result with much less overhead. By the way, creating singletons like this is entirely wrong. The correct way of creating a singleton is to do it in +initialize, like this: + (void)initialize { if ([MyClass class] == self) { MY_SINGLETON_VARIABLE = [[self alloc] init]; } } Then the runtime will ensure: 1) This method runs to completion before any other messages are sent to the class. 2) This method runs exactly once. Creating singletons any other way introduces potential race conditions. David On 27 Feb 2010, at 15:54, ici...@mail.cg.tuwien.ac.at wrote: > Hi! > > I am doing something like: > > @synchronized(self) > { > if ( MY_SINGLETON_VARIABLE == nil ) > { > [[ self alloc ] init ]; > } > } > > Looks like in sync.m:initLockObject my objects ISA pointer gets changed. So, > at the time "alloc" is called the message lookup simply fails. > > TOM > > > > ___ > Gnustep-dev mailing list > Gnustep-dev@gnu.org > http://lists.gnu.org/mailman/listinfo/gnustep-dev -- Send from my Jacquard Loom ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 27 Feb 2010, at 17:15, David Chisnall wrote: > Thanks for the report, I'll take a look. I don't think I'd tested > @synchronized() with a class as an argument - it seems like a very strange > thing to do when there are safe ways of achieving the same result with much > less overhead. Good point, but one which is probably not obvious to most people. Certainly a new ObjC programmer is likely to think that anything which is part of the 'standard' must be good. You are probably in a better position than anyone else to be aware of precisely what parts of ObjectiveC-2 are most efficient or inefficient, and how they compare to the traditional ways of doing things. Have you considered producing a paper describing those differences? If we had them quantified we would have a really good guide for people to know when to use new features and when to avoid them (and when it really doesn't matter). Just a suggestion ... ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
I've now fixed this case in libobjc2. Unfortunately, someone decided to 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor to diffs against the original version in Étoilé svn), so whoever did that gets to volunteer to back-port the changes. On 27 Feb 2010, at 17:40, Richard Frith-Macdonald wrote: > You are probably in a better position than anyone else to be aware of > precisely what parts of ObjectiveC-2 are most efficient or inefficient, and > how they compare to the traditional ways of doing things. Have you > considered producing a paper describing those differences? If we had them > quantified we would have a really good guide for people to know when to use > new features and when to avoid them (and when it really doesn't matter). Well, I did write a book that describes them... @synchronized is basically impossible to implement efficiently. It's a stupid feature added to make life easier for Java programmers who are too lazy to think when they learn a new language. There are basically three ways you can do it: 1) Allocate a pthread_mutex_t with every object Pros: Fast, simple Cons: Wastes at least one word of memory for every object, including the 99.9% that are never used as arguments to @synchronized(). 2) Have a shadow data structure mapping objects to locks. Pros: Doesn't waste much memory. Cons: Extra locking on the shadow structure needed, extra code needed to remove locks when they are no longer needed, overhead performing the lookup. 3) Add a hidden class between the object and its real class which stores the lock. Pros: Relatively simple and non-invasive. Cons: Needs an extra class structure for every locked object. libobjc2 / ObjectiveC2.framework use option 3. We use objc_allocateClassPair(), which doesn't work for creating just a new metaclass (although we fail slightly more gracefully than Apple's version, which just returns a pointer to a random address). I've now added a special case to libobjc2 and a non-portable runtime function for allocating just a new metaclass. In all cases, this pattern will be much faster: [nslock lock]; @try { // do stuff } @finally { [nslock unlock]; } It's also worth remembering that @synchronized uses a recursive mutex, which, on most platforms, is slower than the non-recursive form used by NSLock. Unless you actually need the recursive behaviour, don't use it. @synchronized is a horrendous language feature, because it looks just like the Java keyword, but has almost the exact opposite performance characteristics. David -- Sent from my Difference Engine ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Hi! looks like it is not fixed :( Richard ported the code over to the ObjectiveC2 framework immediately, but it still does not work. Now I get "Uncaught exception NSInvalidArgumentException, reason: (null)(class) does not recognize instance". As "instance" is the class method which creates the singleton now something else seems to go wrong. Thanks TOM Zitat von David Chisnall : I've now fixed this case in libobjc2. Unfortunately, someone decided to 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor to diffs against the original version in Étoilé svn), so whoever did that gets to volunteer to back-port the changes. On 27 Feb 2010, at 17:40, Richard Frith-Macdonald wrote: You are probably in a better position than anyone else to be aware of precisely what parts of ObjectiveC-2 are most efficient or inefficient, and how they compare to the traditional ways of doing things. Have you considered producing a paper describing those differences? If we had them quantified we would have a really good guide for people to know when to use new features and when to avoid them (and when it really doesn't matter). Well, I did write a book that describes them... @synchronized is basically impossible to implement efficiently. It's a stupid feature added to make life easier for Java programmers who are too lazy to think when they learn a new language. There are basically three ways you can do it: 1) Allocate a pthread_mutex_t with every object Pros: Fast, simple Cons: Wastes at least one word of memory for every object, including the 99.9% that are never used as arguments to @synchronized(). 2) Have a shadow data structure mapping objects to locks. Pros: Doesn't waste much memory. Cons: Extra locking on the shadow structure needed, extra code needed to remove locks when they are no longer needed, overhead performing the lookup. 3) Add a hidden class between the object and its real class which stores the lock. Pros: Relatively simple and non-invasive. Cons: Needs an extra class structure for every locked object. libobjc2 / ObjectiveC2.framework use option 3. We use objc_allocateClassPair(), which doesn't work for creating just a new metaclass (although we fail slightly more gracefully than Apple's version, which just returns a pointer to a random address). I've now added a special case to libobjc2 and a non-portable runtime function for allocating just a new metaclass. In all cases, this pattern will be much faster: [nslock lock]; @try { // do stuff } @finally { [nslock unlock]; } It's also worth remembering that @synchronized uses a recursive mutex, which, on most platforms, is slower than the non-recursive form used by NSLock. Unless you actually need the recursive behaviour, don't use it. @synchronized is a horrendous language feature, because it looks just like the Java keyword, but has almost the exact opposite performance characteristics. David -- Sent from my Difference Engine ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Hi! I put together a testcase, this used to work before the switch ObjectiveC2 framework. Lin 62 is the one causing the crash. Thanks TOM Zitat von ici...@mail.cg.tuwien.ac.at: Hi! looks like it is not fixed :( Richard ported the code over to the ObjectiveC2 framework immediately, but it still does not work. Now I get "Uncaught exception NSInvalidArgumentException, reason: (null)(class) does not recognize instance". As "instance" is the class method which creates the singleton now something else seems to go wrong. Thanks TOM Zitat von David Chisnall : I've now fixed this case in libobjc2. Unfortunately, someone decided to 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor to diffs against the original version in Étoilé svn), so whoever did that gets to volunteer to back-port the changes. On 27 Feb 2010, at 17:40, Richard Frith-Macdonald wrote: You are probably in a better position than anyone else to be aware of precisely what parts of ObjectiveC-2 are most efficient or inefficient, and how they compare to the traditional ways of doing things. Have you considered producing a paper describing those differences? If we had them quantified we would have a really good guide for people to know when to use new features and when to avoid them (and when it really doesn't matter). Well, I did write a book that describes them... @synchronized is basically impossible to implement efficiently. It's a stupid feature added to make life easier for Java programmers who are too lazy to think when they learn a new language. There are basically three ways you can do it: 1) Allocate a pthread_mutex_t with every object Pros: Fast, simple Cons: Wastes at least one word of memory for every object, including the 99.9% that are never used as arguments to @synchronized(). 2) Have a shadow data structure mapping objects to locks. Pros: Doesn't waste much memory. Cons: Extra locking on the shadow structure needed, extra code needed to remove locks when they are no longer needed, overhead performing the lookup. 3) Add a hidden class between the object and its real class which stores the lock. Pros: Relatively simple and non-invasive. Cons: Needs an extra class structure for every locked object. libobjc2 / ObjectiveC2.framework use option 3. We use objc_allocateClassPair(), which doesn't work for creating just a new metaclass (although we fail slightly more gracefully than Apple's version, which just returns a pointer to a random address). I've now added a special case to libobjc2 and a non-portable runtime function for allocating just a new metaclass. In all cases, this pattern will be much faster: [nslock lock]; @try { // do stuff } @finally { [nslock unlock]; } It's also worth remembering that @synchronized uses a recursive mutex, which, on most platforms, is slower than the non-recursive form used by NSLock. Unless you actually need the recursive behaviour, don't use it. @synchronized is a horrendous language feature, because it looks just like the Java keyword, but has almost the exact opposite performance characteristics. David -- Sent from my Difference Engine ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev synchronized.tar.gz Description: GNU Zip compressed data ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Thanks - I forgot to set a couple of flags in the new metaclass, which was confusing things later. This is now working with libobjc2, so thanks for the report. A few observations about the code in your sample: Although this works, it is a really, really bad way of creating a singleton. I strongly suggest that you create it in +initialize instead. If you really must use @synchronized(), you should put a test outside, like this: if (nil == sharedInstance) { @synchronized(self) { if (nil == NP_ENGINE_CORE) { NP_ENGINE_CORE = [self new]; } } return NP_ENGINE_CORE; } At least this way you will only have to do the (very expensive) objc_sync_enter/exit thing once, or maybe twice. If you implement it with +initialize, however, you don't have to do it at all: + (void)initialize { if ([NPEngineCore class] == self) { NP_ENGINE_CORE = [self new]; } } + (id)sharedInstance { return NP_ENGINE_CORE; } The runtime will handle the locking for you, calling the +initialize method precisely once, the first time the class is sent any message. You can then guarantee that the singleton instance already exists by the time the +sharedInstance method is called. You could also then eliminate the need for @sycnhronized() in +allocWithZone: because if NP_ENGINE_CORE is still nil then you are being called from the +initialize method. In general, when a solution to a problem is both more developer effort and slower, it's not the correct one... Your +allocWithZone: method should really check that it's not a subclass, before returning the singleton. In -initWithName:, you should check that self != nil after [super init]. See the SUPERINIT macro from EtoileFoundation. In a singleton, it's a good idea to override -dealloc to not call [super dealloc]. This will cause a warning with GCC, which you can hide like this: - (void)dealloc { if (0) { [super dealloc]; } } You should really use -copy, not -retain when assigning newName to name. If newName is an NSString, this will be equivalent. If it's an NSMutableString then this will create an immutable copy for you. In the @interface, you don't need to declare methods that are declared in the superclass's @interface. By the way, where did you get the spaces-inside-square-brackets style from? I don't think I've ever seen Objective-C written like that. David On 27 Feb 2010, at 22:47, ici...@mail.cg.tuwien.ac.at wrote: > Hi! > > I put together a testcase, this used to work before the switch > ObjectiveC2 framework. Lin 62 is the one causing the crash. > > Thanks > TOM > > Zitat von ici...@mail.cg.tuwien.ac.at: > >> Hi! >> >> looks like it is not fixed :( Richard ported the code over to the >> ObjectiveC2 framework immediately, but it still does not work. Now I >> get "Uncaught exception NSInvalidArgumentException, reason: >> (null)(class) does not recognize instance". As "instance" is the >> class method which creates the singleton now something else seems to >> go wrong. >> >> Thanks >> TOM >> >> Zitat von David Chisnall : >> >>> I've now fixed this case in libobjc2. Unfortunately, someone >>> decided to 'helpfully' reindent the version of ObjectiveC2.framework >>> in GNUstep, which means that diffs from libobjc2 no longer cleanly >>> apply in ObjectiveC2 (nor to diffs against the original version in >>> Étoilé svn), so whoever did that gets to volunteer to back-port the >>> changes. >>> >>> On 27 Feb 2010, at 17:40, Richard Frith-Macdonald wrote: >>> You are probably in a better position than anyone else to be aware of precisely what parts of ObjectiveC-2 are most efficient or inefficient, and how they compare to the traditional ways of doing things. Have you considered producing a paper describing those differences? If we had them quantified we would have a really good guide for people to know when to use new features and when to avoid them (and when it really doesn't matter). >>> >>> >>> Well, I did write a book that describes them... >>> >>> @synchronized is basically impossible to implement efficiently. >>> It's a stupid feature added to make life easier for Java programmers >>> who are too lazy to think when they learn a new language. There are >>> basically three ways you can do it: >>> >>> 1) Allocate a pthread_mutex_t with every object >>> >>> Pros: Fast, simple >>> Cons: Wastes at least one word of memory for every object, including >>> the 99.9% that are never used as arguments to @synchronized(). >>> >>> 2) Have a shadow data structure mapping objects to locks. >>> >>> Pros: Doesn't waste much memory. >>> Cons: Extra locking on the shadow structure needed, extra code >>> needed to remove locks when they are no longer needed, overhead >>> performing the lookup. >>> >>> 3) Add a hidden class b
Re: sync.m
Although this works, it is a really, really bad way of creating a singleton. I copied it from the apple developer pages... I strongly suggest that you create it in +initialize instead. If you really must use @synchronized(), you should put a test outside, like this: if (nil == sharedInstance) { @synchronized(self) { if (nil == NP_ENGINE_CORE) { NP_ENGINE_CORE = [self new]; } } return NP_ENGINE_CORE; } At least this way you will only have to do the (very expensive) objc_sync_enter/exit thing once, or maybe twice. If you implement it with +initialize, however, you don't have to do it at all: + (void)initialize { if ([NPEngineCore class] == self) { NP_ENGINE_CORE = [self new]; } } + (id)sharedInstance { return NP_ENGINE_CORE; } The runtime will handle the locking for you, calling the +initialize method precisely once, the first time the class is sent any message. You can then guarantee that the singleton instance already exists by the time the +sharedInstance method is called. You could also then eliminate the need for @sycnhronized() in +allocWithZone: because if NP_ENGINE_CORE is still nil then you are being called from the +initialize method. I thought +initialize would be called on program startup for every class. I want to be able to create my singleton on demand since it has a rather large memory footprint. If that works with the method you propose I'm fine with it. Your +allocWithZone: method should really check that it's not a subclass, before returning the singleton. I don't want this class to be subclassed. In -initWithName:, you should check that self != nil after [super init]. See the SUPERINIT macro from EtoileFoundation. In a singleton, it's a good idea to override -dealloc to not call [super dealloc]. This will cause a warning with GCC, which you can hide like this: - (void)dealloc { if (0) { [super dealloc]; } } How would you deallocate your singleton then? By the way, where did you get the spaces-inside-square-brackets style from? I don't think I've ever seen Objective-C written like that. I didn't get it anywhere, that's my own :) Thanks TOM David On 27 Feb 2010, at 22:47, ici...@mail.cg.tuwien.ac.at wrote: Hi! I put together a testcase, this used to work before the switch ObjectiveC2 framework. Lin 62 is the one causing the crash. Thanks TOM Zitat von ici...@mail.cg.tuwien.ac.at: Hi! looks like it is not fixed :( Richard ported the code over to the ObjectiveC2 framework immediately, but it still does not work. Now I get "Uncaught exception NSInvalidArgumentException, reason: (null)(class) does not recognize instance". As "instance" is the class method which creates the singleton now something else seems to go wrong. Thanks TOM Zitat von David Chisnall : I've now fixed this case in libobjc2. Unfortunately, someone decided to 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor to diffs against the original version in Étoilé svn), so whoever did that gets to volunteer to back-port the changes. On 27 Feb 2010, at 17:40, Richard Frith-Macdonald wrote: You are probably in a better position than anyone else to be aware of precisely what parts of ObjectiveC-2 are most efficient or inefficient, and how they compare to the traditional ways of doing things. Have you considered producing a paper describing those differences? If we had them quantified we would have a really good guide for people to know when to use new features and when to avoid them (and when it really doesn't matter). Well, I did write a book that describes them... @synchronized is basically impossible to implement efficiently. It's a stupid feature added to make life easier for Java programmers who are too lazy to think when they learn a new language. There are basically three ways you can do it: 1) Allocate a pthread_mutex_t with every object Pros: Fast, simple Cons: Wastes at least one word of memory for every object, including the 99.9% that are never used as arguments to @synchronized(). 2) Have a shadow data structure mapping objects to locks. Pros: Doesn't waste much memory. Cons: Extra locking on the shadow structure needed, extra code needed to remove locks when they are no longer needed, overhead performing the lookup. 3) Add a hidden class between the object and its real class which stores the lock. Pros: Relatively simple and non-invasive. Cons: Needs an extra class structure for every locked object. libobjc2 / ObjectiveC2.framework use option 3. We use objc_allocateClassPair(), which doesn't work for creating just a new metaclass (although we fail slightly more gracefully than Apple's version, which just returns a pointer to a random address). I've now added a s
Re: sync.m
On 28 Feb 2010, at 08:42, ici...@mail.cg.tuwien.ac.at wrote: > >> Although this works, it is a really, really bad way of creating a singleton. > > I copied it from the apple developer pages... :-) > I thought +initialize would be called on program startup for every > class. I guess you are confusing +initialize with +load The +load method is called when your code is loaded into the program (usually on program startup unless your code is in a dynamically loaded bundle) The +initialize method is called the first time anything tries to *use* the class. > I want to be able to create my singleton on demand since it has > a rather large memory footprint. If that works with the method you > propose I'm fine with it. +initialize is perfect for that. > >> Your +allocWithZone: method should really check that it's not a >> subclass, before returning the singleton. > > I don't want this class to be subclassed. All the more reason why you should check. eg. + (id) allocWithZone: (NSZone*)z { if (self != [MyClass class]) { []NSException raise: NSInvalidArgumentException format: @"Illegal attempt to subclass MyClass as %@", self]; } if (sharedInstance == nil) { sharedInstance = [super allocWithZone: z]; } } >> In -initWithName:, you should check that self != nil after [super >> init]. See the SUPERINIT macro from EtoileFoundation. >> >> In a singleton, it's a good idea to override -dealloc to not call >> [super dealloc]. This will cause a warning with GCC, which you can >> hide like this: >> >> - (void)dealloc >> { >> if (0) >> { >> [super dealloc]; >> } >> } > > How would you deallocate your singleton then? Typically you don't deallocate singletons ... the idea is that they are created on demand and then are available for the rest of the program. If you *want* to manually destroy the singleton before the program ends, you can just add an extra class method to set sharedInstance to nil and release the object, then -dealloc could do this: - (void) dealloc { if (self != sharedInstance) { [super dealloc]; } } If you want multiple instances of the class, but never more than one at a time, then you wouldn't create them in +initialize (and this wouldn't really be what is meant by 'singleton'). In that case you would use a lock to protect critical bits of code, have +allocWithZone: return the existing instance (if there is one), and have -dealloc reset the sharedInstance variable to nil. ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 27 Feb 2010, at 18:39, David Chisnall wrote: > I've now fixed this case in libobjc2. Unfortunately, someone decided to > 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which > means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor to > diffs against the original version in Étoilé svn), so whoever did that gets > to volunteer to back-port the changes. Guess we should think about getting libobjc2 to conform to the coding standards soon. At least that's easier because it's largely C code rather than ObjC, and the 'indent' program will largely do it for us. ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Hi! After porting David's fixes from libobjc2 to the Objective2 framework @synchronized(class) works fine. Thank you all for your quick responses. TOM Zitat von Richard Frith-Macdonald : On 28 Feb 2010, at 08:42, ici...@mail.cg.tuwien.ac.at wrote: Although this works, it is a really, really bad way of creating a singleton. I copied it from the apple developer pages... :-) I thought +initialize would be called on program startup for every class. I guess you are confusing +initialize with +load The +load method is called when your code is loaded into the program (usually on program startup unless your code is in a dynamically loaded bundle) The +initialize method is called the first time anything tries to *use* the class. I want to be able to create my singleton on demand since it has a rather large memory footprint. If that works with the method you propose I'm fine with it. +initialize is perfect for that. Your +allocWithZone: method should really check that it's not a subclass, before returning the singleton. I don't want this class to be subclassed. All the more reason why you should check. eg. + (id) allocWithZone: (NSZone*)z { if (self != [MyClass class]) { []NSException raise: NSInvalidArgumentException format: @"Illegal attempt to subclass MyClass as %@", self]; } if (sharedInstance == nil) { sharedInstance = [super allocWithZone: z]; } } In -initWithName:, you should check that self != nil after [super init]. See the SUPERINIT macro from EtoileFoundation. In a singleton, it's a good idea to override -dealloc to not call [super dealloc]. This will cause a warning with GCC, which you can hide like this: - (void)dealloc { if (0) { [super dealloc]; } } How would you deallocate your singleton then? Typically you don't deallocate singletons ... the idea is that they are created on demand and then are available for the rest of the program. If you *want* to manually destroy the singleton before the program ends, you can just add an extra class method to set sharedInstance to nil and release the object, then -dealloc could do this: - (void) dealloc { if (self != sharedInstance) { [super dealloc]; } } If you want multiple instances of the class, but never more than one at a time, then you wouldn't create them in +initialize (and this wouldn't really be what is meant by 'singleton'). In that case you would use a lock to protect critical bits of code, have +allocWithZone: return the existing instance (if there is one), and have -dealloc reset the sharedInstance variable to nil. ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 28 Feb 2010, at 08:42, ici...@mail.cg.tuwien.ac.at wrote: >> Although this works, it is a really, really bad way of creating a singleton. > > I copied it from the apple developer pages... This is rarely a good idea, unfortunately. Apple's API documentation is very good, but their example code doesn't seem to have been written by programmers so it often does things in ways that are more appropriate to thedailywtf.com than developer.apple.com. > I thought +initialize would be called on program startup for every > class. I want to be able to create my singleton on demand since it has > a rather large memory footprint. If that works with the method you > propose I'm fine with it. There are two methods on a class that will be called by the runtime; +load and +initialize. The +load method is called as soon as the class is loaded. At this point, you can guarantee that the class and its superclasses are loaded, but you can't guarantee anything else about the state of the system. Generally speaking, any code using +load is wrong. I think I've used it twice, and both times it's been for something quite ugly. The +initialize method is much safer. It is called, in a thread-safe way, by the runtime when the first message is sent to the class. The first message sent to a class is usually something like +alloc, +new, or +sharedInstance. Creating the singleton in +initialize will create it in the right place. I was going to suggest that you look in Erik Buck's Cocoa Design Patterns, but it turns out that he also does it wrong - his non-thread-safe solution is more complex and slower than the thread-safe one, which is a shame; I'd have expected better from an old NeXT programmer. >> Your +allocWithZone: method should really check that it's not a >> subclass, before returning the singleton. > > I don't want this class to be subclassed. As Richard said, the best solution in this case is to throw an exception if the +allocWithZone: method is called on a subclass. This will prevent any subclasses from working. > How would you deallocate your singleton then? That's a good question. The answer in your current code is 'prematurely'. You are not retaining your singleton when it is returned, so either calling code will treat it like a singleton and never -release it, or it will -release it causing it to be destroyed and your global to be a dangling pointer. Erik suggests implementing a +attemptDealloc method that calls -release if -retainCount returns 1, but that's a messy and silly idea. If you want to be able to deallocate and recreate the singleton, be aware that you need to set the static pointer to nil. You also need to rewrite your +sharedInstance method like this (where instanceLock is an NSLock created in +initialize and sharedInstance is the instance pointer, both are file statics): + (id)sharedInstance { id obj; [instanceLock lock]; obj = sharedInstance; if (nil == obj) { obj = sharedInstance = [self new]; } obj = [obj retain] [instanceLock unlock]; return [obj autorelease]; } Your dealloc method will then look like this: - (void)dealloc { [instanceLock lock]; if ([self retainCount] == 0) { sharedInstance = nil; // do cleanup [super dealloc]; } [instanceLock unlock]; } It's important that you check the retain count before freeing the singleton, because otherwise you might have one thread call -sharedInstance while another calls -release. The +sharedInstance method will acquire the lock, blocking the -dealloc method in the other thread. When the -dealloc method is entered, you have to check that you really should proceed with the deallocation. Don't actually destroy the object unless no other thread has gained a reference to it. In general, as Richard says, you don't deallocate singletons. They are expected to exist for the lifetime of the program. The lazy-initialization trick just means that they don't really exist until observed; you can still reason about them as if they did exist from the program start (unless creation of them has side effects). >> By the way, where did you get the spaces-inside-square-brackets style >> from? I don't think I've ever seen Objective-C written like that. > > I didn't get it anywhere, that's my own :) Interesting. What's the rationale for it? It looks a bit more Smalltalk-like. I can imagine it working quite nicely in an editor that does rainbow brackets. David -- Sent from my STANTEC-ZEBRA ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Just one thing here... if conforming to the coding standards is going to be a point of contention, then I don't think we need to be very strict on them, at least not until after the code is completed and stabilized. GC On Sun, Feb 28, 2010 at 4:36 AM, Richard Frith-Macdonald wrote: > > On 27 Feb 2010, at 18:39, David Chisnall wrote: > >> I've now fixed this case in libobjc2. Unfortunately, someone decided to >> 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which >> means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor >> to diffs against the original version in Étoilé svn), so whoever did that >> gets to volunteer to back-port the changes. > > Guess we should think about getting libobjc2 to conform to the coding > standards soon. At least that's easier because it's largely C code rather > than ObjC, and the 'indent' program will largely do it for us. > > ___ > Discuss-gnustep mailing list > discuss-gnus...@gnu.org > http://lists.gnu.org/mailman/listinfo/discuss-gnustep > -- Gregory Casamento - GNUstep Lead/Principal Consultant, OLC, Inc. yahoo/skype: greg_casamento, aol: gjcasa (240)274-9630 (Cell) ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 28 Feb 2010, at 15:06, Gregory Casamento wrote: > Just one thing here... if conforming to the coding standards is going > to be a point of contention, then I don't think we need to be very > strict on them, at least not until after the code is completed and > stabilized. > > GC > > On Sun, Feb 28, 2010 at 4:36 AM, Richard Frith-Macdonald > wrote: >> >> On 27 Feb 2010, at 18:39, David Chisnall wrote: >> >>> I've now fixed this case in libobjc2. Unfortunately, someone decided to >>> 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which >>> means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor >>> to diffs against the original version in Étoilé svn), so whoever did that >>> gets to volunteer to back-port the changes. >> >> Guess we should think about getting libobjc2 to conform to the coding >> standards soon. At least that's easier because it's largely C code rather >> than ObjC, and the 'indent' program will largely do it for us. Well, that's why I didn't mention it until now (hopefully the code is getting stable ... it mostly seems to work). It makes me wonder though, if it would be worth the effort of making the indent program work for objective-c (I've always liked the idea of just automatically converting things to a common style with indent when a file is committed but people being able to regenerate their preferred style with indent on checkout ... it really should be possible). Actually, David's original comment is a bit wide of the mark anyway ... changes to the ObjectiveC2 code are rather more than just reindentation as it needed a bug fix or two and quite a few changes to fix c99isms which prevented it building on older systems (and the whole point of a compatibility library is to allow older systems, specifically older versions of the runtime, to work without having to have masses of #ifdef's in the code). If we want to keep ObjectiveC2 and libobc2 sufficiently in sync to allow patches from one to be applied to the other, we will need to restructure quite a bit of the libobjc2 code to avoid c99 features where possible, and David put a comment to Riccardo in libobjc2 specifically asking him not to do that (since the new library will only work on more modern systems), so unless David wants to reconsider, such synchronisation is impossible anyway :-( ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
I think one thing we seriously need to examine is how critical support for compilers which do not support C99 really is. Do any of the embedded platforms require gcc 2.95.x? GC On Sun, Feb 28, 2010 at 11:44 AM, Richard Frith-Macdonald wrote: > > On 28 Feb 2010, at 15:06, Gregory Casamento wrote: > >> Just one thing here... if conforming to the coding standards is going >> to be a point of contention, then I don't think we need to be very >> strict on them, at least not until after the code is completed and >> stabilized. >> >> GC >> >> On Sun, Feb 28, 2010 at 4:36 AM, Richard Frith-Macdonald >> wrote: >>> >>> On 27 Feb 2010, at 18:39, David Chisnall wrote: >>> I've now fixed this case in libobjc2. Unfortunately, someone decided to 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor to diffs against the original version in Étoilé svn), so whoever did that gets to volunteer to back-port the changes. >>> >>> Guess we should think about getting libobjc2 to conform to the coding >>> standards soon. At least that's easier because it's largely C code rather >>> than ObjC, and the 'indent' program will largely do it for us. > > Well, that's why I didn't mention it until now (hopefully the code is getting > stable ... it mostly seems to work). It makes me wonder though, if it would > be worth the effort of making the indent program work for objective-c (I've > always liked the idea of just automatically converting things to a common > style with indent when a file is committed but people being able to > regenerate their preferred style with indent on checkout ... it really should > be possible). > > Actually, David's original comment is a bit wide of the mark anyway ... > changes to the ObjectiveC2 code are rather more than just reindentation as it > needed a bug fix or two and quite a few changes to fix c99isms which > prevented it building on older systems (and the whole point of a > compatibility library is to allow older systems, specifically older versions > of the runtime, to work without having to have masses of #ifdef's in the > code). > > If we want to keep ObjectiveC2 and libobc2 sufficiently in sync to allow > patches from one to be applied to the other, we will need to restructure > quite a bit of the libobjc2 code to avoid c99 features where possible, and > David put a comment to Riccardo in libobjc2 specifically asking him not to do > that (since the new library will only work on more modern systems), so unless > David wants to reconsider, such synchronisation is impossible anyway :-( > > > > > -- Gregory Casamento - GNUstep Lead/Principal Consultant, OLC, Inc. yahoo/skype: greg_casamento, aol: gjcasa (240)274-9630 (Cell) ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
My apologies... I misunderstood the difficulty here. I'd forgotten that there is ObjectiveC2 and libobjc2. :) I'm not certain what the right solution here is beyond continuing to backport as best we can to ObjectiveC2. However, I think the question I asked in the previous email I sent is still relavent in general, though not related to this problem. GC On Sun, Feb 28, 2010 at 11:44 AM, Richard Frith-Macdonald wrote: > > On 28 Feb 2010, at 15:06, Gregory Casamento wrote: > >> Just one thing here... if conforming to the coding standards is going >> to be a point of contention, then I don't think we need to be very >> strict on them, at least not until after the code is completed and >> stabilized. >> >> GC >> >> On Sun, Feb 28, 2010 at 4:36 AM, Richard Frith-Macdonald >> wrote: >>> >>> On 27 Feb 2010, at 18:39, David Chisnall wrote: >>> I've now fixed this case in libobjc2. Unfortunately, someone decided to 'helpfully' reindent the version of ObjectiveC2.framework in GNUstep, which means that diffs from libobjc2 no longer cleanly apply in ObjectiveC2 (nor to diffs against the original version in Étoilé svn), so whoever did that gets to volunteer to back-port the changes. >>> >>> Guess we should think about getting libobjc2 to conform to the coding >>> standards soon. At least that's easier because it's largely C code rather >>> than ObjC, and the 'indent' program will largely do it for us. > > Well, that's why I didn't mention it until now (hopefully the code is getting > stable ... it mostly seems to work). It makes me wonder though, if it would > be worth the effort of making the indent program work for objective-c (I've > always liked the idea of just automatically converting things to a common > style with indent when a file is committed but people being able to > regenerate their preferred style with indent on checkout ... it really should > be possible). > > Actually, David's original comment is a bit wide of the mark anyway ... > changes to the ObjectiveC2 code are rather more than just reindentation as it > needed a bug fix or two and quite a few changes to fix c99isms which > prevented it building on older systems (and the whole point of a > compatibility library is to allow older systems, specifically older versions > of the runtime, to work without having to have masses of #ifdef's in the > code). > > If we want to keep ObjectiveC2 and libobc2 sufficiently in sync to allow > patches from one to be applied to the other, we will need to restructure > quite a bit of the libobjc2 code to avoid c99 features where possible, and > David put a comment to Riccardo in libobjc2 specifically asking him not to do > that (since the new library will only work on more modern systems), so unless > David wants to reconsider, such synchronisation is impossible anyway :-( > > > > > -- Gregory Casamento - GNUstep Lead/Principal Consultant, OLC, Inc. yahoo/skype: greg_casamento, aol: gjcasa (240)274-9630 (Cell) ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 28 Feb 2010, at 17:22, Gregory Casamento wrote: > My apologies... I misunderstood the difficulty here. I'd forgotten > that there is ObjectiveC2 and libobjc2. :) > > I'm not certain what the right solution here is beyond continuing to > backport as best we can to ObjectiveC2. I don't think it's a big deal ... this is fairly simple stuff. The complex/clever part of libobjc2 that David is working on, is the stuff which isn't in the ObjectiveC2backward compatibility code anyway. Basically we have two scenarios ... 1. modern systems using libobjc2 (fully featured ObjC2 code) 2. older systems (including most current production system) which won't ever get full featured ObjC2 support. The compatibility library means we can use the same runtime API for both scenarios, but it's not going to give the older systems the full ObjC2 feature set... some of the functions in the API will be no-ops > However, I think the question I asked in the previous email I sent is > still relavent in general, though not related to this problem. Yep .. I'd kind of like to say we can forget non-c99 systems. I know that Riccardo uses some. I know that Dr Nikolaus Schaller uses old compilers on his embedded systems But ... I'm not sure that the old compilers are *required*, it's probably a hassle to get a newer toolchain working on these old systems, but maybe not a bad thing to upgrade. At FOSDEM Felipe told me that the older compilers actually produce smaller code! So that might be an issue for embedded systems. However, I've also heard that Clang produces smaller code than current GCC (no idea if that's true), so it might pay for people currently using old compilers to look into updating to either the latest gcc or to Clang. So ... while I wouldn't take it upon myself to unilaterally insist on c99 compiler support yet, I would be strongly in favour of at least putting it on a roadmap and requiring the people using those old compilers either commit to a timetable for updating, or provide a convincing argument why we shouldn't. PS. after a recent linux specific bugfix, it looks like clang from svn trunk is finally able to build a working version of gnustep-base on gnu/linux (well, passing all the expected regression tests and working for a few apps I tested) using David's libobjc2 and the non-fragile-ivar ABI. ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Hi, Actually, David's original comment is a bit wide of the mark anyway ... changes to the ObjectiveC2 code are rather more than just reindentation as it needed a bug fix or two and quite a few changes to fix c99isms which prevented it building on older systems (and the whole point of a compatibility library is to allow older systems, specifically older versions of the runtime, to work without having to have masses of #ifdef's in the code). If we want to keep ObjectiveC2 and libobc2 sufficiently in sync to allow patches from one to be applied to the other, we will need to restructure quite a bit of the libobjc2 code to avoid c99 features where possible, and David put a comment to Riccardo in libobjc2 specifically asking him not to do that (since the new library will only work on more modern systems), so unless David wants to reconsider, such synchronisation is impossible anyway :-( It is not that I removed and changed stuff randomly, I just changed it where I needed it to get things to compile. So I'd like the compatibility library to continue to compile. I'm perfectly fine to use the old libobjc on the systems with old or weird compilers. As long of course as core itself doesn't require libobjc-2 feature (which I hope will be never, but that's tough to say). Things used to work well enough even on gcc 2.95 to have the whole gnustep core, gworkspace, systemprefrences, projectcenter, gorm and all of GAP compiling and working. That is all I ask, I do not expect to use Obj-c2 programs or etoile there. But breaking them gratuitously is stupid. Up to know I was able to detect and patch the stuff, it wasn't that hard, I just need sometimes help from the original author to understand what the code actually does. Riccardo ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 1 Mar 2010, at 00:12, Riccardo Mottola wrote: > It is not that I removed and changed stuff randomly, I just changed it where > I needed it to get things to compile. Yes, I think we all understand that. > So I'd like the compatibility library to continue to compile. I'm perfectly > fine to use the old libobjc on the systems with old or weird compilers. Using the old libobjc is not currently a problem, the problem is using the old API (or more accurately, having to use multiple runtime APIs)... I'm not really happy to continue using the old API for two reasons: To keep the code maintainable, we want to use a single API rather than using #ifdef to select alternative code fragments for different APIs. To maximise portability between GNUstep/OSX, we need that single API to be the one Apple use (we've tried using our own, and people weren't happy with that choice). The compatibility code should let us use the single API we want, with both old and new runtimes, so I'm very grateful that Etoile provided it. > As long of course as core itself doesn't require libobjc-2 feature (which I > hope will be never, but that's tough to say). That depends what you mean by 'require' ... some of Apples new OSX APIs cannot be implemented without ObjC2 features because they are built in to the API ... so to implement those features we will *have* to use ObjC2. However, for the forseeable future we are going to want to have GNUstep be able to build without ObjC2 on platforms where it is not available (and just leave the bits which require Objc2 unimplemented in those cases). > Things used to work well enough even on gcc 2.95 to have the whole gnustep > core, gworkspace, systemprefrences, projectcenter, gorm and all of GAP > compiling and working. That is all I ask, I do not expect to use Obj-c2 > programs or etoile there. But breaking them gratuitously is stupid. Nobody is breaking things gratuitously. The c99isms slip in to code simply because all modern compilers support them, and don't warn you that older compilers won't. Most people use them habitually (locality of declaration of variables is particularly good for code readability for instance) and simply won't notice that they have used them. Asking people to upgrade and use more modern compilers won't break any existing applications (old code will continue to compile), but would mean that we wouldn't have to keep trying to remember not to use c99 features, we wouldn't need to waste the time of people like you and me 'fixing' code which slips through into svn using them, and arguably we could write slightly better code. ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 1 Mar 2010, at 00:12, Riccardo Mottola wrote: > As long of course as core itself doesn't require libobjc-2 feature (which I > hope will be never, but that's tough to say). I don't have any plans for core to require anything in libobjc2, per se. There is currently one feature in -base that requires the new ABI; -forwardingTargetForSelector: on NSObject. I wrote a hacky implementation that will try to make this work with the old ABI (using -forwardInvocation:) but it's unreliable. This is quite a new feature on the Apple side, however. It doesn't give any more expressiveness, just a bit more speed. I think the other runtime hooks in NSObject that allow classes and objects to lazily install methods will also only work with libobjc2. Nothing in -base or -gui uses these (well, NSContentAccessingProxy does, but it has fall-back code for when they are not present, so it doesn't /require/ them). If third-party apps do, then that's beyond our control. Depending on them limits you to very recent versions of OS X, but given that people seem to be dropping support for 10.4 already that's possibly not a problem for Mac developers. On 1 Mar 2010, at 06:07, Richard Frith-Macdonald wrote: > Nobody is breaking things gratuitously. The c99isms slip in to code simply > because all modern compilers support them, and don't warn you that older > compilers won't. Most people use them habitually (locality of declaration of > variables is particularly good for code readability for instance) and simply > won't notice that they have used them. Additionally, a load of C99 features (e.g. VLAs, which GNUstep has used for ages) are implemented as extensions by GCC 2.95. Without access to it, it's difficult to keep track of exactly which subset of C99 will work with any given compiler version. GCC is terrible at documenting when features appeared; they expect everyone to use the latest version. David -- Sent from my Cray X1 ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Just for the record, I have nothing really to add to either David or Richard's comments since both of them sum up my feelings on the subject very succinctly. We should not sacrifice new features or readability for the sake of holding on to older architectures and compilers. Also, the use of non-c99 standards does hinder contributions since we constantly expect people who don't have access to c99 based compilers to change their code to conform to c89. GC On Mon, Mar 1, 2010 at 7:44 AM, David Chisnall wrote: > On 1 Mar 2010, at 00:12, Riccardo Mottola wrote: > >> As long of course as core itself doesn't require libobjc-2 feature (which I >> hope will be never, but that's tough to say). > > I don't have any plans for core to require anything in libobjc2, per se. > > There is currently one feature in -base that requires the new ABI; > -forwardingTargetForSelector: on NSObject. I wrote a hacky implementation > that will try to make this work with the old ABI (using -forwardInvocation:) > but it's unreliable. This is quite a new feature on the Apple side, however. > It doesn't give any more expressiveness, just a bit more speed. I think the > other runtime hooks in NSObject that allow classes and objects to lazily > install methods will also only work with libobjc2. > > Nothing in -base or -gui uses these (well, NSContentAccessingProxy does, but > it has fall-back code for when they are not present, so it doesn't /require/ > them). If third-party apps do, then that's beyond our control. Depending on > them limits you to very recent versions of OS X, but given that people seem > to be dropping support for 10.4 already that's possibly not a problem for Mac > developers. > > On 1 Mar 2010, at 06:07, Richard Frith-Macdonald wrote: > >> Nobody is breaking things gratuitously. The c99isms slip in to code simply >> because all modern compilers support them, and don't warn you that older >> compilers won't. Most people use them habitually (locality of declaration >> of variables is particularly good for code readability for instance) and >> simply won't notice that they have used them. > > Additionally, a load of C99 features (e.g. VLAs, which GNUstep has used for > ages) are implemented as extensions by GCC 2.95. Without access to it, it's > difficult to keep track of exactly which subset of C99 will work with any > given compiler version. GCC is terrible at documenting when features > appeared; they expect everyone to use the latest version. > > David > > -- Sent from my Cray X1 > > > > ___ > Gnustep-dev mailing list > Gnustep-dev@gnu.org > http://lists.gnu.org/mailman/listinfo/gnustep-dev > -- Gregory Casamento - GNUstep Lead/Principal Consultant, OLC, Inc. yahoo/skype: greg_casamento, aol: gjcasa (240)274-9630 (Cell) ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
We should not sacrifice new features or readability for the sake of holding on to older architectures and compilers. Also, the use of non-c99 standards does hinder contributions since we constantly expect people who don't have access to c99 based compilers to change their code to conform to c89. I think we should have a clear, explicit and unemotional support/ compatibility strategy. :-) As GCC 2.95.3 was released in March 16, 2001, it may make sense to no longer support it. Or maybe it does. I vote for supporting it. Anyway the question really is - what is the oldest GCC that we support if it's not 2.95.3 ? 3.0.4 (released February 20, 2002) ? Just mentioning c99 doesn't seem to help that much since IIRC no version of GCC actually implements all of c99 anyway. I actually am not really sure what C99 features, added after 2.95, we really need. Nobody is breaking things gratuitously. The c99isms slip in to code simply because all modern compilers support them, and don't warn you that older compilers won't. Most people use them habitually (locality of declaration of variables is particularly good for code readability for instance) and simply won't notice that they have used them. We can use -Wdeclaration-after-statement to get a post-2.95 GCC warn you when you locally declare variables without starting a { } block. Really not a problem - it's easy enough to add it to gnustep-base and gnustep-gui. Thanks ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Hi, Nicola Pero wrote: As GCC 2.95.3 was released in March 16, 2001, it may make sense to no longer support it. Or maybe it does. I vote for supporting it. Me obviously too! Anyway the question really is - what is the oldest GCC that we support if it's not 2.95.3 ? 3.0.4 (released February 20, 2002) ? Actually I think I find it more useful to support gcc 2.95 than 3.0.4 if any oddity will arise. From a personal experience in porting to non-gnu and non-BSD platforms, gcc 2.95 is a big milestone. THe next one is gcc 3.2, which was the last reasonable gcc compiler (with that I mean that if you can run 3.0, chances are high that 3.2 will be a no brainer). From that point on things get hairier with every release, depending more and more on gnu binary utilities, gnu assembler and with gcc 4 on other libraries. This makes it really a pain to bootstrap the compiler. I never got a reliable gcc > 3.2 on my AIX 4.x boxen at my old workplace and although IRIX was difficult, I do't think I got anything past gcc 3.4 to work. OFten C does work, but C++ does not and usually people like to have one compiler for C, C++ and Obj-C! Not that we support those platforms, I just used those as examples. Just mentioning c99 doesn't seem to help that much since IIRC no version of GCC actually implements all of c99 anyway. I actually am not really sure what C99 features, added after 2.95, we really need. This is correct, since from my knowledge we only support gcc and more recently clang. There aren't many other obj-c compilers around and AFAIk we don't support them. We can use -Wdeclaration-after-statement to get a post-2.95 GCC warn you when you locally declare variables without starting a { } block. Really not a problem - it's easy enough to add it to gnustep-base and gnustep-gui. We can do that, but fixing those is relatively trivial and personally I like to have all declarations on top, it is much more readable. Variadic Macros where an initial hurdle, but now I learned how to cope with them, Easy it is just ugly to #ifdef the code. These are the two recurrent things which I usually fix. Then there is instead a nasty compiler bug, which is that forward declarations of protocols is broken, but core avoids that cleanly up to now. Riccardo ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 1 Mar 2010, at 20:16, Nicola Pero wrote: > >> We should not sacrifice new features or readability for the sake of >> holding on to older architectures and compilers. >> >> Also, the use of non-c99 standards does hinder contributions since we >> constantly expect people who don't have access to c99 based compilers >> to change their code to conform to c89. > > I think we should have a clear, explicit and unemotional > support/compatibility strategy. :-) > > As GCC 2.95.3 was released in March 16, 2001, it may make sense to no longer > support it. > Or maybe it does. I vote for supporting it. > > Anyway the question really is - what is the oldest GCC that we support if > it's not 2.95.3 ? > > 3.0.4 (released February 20, 2002) ? > > Just mentioning c99 doesn't seem to help that much since IIRC no version of > GCC > actually implements all of c99 anyway. I actually am not really sure what > C99 features, > added after 2.95, we really need. > > Nobody is breaking things gratuitously. The c99isms slip in to code simply because all modern compilers support them, and don't warn you that older compilers won't. Most people use them habitually (locality of declaration of variables is particularly good for code readability for instance) and simply won't notice that they have used them. > > We can use -Wdeclaration-after-statement to get a post-2.95 GCC warn you when > you locally declare variables without starting a { } block. > Really not a problem - it's easy enough to add it to gnustep-base and > gnustep-gui. I didn't know about -Wdeclaration-after-statement I guess it's true that the issue is not c99 as such ... I think the problem is almost entirely down to declarations after statements and the warning flag could catch that. If so, adding -Wdeclaration-after-statement would remove most of the maintenance issue (though of course it means you can't have locality of variable declaration without an ugly excess of curly braces to wrap them). David's libobjc2 code won't even build using the compiler on CentOS/Redhant 4.5 (gcc-4.1.2) and we almost certainly can't insist on people using compilers younger than that... it's only three years old! For now, I'll add -Wdeclaration-after-statement to gnustep base. Still, I think we need to keep an eye on this issue. ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 3 Mar 2010, at 09:48, Richard Frith-Macdonald wrote: > David's libobjc2 code won't even build using the compiler on CentOS/Redhant > 4.5 (gcc-4.1.2) and we almost certainly can't insist on people using > compilers younger than that... it's only three years old! The only way to fix that is for someone to write some inline assembly for every single platform that we want to support that provides the atomic operations. I'm not particularly interested in doing that, because GCC 4.2 supports the intrinsics (as does clang), is three years old next Saturday, and runs on all of the platforms that I'm interested in supporting. Actually, according to the manual, these should work on 4.1.2 as well, so I'm not sure why you had a problem. Possibly it was the -march=native (you need to specify a target CPU that actually supports atomic ops for the compiler to be able to generate code for them, so explicitly stating -march=i686 should work as a substitute): http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html In NSObject, we have a lot of code for doing atomic operations, to support old compilers, and we still don't have (for example) fast paths for SPARC, ARM, or MIPS unless you use GCC 4.2 or newer. We only have fast paths on PowerPC and M68K because I wrote the former and worked with Riccardo to implement the latter. David -- Sent from my Difference Engine ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Hi, http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html In NSObject, we have a lot of code for doing atomic operations, to support old compilers, and we still don't have (for example) fast paths for SPARC, ARM, or MIPS unless you use GCC 4.2 or newer. We only have fast paths on PowerPC and M68K because I wrote the former and worked with Riccardo to implement the latter. wow, so except the m68k thing that was done more for fun a weekend but is perhaps not of such big interest (or does somebody runs gnustep on an embedded platform?) Sparc, ARM and MIPS would be of wider use. I can look and test Sparc and MIPS (LE). Maybe we can do that on another rainy weekend, David? An excuse to dig out the sparc-asm. Actually, I think I did implement it for the Kaffe Java-VM, I should look there. Riccardo ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On 3 Mar 2010, at 19:20, Riccardo Mottola wrote: > Hi, >> http://gcc.gnu.org/onlinedocs/gcc-4.1.2/gcc/Atomic-Builtins.html >> >> In NSObject, we have a lot of code for doing atomic operations, to support >> old compilers, and we still don't have (for example) fast paths for SPARC, >> ARM, or MIPS unless you use GCC 4.2 or newer. We only have fast paths on >> PowerPC and M68K because I wrote the former and worked with Riccardo to >> implement the latter. >> > wow, so except the m68k thing that was done more for fun a weekend but is > perhaps not of such big interest (or does somebody runs gnustep on an > embedded platform?) Sparc, ARM and MIPS would be of wider use. > > I can look and test Sparc and MIPS (LE). Maybe we can do that on another > rainy weekend, David? An excuse to dig out the sparc-asm. > Actually, I think I did implement it for the Kaffe Java-VM, I should look > there. If you're using Clang or GCC >= 4.2 then you get the fast path on these platforms with the compiler intrinsics. It's only if you're using an older GCC that you have problems. I'm not sure what your little MIPS machine uses, but I'd imagine it's a sufficiently recent GCC for this not to be an issue. I think you said OpenBSD on SPARC32 is still using an ancient GCC, but it is supported by clang, so it would be worth switching on that platform. ARM gets a lot of attention from Apple at the moment (apparently they ship some things with ARM chips in them), so it has good support in clang and quite good support in recent GCC for EABI platforms, but not so much for OABI ones. I think there might be some code in MySTEP for the atomic ops though, as I seem to recall Nikolaus using GCC 2.95 for a long time and performance on a 200MHz ARM chip using an objc_mutex for protecting reference counts would have been painful (unless he just didn't support multiple threads, in which case he could have used nonatomic ops). Actually, I wonder what kind of performance difference we'd see if we replaced -retain and -release with nonatomic versions and swizzled the methods to use the atomic versions when the will become multithreaded notification is posted. I might have a go at implementing that, if anyone has some good benchmarking code for testing it... David -- Sent from my IBM 1620 ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
Am 03.03.2010 um 20:34 schrieb David Chisnall: ARM gets a lot of attention from Apple at the moment (apparently they ship some things with ARM chips in them) It's no secret the iPhone as well as the iPad ship with ARM CPUs. Markus ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: sync.m
On Fri, 5 Mar 2010 22:02:31 +0100, Markus Hitter wrote: > Am 03.03.2010 um 20:34 schrieb David Chisnall: > >> ARM gets a lot of attention from Apple at the moment (apparently >> they ship some things with ARM chips in them) > > It's no secret the iPhone as well as the iPad ship with ARM CPUs. > I thought he was ironic not mentioning them explicitely ;-) ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
ObjectiveC2 sync.m dealloc/synthesized setter issue.
If you call a synthesized setter in dealloc, you get a fault. The synthesized setter wants to sync, the object's "isa" has already been restored to pre-faux-lock-object-subclass; therefore, sync.m attempts to re-subclass-swizzle which fails at some assert within the runtime (I don't have the runtime built with debug). Clearly, if it were to succeed, bad things would happen. OK, didn't look at SVN. We seem to have a better approach, though looks like we can never clean up locks. Thought: we should still be able to swizzle 'dealloc', no? We just need to steal the dealloc of any object hierarchy root? ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev
Re: ObjectiveC2 sync.m dealloc/synthesized setter issue.
On 9 Feb 2011, at 04:36, Jason Felice wrote: > If you call a synthesized setter in dealloc, you get a fault. The > synthesized setter wants to sync, the object's "isa" has already been > restored to pre-faux-lock-object-subclass; therefore, sync.m attempts to > re-subclass-swizzle which fails at some assert within the runtime (I don't > have the runtime built with debug). This should have been fixed in libobjc2 some time ago (before 1.0, I think). The dealloc method added by the lock class calls [super dealloc], then destroys the lock class after it returns. > Clearly, if it were to succeed, bad things would happen. > > OK, didn't look at SVN. We seem to have a better approach, though looks like > we can never clean up locks. Please test this with a vaguely recent svn and provide me with a simple test case if it still doesn't work for you. > Thought: we should still be able to swizzle 'dealloc', no? We just need to > steal the dealloc of any object hierarchy root? Yes, if you only had to deal with well-written code. Unfortunately, a load of GNUstep code uses NSDeallocateObject(self) instead of calling [super dealloc]. David -- Sent from my Difference Engine ___ Gnustep-dev mailing list Gnustep-dev@gnu.org http://lists.gnu.org/mailman/listinfo/gnustep-dev