ObjFW  Check-in [1cb3d9fef9]

Overview
Comment:Add of_rmutex_t, a reentrant mutex implementation.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 1cb3d9fef9d4170740deb898665772392dd77fb7a6a93cb0593d45e611ba8c64
User & Date: js on 2012-08-05 10:45:41
Original User & Date: js on 2012-08-05 10:45:42
Other Links: manifest | tags
Context
2012-08-05
10:45
runtime: Rewrite synchronized.m. check-in: f65ad67272 user: js tags: trunk
10:45
Add of_rmutex_t, a reentrant mutex implementation. check-in: 1cb3d9fef9 user: js tags: trunk
2012-08-04
10:29
Add missing include. check-in: 96de96bbf6 user: js tags: trunk
Changes

Modified src/runtime/runtime-private.h from [84eb751cc1] to [8b51aa0f01].

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
extern void objc_free_all_classes(void);
extern uint32_t objc_hash_string(const char*);
extern struct objc_hashtable* objc_hashtable_new(uint32_t);
extern void objc_hashtable_set(struct objc_hashtable*, const char*,
    const void*);
extern void* objc_hashtable_get(struct objc_hashtable*, const char*);
extern void objc_hashtable_free(struct objc_hashtable *h);
extern BOOL objc_hashtable_warn_on_collision;
extern void objc_register_selector(struct objc_abi_selector*);
extern void objc_register_all_selectors(struct objc_abi_symtab*);
extern void objc_free_all_selectors(void);
extern struct objc_sparsearray* objc_sparsearray_new(void);
extern void objc_sparsearray_copy(struct objc_sparsearray*,
    struct objc_sparsearray*);
extern void objc_sparsearray_set(struct objc_sparsearray*, uint32_t,
    const void*);
extern void objc_sparsearray_free(struct objc_sparsearray*);
extern void objc_sparsearray_free_when_singlethreaded(struct objc_sparsearray*);
extern void objc_sparsearray_cleanup(void);
extern void objc_init_static_instances(struct objc_abi_symtab*);
extern void __objc_exec_class(struct objc_abi_module*);
extern BOOL objc_mutex_new(objc_mutex_t*);
extern BOOL objc_mutex_lock(objc_mutex_t*);
extern BOOL objc_mutex_unlock(objc_mutex_t*);
extern BOOL objc_mutex_free(objc_mutex_t*);
extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);
extern void objc_free_when_singlethreaded(void*);

static inline void*
objc_sparsearray_get(const struct objc_sparsearray *s, uint32_t idx)
{
#ifndef OF_SELUID16
	uint8_t i = idx >> 16;
	uint8_t j = idx >>  8;







<









<



<
<
<
<



<







139
140
141
142
143
144
145

146
147
148
149
150
151
152
153
154

155
156
157




158
159
160

161
162
163
164
165
166
167
extern void objc_free_all_classes(void);
extern uint32_t objc_hash_string(const char*);
extern struct objc_hashtable* objc_hashtable_new(uint32_t);
extern void objc_hashtable_set(struct objc_hashtable*, const char*,
    const void*);
extern void* objc_hashtable_get(struct objc_hashtable*, const char*);
extern void objc_hashtable_free(struct objc_hashtable *h);

extern void objc_register_selector(struct objc_abi_selector*);
extern void objc_register_all_selectors(struct objc_abi_symtab*);
extern void objc_free_all_selectors(void);
extern struct objc_sparsearray* objc_sparsearray_new(void);
extern void objc_sparsearray_copy(struct objc_sparsearray*,
    struct objc_sparsearray*);
extern void objc_sparsearray_set(struct objc_sparsearray*, uint32_t,
    const void*);
extern void objc_sparsearray_free(struct objc_sparsearray*);

extern void objc_sparsearray_cleanup(void);
extern void objc_init_static_instances(struct objc_abi_symtab*);
extern void __objc_exec_class(struct objc_abi_module*);




extern void objc_global_mutex_lock(void);
extern void objc_global_mutex_unlock(void);
extern void objc_global_mutex_free(void);


static inline void*
objc_sparsearray_get(const struct objc_sparsearray *s, uint32_t idx)
{
#ifndef OF_SELUID16
	uint8_t i = idx >> 16;
	uint8_t j = idx >>  8;

Modified src/runtime/threading.m from [1343be0c29] to [0fd3a6e663].

17
18
19
20
21
22
23

24
25
26
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include "config.h"

#include <stdio.h>
#include <stdlib.h>

#import "runtime.h"
#import "runtime-private.h"


static objc_mutex_t global_mutex;
static BOOL global_mutex_init = NO;

BOOL
objc_mutex_new(objc_mutex_t *mutex)
{
	if (!of_mutex_new(&mutex->mutex ))
		return NO;

	mutex->count = 0;

	return YES;
}

BOOL
objc_mutex_lock(objc_mutex_t *mutex)
{
	if (mutex->count > 0 && of_thread_is_current(mutex->owner)) {
		mutex->count++;
		return YES;
	}

	if (!of_mutex_lock(&mutex->mutex))
		return NO;

	mutex->owner = of_thread_current();
	mutex->count++;

	return YES;
}

BOOL
objc_mutex_unlock(objc_mutex_t *mutex)
{
	if (--mutex->count == 0)
		return of_mutex_unlock(&mutex->mutex);

	return YES;
}

BOOL
objc_mutex_free(objc_mutex_t *mutex)
{
	return of_mutex_free(&mutex->mutex);
}

static void
objc_global_mutex_new(void)
{
	if (!objc_mutex_new(&global_mutex))
		OBJC_ERROR("Failed to create global mutex!");

	global_mutex_init = YES;
}

void
objc_global_mutex_lock(void)
{
	if (!global_mutex_init)
		objc_global_mutex_new();

	if (!objc_mutex_lock(&global_mutex))
		OBJC_ERROR("Failed to lock global mutex!");
}

void
objc_global_mutex_unlock(void)
{
	if (!objc_mutex_unlock(&global_mutex))
		OBJC_ERROR("Failed to unlock global mutex!");
}

void
objc_global_mutex_free(void)
{
	if (!objc_mutex_free(&global_mutex))
		OBJC_ERROR("Failed to free global mutex!");
}







>

|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|











|






|






|


17
18
19
20
21
22
23
24
25
26
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
53
54
55
56
57
58
59
60
#include "config.h"

#include <stdio.h>
#include <stdlib.h>

#import "runtime.h"
#import "runtime-private.h"
#import "threading.h"

static of_rmutex_t global_mutex;
static BOOL global_mutex_init = NO;












































static void
objc_global_mutex_new(void)
{
	if (!of_rmutex_new(&global_mutex))
		OBJC_ERROR("Failed to create global mutex!");

	global_mutex_init = YES;
}

void
objc_global_mutex_lock(void)
{
	if (!global_mutex_init)
		objc_global_mutex_new();

	if (!of_rmutex_lock(&global_mutex))
		OBJC_ERROR("Failed to lock global mutex!");
}

void
objc_global_mutex_unlock(void)
{
	if (!of_rmutex_unlock(&global_mutex))
		OBJC_ERROR("Failed to unlock global mutex!");
}

void
objc_global_mutex_free(void)
{
	if (!of_rmutex_free(&global_mutex))
		OBJC_ERROR("Failed to free global mutex!");
}

Modified src/threading.h from [47f623ac86] to [f15e1e67ea].

44
45
46
47
48
49
50





51
52
53
54
55
56
57
typedef volatile int of_spinlock_t;
# define OF_SPINCOUNT 10
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
typedef pthread_spinlock_t of_spinlock_t;
#else
typedef of_mutex_t of_spinlock_t;
#endif






#if defined(OF_HAVE_PTHREADS)
# define of_thread_is_current(t) pthread_equal(t, pthread_self())
# define of_thread_current pthread_self
#elif defined(_WIN32)
# define of_thread_is_current(t) (t == GetCurrentThread())
# define of_thread_current GetCurrentThread







>
>
>
>
>







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
typedef volatile int of_spinlock_t;
# define OF_SPINCOUNT 10
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
typedef pthread_spinlock_t of_spinlock_t;
#else
typedef of_mutex_t of_spinlock_t;
#endif

typedef struct {
	of_mutex_t mutex;
	of_tlskey_t count;
} of_rmutex_t;

#if defined(OF_HAVE_PTHREADS)
# define of_thread_is_current(t) pthread_equal(t, pthread_self())
# define of_thread_current pthread_self
#elif defined(_WIN32)
# define of_thread_is_current(t) (t == GetCurrentThread())
# define of_thread_current GetCurrentThread
359
360
361
362
363
364
365


































































	return YES;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_destroy(spinlock);
#else
	return of_mutex_free(spinlock);
#endif
}









































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
	return YES;
#elif defined(OF_HAVE_PTHREAD_SPINLOCKS)
	return !pthread_spin_destroy(spinlock);
#else
	return of_mutex_free(spinlock);
#endif
}

static OF_INLINE BOOL
of_rmutex_new(of_rmutex_t *rmutex)
{
	if (!of_mutex_new(&rmutex->mutex))
		return NO;

	if (!of_tlskey_new(&rmutex->count))
		return NO;

	return YES;
}

static OF_INLINE BOOL
of_rmutex_lock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 0) {
		if (!of_tlskey_set(rmutex->count, (void*)(count + 1)))
			return NO;
		return YES;
	}

	if (!of_mutex_lock(&rmutex->mutex))
		return NO;

	if (!of_tlskey_set(rmutex->count, (void*)1)) {
		of_mutex_unlock(&rmutex->mutex);
		return NO;
	}

	return YES;
}

static OF_INLINE BOOL
of_rmutex_unlock(of_rmutex_t *rmutex)
{
	uintptr_t count = (uintptr_t)of_tlskey_get(rmutex->count);

	if (count > 1) {
		if (!of_tlskey_set(rmutex->count, (void*)(count - 1)))
			return NO;
		return YES;
	}

	if (!of_tlskey_set(rmutex->count, (void*)0))
		return NO;

	if (!of_mutex_unlock(&rmutex->mutex))
		return NO;

	return YES;
}

static OF_INLINE BOOL
of_rmutex_free(of_rmutex_t *rmutex)
{
	if (!of_mutex_free(&rmutex->mutex))
		return NO;

	if (!of_tlskey_free(rmutex->count))
		return NO;

	return YES;
}