#ifndef __SCHEDULE_H
#define __SCHEDULE_H

/*
 *  Wrapper macros for scheduler
 *  Copyright (c) by Jaroslav Kysela <perex@jcu.cz>
 *
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

#ifdef __QNXNTO__

#define snd_sleep_define( ident )			pthread_cond_t cond_##ident;\
											int errno_##ident
#define snd_wakeup(  object, ident )		do { pthread_cond_signal( &object->cond_##ident );object->errno_##ident = errno;}while(0)
#define snd_sleep( object, ident, mutex, to )    do { struct timespec t;\
										    memset(&t, 0, sizeof t);\
											t.tv_sec = time(0) + to; \
											t.tv_nsec = 0; \
 											object->errno_##ident = pthread_cond_timedwait( &object->cond_##ident, &object->mutex_##mutex, &t);\
											} while(0)
#define snd_sleep_abort(object, ident)		(object->errno_##ident == EINTR)
#define snd_timeout(object, ident)			(object->errno_##ident == ETIMEDOUT)
#define snd_sleep_prepare(object, ident)	pthread_cond_init(&object->cond_##ident, NULL)
#define snd_sleep_destroy(object, ident)	pthread_cond_destroy(&object->cond_##ident)
/* mutex */
#define snd_mutex_define( ident )			pthread_mutex_t mutex_##ident
#if 1
#define snd_mutex_prepare( object, ident )  pthread_mutex_init( &object->mutex_##ident, NULL)
#define snd_mutex_destroy( object, ident )  pthread_mutex_destroy( &object->mutex_##ident)
#define snd_mutex_lock( object, ident )		pthread_mutex_lock( &object->mutex_##ident )
#define snd_mutex_unlock( object, ident )	pthread_mutex_unlock( &object->mutex_##ident)
#else
#define snd_mutex_prepare( object, ident )  do { int e; if ((e = pthread_mutex_init( &object->mutex_##ident, NULL)) != 0 ) { errno = e; perror("mutex init "#ident);}\
											snd_printd("mutex init of %s %p\n",#object"_"#ident, &object->mutex_##ident);}while(0)
#define snd_mutex_destroy( object, ident )  do { int e; if ((e = pthread_mutex_destroy( &object->mutex_##ident)) != 0 ) { errno = e; perror("mutex destroy "#ident);}\
											snd_printd("mutex destroy of %s %p\n",#object"_"#ident, &object->mutex_##ident);}while(0)
#define snd_mutex_lock( object, ident )		do { pthread_mutex_lock( &object->mutex_##ident ); snd_printd("mutex_"#ident " - locked\n");\
											} while(0)
#define snd_mutex_unlock( object, ident )	do { pthread_mutex_unlock( &object->mutex_##ident);snd_printd("mutex_"#ident "- unlock\n");\
											} while(0)
#endif
#define snd_mutex_define_static( ident )	static pthread_mutex_t mutex_##ident = PTHREAD_MUTEX_INITIALIZER
#define snd_mutex_lock_static( ident )		pthread_mutex_lock( &mutex_##ident )
#define snd_mutex_unlock_static( ident )	pthread_mutex_unlock( &mutex_##ident)

#else

#define snd_sleep_define(ident) sleep_entity_t sleep_##ident

#define snd_sleep_prepare(object, ident) \
                        do { \
                          memset(&object->sleep_##ident, 0, sizeof(sleep_entity_t)); \
                          object->sleep_##ident.wchan = ++WCHAN; \
                          object->sleep_##ident.func = proxy_callback; \
			} while(0)



#define snd_sleep(object, ident, mutex, to) \
                                do { \
                                        snd_mutex_unlock(object, mutex); \
                                        put_to_sleep(&object->sleep_##ident, to); \
                                        snd_mutex_lock(object, mutex); \
					} while(0)

#define snd_wakeup(object, ident) \
                                do { \
                                        wake_up_sleeper(&object->sleep_##ident); \
					} while(0)

#define snd_sleep_destroy(object, ident)

#define snd_mutex_define(ident)                 sem_t sem_##ident
#define snd_mutex_prepare(object, ident)        do { \
                                                     /*printf("Mutex init: sem_"#ident "\n");*/  \
                                                     sem_init(&object->sem_##ident, 1, 1); \
						     } while (0)
#define snd_mutex_destroy(object, ident)        sem_destroy(&object->sem_##ident)
#define snd_mutex_lock(object, ident)           do { \
                                                      /*printf("Mutex Lock: sem_"#ident ": %d\n", getpid());*/  \
                                                     sem_wait(&object->sem_##ident); \
						     } while (0)

#define snd_mutex_unlock(object, ident)         do { \
                                                     /*printf("Mutex Unlock: sem_"#ident ":%d\n", getpid());*/  \
                                                     sem_post(&object->sem_##ident); \
						     } while (0)
#define snd_mutex_define_static(ident)
#define snd_mutex_lock_static(ident)
#define snd_mutex_unlock_static(ident)
#define snd_sleep_abort(object, ident)		((object->sleep_##ident).timedout == ETIMEDOUT) 
#define snd_timeout(object, ident) 		((object->sleep_##ident).timedout == ETIMEDOUT)

#endif

#endif				/* __SCHEDULE_H */



