symbian-qemu-0.9.1-12/python-2.6.1/Python/thread_atheos.h
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /* Threading for AtheOS.
       
     2    Based on thread_beos.h. */
       
     3 
       
     4 #include <atheos/threads.h>
       
     5 #include <atheos/semaphore.h>
       
     6 #include <atheos/atomic.h>
       
     7 #include <errno.h>
       
     8 #include <string.h>
       
     9 
       
    10 /* Missing decl from threads.h */
       
    11 extern int exit_thread(int);
       
    12 
       
    13 
       
    14 /* Undefine FASTLOCK to play with simple semaphores. */
       
    15 #define FASTLOCK
       
    16 
       
    17 
       
    18 #ifdef FASTLOCK
       
    19 
       
    20 /* Use an atomic counter and a semaphore for maximum speed. */
       
    21 typedef struct fastmutex {
       
    22 	sem_id sem;
       
    23 	atomic_t count;
       
    24 } fastmutex_t;
       
    25 
       
    26 
       
    27 static int fastmutex_create(const char *name, fastmutex_t * mutex);
       
    28 static int fastmutex_destroy(fastmutex_t * mutex);
       
    29 static int fastmutex_lock(fastmutex_t * mutex);
       
    30 static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout);
       
    31 static int fastmutex_unlock(fastmutex_t * mutex);
       
    32 
       
    33 
       
    34 static int fastmutex_create(const char *name, fastmutex_t * mutex)
       
    35 {
       
    36 	mutex->count = 0;
       
    37 	mutex->sem = create_semaphore(name, 0, 0);
       
    38 	return (mutex->sem < 0) ? -1 : 0;
       
    39 }
       
    40 
       
    41 
       
    42 static int fastmutex_destroy(fastmutex_t * mutex)
       
    43 {
       
    44 	if (fastmutex_timedlock(mutex, 0) == 0 || errno == EWOULDBLOCK) {
       
    45 		return delete_semaphore(mutex->sem);
       
    46 	}
       
    47 	return 0;
       
    48 }
       
    49 
       
    50 
       
    51 static int fastmutex_lock(fastmutex_t * mutex)
       
    52 {
       
    53 	atomic_t prev = atomic_add(&mutex->count, 1);
       
    54 	if (prev > 0)
       
    55 		return lock_semaphore(mutex->sem);
       
    56 	return 0;
       
    57 }
       
    58 
       
    59 
       
    60 static int fastmutex_timedlock(fastmutex_t * mutex, bigtime_t timeout)
       
    61 {
       
    62 	atomic_t prev = atomic_add(&mutex->count, 1);
       
    63 	if (prev > 0)
       
    64 		return lock_semaphore_x(mutex->sem, 1, 0, timeout);
       
    65 	return 0;
       
    66 }
       
    67 
       
    68 
       
    69 static int fastmutex_unlock(fastmutex_t * mutex)
       
    70 {
       
    71 	atomic_t prev = atomic_add(&mutex->count, -1);
       
    72 	if (prev > 1)
       
    73 		return unlock_semaphore(mutex->sem);
       
    74 	return 0;
       
    75 }
       
    76 
       
    77 
       
    78 #endif				/* FASTLOCK */
       
    79 
       
    80 
       
    81 /*
       
    82  * Initialization.
       
    83  *
       
    84  */
       
    85 static void PyThread__init_thread(void)
       
    86 {
       
    87 	/* Do nothing. */
       
    88 	return;
       
    89 }
       
    90 
       
    91 
       
    92 /*
       
    93  * Thread support.
       
    94  *
       
    95  */
       
    96 
       
    97 static atomic_t thread_count = 0;
       
    98 
       
    99 long PyThread_start_new_thread(void (*func) (void *), void *arg)
       
   100 {
       
   101 	status_t success = -1;
       
   102 	thread_id tid;
       
   103 	char name[OS_NAME_LENGTH];
       
   104 	atomic_t this_thread;
       
   105 
       
   106 	dprintf(("PyThread_start_new_thread called\n"));
       
   107 
       
   108 	this_thread = atomic_add(&thread_count, 1);
       
   109 	PyOS_snprintf(name, sizeof(name), "python thread (%d)", this_thread);
       
   110 
       
   111 	tid = spawn_thread(name, func, NORMAL_PRIORITY, 0, arg);
       
   112 	if (tid < 0) {
       
   113 		dprintf(("PyThread_start_new_thread spawn_thread failed: %s\n", strerror(errno)));
       
   114 	} else {
       
   115 		success = resume_thread(tid);
       
   116 		if (success < 0) {
       
   117 			dprintf(("PyThread_start_new_thread resume_thread failed: %s\n", strerror(errno)));
       
   118 		}
       
   119 	}
       
   120 
       
   121 	return (success < 0 ? -1 : tid);
       
   122 }
       
   123 
       
   124 
       
   125 long PyThread_get_thread_ident(void)
       
   126 {
       
   127 	return get_thread_id(NULL);
       
   128 }
       
   129 
       
   130 
       
   131 static void do_PyThread_exit_thread(int no_cleanup)
       
   132 {
       
   133 	dprintf(("PyThread_exit_thread called\n"));
       
   134 
       
   135 	/* Thread-safe way to read a variable without a mutex: */
       
   136 	if (atomic_add(&thread_count, 0) == 0) {
       
   137 		/* No threads around, so exit main(). */
       
   138 		if (no_cleanup)
       
   139 			_exit(0);
       
   140 		else
       
   141 			exit(0);
       
   142 	} else {
       
   143 		/* We're a thread */
       
   144 		exit_thread(0);
       
   145 	}
       
   146 }
       
   147 
       
   148 
       
   149 void PyThread_exit_thread(void)
       
   150 {
       
   151 	do_PyThread_exit_thread(0);
       
   152 }
       
   153 
       
   154 
       
   155 void PyThread__exit_thread(void)
       
   156 {
       
   157 	do_PyThread_exit_thread(1);
       
   158 }
       
   159 
       
   160 
       
   161 #ifndef NO_EXIT_PROG
       
   162 static void do_PyThread_exit_prog(int status, int no_cleanup)
       
   163 {
       
   164 	dprintf(("PyThread_exit_prog(%d) called\n", status));
       
   165 
       
   166 	/* No need to do anything, the threads get torn down if main()exits. */
       
   167 	if (no_cleanup)
       
   168 		_exit(status);
       
   169 	else
       
   170 		exit(status);
       
   171 }
       
   172 
       
   173 
       
   174 void PyThread_exit_prog(int status)
       
   175 {
       
   176 	do_PyThread_exit_prog(status, 0);
       
   177 }
       
   178 
       
   179 
       
   180 void PyThread__exit_prog(int status)
       
   181 {
       
   182 	do_PyThread_exit_prog(status, 1);
       
   183 }
       
   184 #endif				/* NO_EXIT_PROG */
       
   185 
       
   186 
       
   187 /*
       
   188  * Lock support.
       
   189  *
       
   190  */
       
   191 
       
   192 static atomic_t lock_count = 0;
       
   193 
       
   194 PyThread_type_lock PyThread_allocate_lock(void)
       
   195 {
       
   196 #ifdef FASTLOCK
       
   197 	fastmutex_t *lock;
       
   198 #else
       
   199 	sem_id sema;
       
   200 #endif
       
   201 	char name[OS_NAME_LENGTH];
       
   202 	atomic_t this_lock;
       
   203 
       
   204 	dprintf(("PyThread_allocate_lock called\n"));
       
   205 
       
   206 #ifdef FASTLOCK
       
   207 	lock = (fastmutex_t *) malloc(sizeof(fastmutex_t));
       
   208 	if (lock == NULL) {
       
   209 		dprintf(("PyThread_allocate_lock failed: out of memory\n"));
       
   210 		return (PyThread_type_lock) NULL;
       
   211 	}
       
   212 #endif
       
   213 	this_lock = atomic_add(&lock_count, 1);
       
   214 	PyOS_snprintf(name, sizeof(name), "python lock (%d)", this_lock);
       
   215 
       
   216 #ifdef FASTLOCK
       
   217 	if (fastmutex_create(name, lock) < 0) {
       
   218 		dprintf(("PyThread_allocate_lock failed: %s\n",
       
   219 			 strerror(errno)));
       
   220 		free(lock);
       
   221 		lock = NULL;
       
   222 	}
       
   223 	dprintf(("PyThread_allocate_lock()-> %p\n", lock));
       
   224 	return (PyThread_type_lock) lock;
       
   225 #else
       
   226 	sema = create_semaphore(name, 1, 0);
       
   227 	if (sema < 0) {
       
   228 		dprintf(("PyThread_allocate_lock failed: %s\n",
       
   229 			 strerror(errno)));
       
   230 		sema = 0;
       
   231 	}
       
   232 	dprintf(("PyThread_allocate_lock()-> %p\n", sema));
       
   233 	return (PyThread_type_lock) sema;
       
   234 #endif
       
   235 }
       
   236 
       
   237 
       
   238 void PyThread_free_lock(PyThread_type_lock lock)
       
   239 {
       
   240 	dprintf(("PyThread_free_lock(%p) called\n", lock));
       
   241 
       
   242 #ifdef FASTLOCK
       
   243 	if (fastmutex_destroy((fastmutex_t *) lock) < 0) {
       
   244 		dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
       
   245 			 strerror(errno)));
       
   246 	}
       
   247 	free(lock);
       
   248 #else
       
   249 	if (delete_semaphore((sem_id) lock) < 0) {
       
   250 		dprintf(("PyThread_free_lock(%p) failed: %s\n", lock,
       
   251 			 strerror(errno)));
       
   252 	}
       
   253 #endif
       
   254 }
       
   255 
       
   256 
       
   257 int PyThread_acquire_lock(PyThread_type_lock lock, int waitflag)
       
   258 {
       
   259 	int retval;
       
   260 
       
   261 	dprintf(("PyThread_acquire_lock(%p, %d) called\n", lock,
       
   262 		 waitflag));
       
   263 
       
   264 #ifdef FASTLOCK
       
   265 	if (waitflag)
       
   266 		retval = fastmutex_lock((fastmutex_t *) lock);
       
   267 	else
       
   268 		retval = fastmutex_timedlock((fastmutex_t *) lock, 0);
       
   269 #else
       
   270 	if (waitflag)
       
   271 		retval = lock_semaphore((sem_id) lock);
       
   272 	else
       
   273 		retval = lock_semaphore_x((sem_id) lock, 1, 0, 0);
       
   274 #endif
       
   275 	if (retval < 0) {
       
   276 		dprintf(("PyThread_acquire_lock(%p, %d) failed: %s\n",
       
   277 			 lock, waitflag, strerror(errno)));
       
   278 	}
       
   279 	dprintf(("PyThread_acquire_lock(%p, %d)-> %d\n", lock, waitflag,
       
   280 		 retval));
       
   281 	return retval < 0 ? 0 : 1;
       
   282 }
       
   283 
       
   284 
       
   285 void PyThread_release_lock(PyThread_type_lock lock)
       
   286 {
       
   287 	dprintf(("PyThread_release_lock(%p) called\n", lock));
       
   288 
       
   289 #ifdef FASTLOCK
       
   290 	if (fastmutex_unlock((fastmutex_t *) lock) < 0) {
       
   291 		dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
       
   292 			 strerror(errno)));
       
   293 	}
       
   294 #else
       
   295 	if (unlock_semaphore((sem_id) lock) < 0) {
       
   296 		dprintf(("PyThread_release_lock(%p) failed: %s\n", lock,
       
   297 			 strerror(errno)));
       
   298 	}
       
   299 #endif
       
   300 }