forked from Bananymous/banan-os
				
			LibC: Implement pthread_barrier
This is not fully working but should be fine for most cases
This commit is contained in:
		
							parent
							
								
									60cb392e97
								
							
						
					
					
						commit
						2a5921b9c9
					
				|  | @ -28,8 +28,8 @@ typedef pthread_t pthread_spinlock_t; | |||
| typedef struct { int type; int shared; } pthread_mutexattr_t; | ||||
| typedef struct { pthread_mutexattr_t attr; pthread_t locker; unsigned lock_depth; } pthread_mutex_t; | ||||
| 
 | ||||
| typedef int pthread_barrierattr_t; | ||||
| typedef int pthread_barrier_t; | ||||
| typedef struct { int shared; } pthread_barrierattr_t; | ||||
| typedef struct { pthread_barrierattr_t attr; unsigned target; unsigned waiting; } pthread_barrier_t; | ||||
| 
 | ||||
| typedef struct { int clock; int shared; } pthread_condattr_t; | ||||
| struct _pthread_cond_block { struct _pthread_cond_block* next; int signaled; }; | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ struct uthread | |||
| 	uintptr_t dtv[]; | ||||
| }; | ||||
| 
 | ||||
| #define PTHREAD_BARRIER_SERIAL_THREAD	1 | ||||
| #define PTHREAD_CANCEL_ASYNCHRONOUS		2 | ||||
| #define PTHREAD_CANCEL_ENABLE			3 | ||||
| #define PTHREAD_CANCEL_DEFERRED			4 | ||||
|  | @ -40,6 +39,8 @@ struct uthread | |||
| #define PTHREAD_SCOPE_PROCESS			23 | ||||
| #define PTHREAD_SCOPE_SYSTEM			24 | ||||
| 
 | ||||
| #define PTHREAD_BARRIER_SERIAL_THREAD	1 | ||||
| 
 | ||||
| #define PTHREAD_ONCE_INIT				0 | ||||
| 
 | ||||
| #define PTHREAD_PROCESS_SHARED			0 | ||||
|  |  | |||
|  | @ -818,6 +818,82 @@ int pthread_cond_timedwait(pthread_cond_t* __restrict cond, pthread_mutex_t* __r | |||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int pthread_barrierattr_destroy(pthread_barrierattr_t* attr) | ||||
| { | ||||
| 	(void)attr; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int pthread_barrierattr_init(pthread_barrierattr_t* attr) | ||||
| { | ||||
| 	*attr = { | ||||
| 		.shared = false, | ||||
| 	}; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int pthread_barrierattr_getpshared(const pthread_barrierattr_t* __restrict attr, int* __restrict pshared) | ||||
| { | ||||
| 	*pshared = attr->shared ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int pthread_barrierattr_setpshared(pthread_barrierattr_t* attr, int pshared) | ||||
| { | ||||
| 	switch (pshared) | ||||
| 	{ | ||||
| 		case PTHREAD_PROCESS_PRIVATE: | ||||
| 			attr->shared = false; | ||||
| 			return 0; | ||||
| 		case PTHREAD_PROCESS_SHARED: | ||||
| 			attr->shared = true; | ||||
| 			return 0; | ||||
| 	} | ||||
| 	return EINVAL; | ||||
| } | ||||
| 
 | ||||
| int pthread_barrier_destroy(pthread_barrier_t* barrier) | ||||
| { | ||||
| 	(void)barrier; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int pthread_barrier_init(pthread_barrier_t* __restrict barrier, const pthread_barrierattr_t* __restrict attr, unsigned count) | ||||
| { | ||||
| 	if (count == 0) | ||||
| 		return EINVAL; | ||||
| 	const pthread_barrierattr_t default_attr = { | ||||
| 		.shared = false, | ||||
| 	}; | ||||
| 	if (attr == nullptr) | ||||
| 		attr = &default_attr; | ||||
| 	*barrier = { | ||||
| 		.attr = *attr, | ||||
| 		.target = count, | ||||
| 		.waiting = 0, | ||||
| 	}; | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| int pthread_barrier_wait(pthread_barrier_t* barrier) | ||||
| { | ||||
| 	const unsigned index = BAN::atomic_add_fetch(barrier->waiting, 1); | ||||
| 
 | ||||
| 	// FIXME: this case should be handled, but should be relatively uncommon
 | ||||
| 	//        so i'll just roll with the easy implementation
 | ||||
| 	ASSERT(index <= barrier->target); | ||||
| 
 | ||||
| 	if (index == barrier->target) | ||||
| 	{ | ||||
| 		BAN::atomic_store(barrier->waiting, 0); | ||||
| 		return PTHREAD_BARRIER_SERIAL_THREAD; | ||||
| 	} | ||||
| 
 | ||||
| 	while (BAN::atomic_load(barrier->waiting)) | ||||
| 		sched_yield(); | ||||
| 	return 0; | ||||
| } | ||||
| 
 | ||||
| #if not __disable_thread_local_storage | ||||
| struct tls_index | ||||
| { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue