ObjFW  Check-in [27138ee85b]

Overview
Comment:Add a few memory barriers.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 27138ee85bb19b2a6ff1b1a368f2e7679046e1dd117e7079e716af7894ca4847
User & Date: js on 2013-03-14 19:25:48
Other Links: manifest | tags
Context
2013-03-14
20:20
Tag class pointers for @compatibility_aliases. check-in: 69d9f76520 user: js tags: trunk
19:25
Add a few memory barriers. check-in: 27138ee85b user: js tags: trunk
2013-03-13
13:31
objfw-config: Add --arc to help. check-in: e6b08898bd user: js tags: trunk
Changes

Modified src/OFRunLoop.m from [d42000199a] to [3b393cf990].

593
594
595
596
597
598
599
600
601
602
603
604







605
606
607
608
609
610
611
		OF_ENSURE(0);
}

- (void)run
{
	_running = true;

	while (_running) {
		void *pool = objc_autoreleasePoolPush();
		OFDate *now = [OFDate date];
		OFTimer *timer;
		OFDate *nextTimer;








#ifdef OF_HAVE_THREADS
		[_timersQueueLock lock];
		@try {
#endif
			of_list_object_t *listObject =
			    [_timersQueue firstListObject];







|
|
|


>
>
>
>
>
>
>







593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
		OF_ENSURE(0);
}

- (void)run
{
	_running = true;

	for (;;) {
		void *pool;
		OFDate *now;
		OFTimer *timer;
		OFDate *nextTimer;

		of_memory_read_barrier();
		if (!_running)
			break;

		pool = objc_autoreleasePoolPush();
		now = [OFDate date];

#ifdef OF_HAVE_THREADS
		[_timersQueueLock lock];
		@try {
#endif
			of_list_object_t *listObject =
			    [_timersQueue firstListObject];
659
660
661
662
663
664
665

666
667
668
		objc_autoreleasePoolPop(pool);
	}
}

- (void)stop
{
	_running = false;

	[_streamObserver cancel];
}
@end







>



666
667
668
669
670
671
672
673
674
675
676
		objc_autoreleasePoolPop(pool);
	}
}

- (void)stop
{
	_running = false;
	of_memory_write_barrier();
	[_streamObserver cancel];
}
@end

Modified src/OFThreadPool.m from [0d55db513d] to [b54e691e3d].

170
171
172
173
174
175
176

177
178
179
180
181
182
183
184
185
186
187
188

189
190
191
192
193
194
195
196
197
198

199
200
201
202
203
204
205
206
207
208
209
210
211
212

213
214
215
216
217
218
219

220
221
222
223
224
225
226
227
228
229

230
231
232
233
234
235
236
	[super dealloc];
}

- (id)main
{
	void *pool;


	if (_terminate)
		return nil;

	pool = objc_autoreleasePoolPush();

	for (;;) {
		OFThreadPoolJob *job;

		[_queueCondition lock];
		@try {
			of_list_object_t *listObject;


			if (_terminate) {
				objc_autoreleasePoolPop(pool);
				return nil;
			}

			listObject = [_queue firstListObject];

			while (listObject == NULL) {
				[_queueCondition wait];


				if (_terminate) {
					objc_autoreleasePoolPop(pool);
					return nil;
				}

				listObject = [_queue firstListObject];
			}

			job = [[listObject->object retain] autorelease];
			[_queue removeListObject: listObject];
		} @finally {
			[_queueCondition unlock];
		}


		if (_terminate) {
			objc_autoreleasePoolPop(pool);
			return nil;
		}

		[job perform];


		if (_terminate) {
			objc_autoreleasePoolPop(pool);
			return nil;
		}

		objc_autoreleasePoolPop(pool);
		pool = objc_autoreleasePoolPush();

		[_countCondition lock];
		@try {

			if (_terminate) {
				objc_autoreleasePoolPop(pool);
				return nil;
			}

			(*_doneCount)++;








>












>










>














>







>










>







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
	[super dealloc];
}

- (id)main
{
	void *pool;

	of_memory_read_barrier();
	if (_terminate)
		return nil;

	pool = objc_autoreleasePoolPush();

	for (;;) {
		OFThreadPoolJob *job;

		[_queueCondition lock];
		@try {
			of_list_object_t *listObject;

			of_memory_read_barrier();
			if (_terminate) {
				objc_autoreleasePoolPop(pool);
				return nil;
			}

			listObject = [_queue firstListObject];

			while (listObject == NULL) {
				[_queueCondition wait];

				of_memory_read_barrier();
				if (_terminate) {
					objc_autoreleasePoolPop(pool);
					return nil;
				}

				listObject = [_queue firstListObject];
			}

			job = [[listObject->object retain] autorelease];
			[_queue removeListObject: listObject];
		} @finally {
			[_queueCondition unlock];
		}

		of_memory_read_barrier();
		if (_terminate) {
			objc_autoreleasePoolPop(pool);
			return nil;
		}

		[job perform];

		of_memory_read_barrier();
		if (_terminate) {
			objc_autoreleasePoolPop(pool);
			return nil;
		}

		objc_autoreleasePoolPop(pool);
		pool = objc_autoreleasePoolPush();

		[_countCondition lock];
		@try {
			of_memory_read_barrier();
			if (_terminate) {
				objc_autoreleasePoolPop(pool);
				return nil;
			}

			(*_doneCount)++;

304
305
306
307
308
309
310


311
312
313
314
315
316
317
		[_countCondition lock];
		@try {
			OFEnumerator *enumerator = [_threads objectEnumerator];
			OFThreadPoolThread *thread;

			while ((thread = [enumerator nextObject]) != nil)
				thread->_terminate = true;


		} @finally {
			[_countCondition unlock];
		}

		[_queueCondition broadcast];
	} @finally {
		[_queueCondition unlock];







>
>







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
		[_countCondition lock];
		@try {
			OFEnumerator *enumerator = [_threads objectEnumerator];
			OFThreadPoolThread *thread;

			while ((thread = [enumerator nextObject]) != nil)
				thread->_terminate = true;

			of_memory_write_barrier();
		} @finally {
			[_countCondition unlock];
		}

		[_queueCondition broadcast];
	} @finally {
		[_queueCondition unlock];

Modified src/atomic.h from [a4f95ba0da] to [d4ea46f231].

753
754
755
756
757
758
759











































	return __sync_bool_compare_and_swap(p, o, n);
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicCompareAndSwapPtrBarrier(o, n, p);
#else
# error No atomic operations available!
#endif
}


















































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
	return __sync_bool_compare_and_swap(p, o, n);
#elif defined(OF_HAVE_OSATOMIC)
	return OSAtomicCompareAndSwapPtrBarrier(o, n, p);
#else
# error No atomic operations available!
#endif
}

static OF_INLINE void
of_memory_barrier(void)
{
#if !defined(OF_HAVE_THREADS)
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ __volatile__ (
	    "mfence"
	);
#elif defined(OF_HAVE_GCC_ATOMIC_OPS)
	__sync_synchronize();
#elif defined(OF_HAVE_OSATOMIC)
	OSMemoryBarrier();
#else
# error No atomic operations available!
#endif
}

static OF_INLINE void
of_memory_read_barrier(void)
{
#if !defined(OF_HAVE_THREADS)
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ __volatile__ (
	    "lfence"
	);
#else
	of_memory_barrier();
#endif
}

static OF_INLINE void
of_memory_write_barrier(void)
{
#if !defined(OF_HAVE_THREADS)
#elif defined(OF_X86_ASM) || defined(OF_AMD64_ASM)
	__asm__ __volatile__ (
	    "sfence"
	);
#else
	of_memory_barrier();
#endif
}

Modified src/threading.h from [c5163894df] to [49f79a338f].

349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#endif
}

static OF_INLINE bool
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)
	*spinlock = 0;
	return true;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_unlock(spinlock);
#else
	return of_mutex_unlock(spinlock);
#endif
}








<
|







349
350
351
352
353
354
355

356
357
358
359
360
361
362
363
#endif
}

static OF_INLINE bool
of_spinlock_unlock(of_spinlock_t *spinlock)
{
#if defined(OF_HAVE_ATOMIC_OPS)

	return of_atomic_cmpswap_int(spinlock, 1, 0);
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_unlock(spinlock);
#else
	return of_mutex_unlock(spinlock);
#endif
}