 d3d33afe9f
			
		
	
	
		d3d33afe9f
		
	
	
	
	
		
			
			This patch adds pthread compatibility by using libmthread. To use this with a program using pthreads, you have to replace #include <pthread> with #define _MTHREADIFY_PTHREADS #include <minix/mthreads> This also changes the initialization function to be a constructor, which is implicitly called before the call to main. This allows for conformance with pthreads, while not paying a high price by checking on each mthread_* call whether the library has been initialized or not. As mthread_init is now a constructor, it also has been set as static, and relevent calls removed from programs using it. Change-Id: I2aa375db557958d2bee9a70d285aabb990c88f00
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| #include <minix/mthread.h>
 | |
| #include "global.h"
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				mthread_rwlock_init			     *
 | |
|  *===========================================================================*/
 | |
| int mthread_rwlock_init(rwlock)
 | |
| mthread_rwlock_t *rwlock; /* The rwlock to be initialized */
 | |
| {
 | |
|   /* Initialize a readers/writer lock. */
 | |
|   int r;
 | |
| 
 | |
|   if (!rwlock)
 | |
| 	return EINVAL;
 | |
| 
 | |
|   rwlock->writer = NO_THREAD;
 | |
|   rwlock->readers = 0;
 | |
| 
 | |
|   r = mthread_mutex_init(&rwlock->queue, NULL);
 | |
|   if (r != 0)
 | |
| 	return r;
 | |
| 
 | |
|   r = mthread_event_init(&rwlock->drain);
 | |
|   if (r != 0)
 | |
| 	mthread_mutex_destroy(&rwlock->queue);
 | |
| 
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				mthread_rwlock_destroy			     *
 | |
|  *===========================================================================*/
 | |
| int mthread_rwlock_destroy(rwlock)
 | |
| mthread_rwlock_t *rwlock; /* The rwlock to be destroyed */
 | |
| {
 | |
|   /* Destroy a readers/writer lock. */
 | |
|   int r;
 | |
| 
 | |
|   if (!rwlock)
 | |
| 	return EINVAL;
 | |
| 
 | |
|   assert(rwlock->writer == NO_THREAD);
 | |
|   assert(rwlock->readers == 0);
 | |
| 
 | |
|   r = mthread_event_destroy(&rwlock->drain);
 | |
|   if (r != 0)
 | |
| 	return r;
 | |
| 
 | |
|   return mthread_mutex_destroy(&rwlock->queue);
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				mthread_rwlock_rdlock			     *
 | |
|  *===========================================================================*/
 | |
| int mthread_rwlock_rdlock(rwlock)
 | |
| mthread_rwlock_t *rwlock; /* The rwlock to be read locked */
 | |
| {
 | |
|   /* Acquire a reader lock. */
 | |
|   int r;
 | |
| 
 | |
|   if (!rwlock)
 | |
| 	return EINVAL;
 | |
| 
 | |
|   r = mthread_mutex_lock(&rwlock->queue);
 | |
|   if (r != 0)
 | |
| 	return r;
 | |
| 
 | |
|   r = mthread_mutex_unlock(&rwlock->queue);
 | |
|   if (r != 0)
 | |
| 	return r;
 | |
| 
 | |
|   rwlock->readers++;
 | |
| 
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				mthread_rwlock_wrlock			     *
 | |
|  *===========================================================================*/
 | |
| int mthread_rwlock_wrlock(rwlock)
 | |
| mthread_rwlock_t *rwlock; /* The rwlock to be write locked */
 | |
| {
 | |
|   /* Acquire a writer lock. */
 | |
|   int r;
 | |
| 
 | |
|   if (!rwlock)
 | |
| 	  return EINVAL;
 | |
| 
 | |
|   r = mthread_mutex_lock(&rwlock->queue);
 | |
|   if (r != 0)
 | |
| 	return r;
 | |
| 
 | |
|   rwlock->writer = current_thread;
 | |
| 
 | |
|   if (rwlock->readers > 0)
 | |
| 	r = mthread_event_wait(&rwlock->drain);
 | |
| 
 | |
|   if (r == 0)
 | |
| 	assert(rwlock->readers == 0);
 | |
| 
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| /*===========================================================================*
 | |
|  *				mthread_rwlock_unlock				*
 | |
|  *===========================================================================*/
 | |
| int mthread_rwlock_unlock(rwlock)
 | |
| mthread_rwlock_t *rwlock; /* The rwlock to be unlocked */
 | |
| {
 | |
|   /* Release a lock. */
 | |
|   int r;
 | |
| 
 | |
|   r = 0;
 | |
|   if (!rwlock)
 | |
| 	  return EINVAL;
 | |
| 
 | |
|   if (rwlock->writer == current_thread) {
 | |
| 	rwlock->writer = NO_THREAD;
 | |
| 	r = mthread_mutex_unlock(&rwlock->queue);
 | |
|   } else {
 | |
| 	assert(rwlock->readers > 0);
 | |
| 
 | |
| 	rwlock->readers--;
 | |
| 
 | |
| 	if (rwlock->readers == 0 && rwlock->writer != NO_THREAD)
 | |
| 		r = mthread_event_fire(&rwlock->drain);
 | |
|   }
 | |
| 
 | |
|   return r;
 | |
| }
 | |
| 
 | |
| /* pthread compatibility layer. */
 | |
| __weak_alias(pthread_rwlock_destroy, mthread_rwlock_destroy)
 | |
| __weak_alias(pthread_rwlock_rdlock, mthread_rwlock_rdlock)
 | |
| __weak_alias(pthread_rwlock_wrlock, mthread_rwlock_wrlock)
 | |
| __weak_alias(pthread_rwlock_unlock, mthread_rwlock_unlock)
 | |
| 
 |