ObjFW  Check-in [bd6a71aad3]

Overview
Comment:Fall back to spinlocks if atomic ops are unavailable.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: bd6a71aad3b6e67b142c31eaf97beb820e28b27515d45aad3427575b05938196
User & Date: js on 2010-01-30 01:50:18
Other Links: manifest | tags
Context
2010-01-30
02:09
Replace some macros with OF_INLINE functions.
This way, there won't be a warning about unused results.
check-in: 839f45a293 user: js tags: trunk
01:50
Fall back to spinlocks if atomic ops are unavailable. check-in: bd6a71aad3 user: js tags: trunk
01:17
Change spinlock implementation, add fallbacks and move to threading.h. check-in: 921b158d17 user: js tags: trunk
Changes

Modified src/OFObject.m from [f35a66b387] to [415ea37dd0].

27
28
29
30
31
32
33
34




35
36
37
38



39
40
41
42
43
44
45
# import <objc/runtime.h>
#endif
#ifdef OF_GNU_RUNTIME
# import <objc/sarray.h>
#endif

#import "atomic.h"





struct pre_ivar {
	void	**memchunks;
	size_t	memchunks_size;
	int32_t	retain_count;	/* int32_t because atomic ops use int32_t */



};

/* Hopefully no arch needs more than 16 bytes padding */
#define PRE_IVAR_ALIGN ((sizeof(struct pre_ivar) + 15) & ~15)
#define PRE_IVAR ((struct pre_ivar*)((char*)self - PRE_IVAR_ALIGN))

static struct {








>
>
>
>

|
|
|
>
>
>







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# import <objc/runtime.h>
#endif
#ifdef OF_GNU_RUNTIME
# import <objc/sarray.h>
#endif

#import "atomic.h"

#ifndef OF_ATOMIC_OPS
#import "threading.h"
#endif

struct pre_ivar {
	void	      **memchunks;
	size_t	      memchunks_size;
	int32_t	      retain_count; /* int32_t because atomic ops use int32_t */
#ifndef OF_ATOMIC_OPS
	of_spinlock_t retain_spinlock;
#endif
};

/* Hopefully no arch needs more than 16 bytes padding */
#define PRE_IVAR_ALIGN ((sizeof(struct pre_ivar) + 15) & ~15)
#define PRE_IVAR ((struct pre_ivar*)((char*)self - PRE_IVAR_ALIGN))

static struct {
108
109
110
111
112
113
114




115
116
117
118
119
120
121
		alloc_failed_exception.isa = [OFAllocFailedException class];
		@throw (OFAllocFailedException*)&alloc_failed_exception;
	}

	((struct pre_ivar*)instance)->memchunks = NULL;
	((struct pre_ivar*)instance)->memchunks_size = 0;
	((struct pre_ivar*)instance)->retain_count = 1;





	instance = (OFObject*)((char*)instance + PRE_IVAR_ALIGN);
	memset(instance, 0, isize);
	instance->isa = self;

	return instance;
}







>
>
>
>







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
		alloc_failed_exception.isa = [OFAllocFailedException class];
		@throw (OFAllocFailedException*)&alloc_failed_exception;
	}

	((struct pre_ivar*)instance)->memchunks = NULL;
	((struct pre_ivar*)instance)->memchunks_size = 0;
	((struct pre_ivar*)instance)->retain_count = 1;

#ifndef OF_ATOMIC_OPS
	of_spinlock_new(&((struct pre_ivar*)instance)->retain_spinlock);
#endif

	instance = (OFObject*)((char*)instance + PRE_IVAR_ALIGN);
	memset(instance, 0, isize);
	instance->isa = self;

	return instance;
}
483
484
485
486
487
488
489

490





491
492
493
494
495
496
497
498
499
500
501

502
503










504
505
506
507
508
509
510

	@throw [OFMemoryNotPartOfObjectException newWithClass: isa
						      pointer: ptr];
}

- retain
{

	of_atomic_inc32(&PRE_IVAR->retain_count);






	return self;
}

- (int32_t)retainCount
{
	return PRE_IVAR->retain_count;
}

- (void)release
{

	if (!of_atomic_dec32(&PRE_IVAR->retain_count))
		[self dealloc];










}

- autorelease
{
	[OFAutoreleasePool addObjectToTopmostPool: self];

	return self;







>

>
>
>
>
>











>


>
>
>
>
>
>
>
>
>
>







494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

	@throw [OFMemoryNotPartOfObjectException newWithClass: isa
						      pointer: ptr];
}

- retain
{
#ifdef OF_ATOMIC_OPS
	of_atomic_inc32(&PRE_IVAR->retain_count);
#else
	of_spinlock_lock(&PRE_IVAR->retain_spinlock);
	PRE_IVAR->retain_count++;
	of_spinlock_unlock(&PRE_IVAR->retain_spinlock);
#endif

	return self;
}

- (int32_t)retainCount
{
	return PRE_IVAR->retain_count;
}

- (void)release
{
#ifdef OF_ATOMIC_OPS
	if (!of_atomic_dec32(&PRE_IVAR->retain_count))
		[self dealloc];
#else
	int32_t c;

	of_spinlock_lock(&PRE_IVAR->retain_spinlock);
	c = --PRE_IVAR->retain_count;
	of_spinlock_unlock(&PRE_IVAR->retain_spinlock);

	if (!c)
		[self dealloc];
#endif
}

- autorelease
{
	[OFAutoreleasePool addObjectToTopmostPool: self];

	return self;