/**************************************************************************** * * Copyright (c) 2001 Novell, Inc. All Rights Reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * * 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, contact Novell, Inc. * * To contact Novell about this file by physical or electronic mail, you * may find current contact information at www.novell.com. * |***************************************************************************/ #ifndef XPLTHREAD_H #define XPLTHREAD_H #ifdef HAVE_SEMAPHORE_H #include #endif typedef struct { int counter; } XplAtomic; /* this can be optimized so that it uses inc for 1, etc, but there is no real * reason to do that * * also, you could make a non-smp build that did not do lock */ static __inline__ void _XplSafeAdd (int i, XplAtomic *v) { (void)__atomic_fetch_add(&v->counter, i, __ATOMIC_SEQ_CST); } static __inline__ int _XplSafeRead (const XplAtomic *v) { return __atomic_load_n(&v->counter, __ATOMIC_SEQ_CST); } static __inline__ void _XplSafeWrite (XplAtomic *v, int value) { __atomic_store_n(&v->counter, value, __ATOMIC_SEQ_CST); } static __inline__ void _XplSafeOr (XplAtomic *v, int value) { (void)__atomic_fetch_or(&v->counter, value, __ATOMIC_SEQ_CST); } static __inline__ void _XplSafeAnd (XplAtomic *v, int value) { (void)__atomic_fetch_and(&v->counter, value, __ATOMIC_SEQ_CST); } #define XplSafeRead(Variable) _XplSafeRead(&(Variable)) #define XplSafeWrite(Variable, Value) _XplSafeWrite(&(Variable), (Value)) #define XplSafeOr(Variable, Value) _XplSafeOr(&(Variable), (Value)) #define XplSafeAnd(Variable, Value) _XplSafeAnd(&(Variable), (Value)) #define XplSafeIncrement(Variable) XplSafeAdd (Variable, 1) #define XplSafeAdd(Variable, Value) _XplSafeAdd((Value), &(Variable)) #define XplSafeDecrement(Variable) XplSafeAdd (Variable, -1) #define XplSafeSub(Variable, Value) XplSafeAdd (Variable, -(Value)) #define XplThreadSwitchWithDelay() /* Thread Groups */ #define XplThreadID pthread_t #define XplGetThreadGroupID() getpid() /* POSIX builds have one process-wide thread group. The legacy macro wrote * to its argument, racing when multiple listener threads shut down. */ static __inline__ XplThreadID _XplSetThreadGroupID(XplThreadID thread) { (void)thread; return (XplThreadID)1; } #define XplSetThreadGroupID(thread) _XplSetThreadGroupID(thread) #define XplGetThreadID() pthread_self() #define XplSetThreadID(thread) /* Threads */ #define XplBeginThread(pID, func, stack, args, ret) { pthread_attr_t thread_attr; \ pthread_attr_init(&thread_attr); \ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); \ pthread_attr_setstacksize(&thread_attr, ((stack) * 2)); \ if (((ret) = pthread_create((pID), &thread_attr, (void *)(func), (void *)(args))) == 0) { \ ; \ } else { \ *(pID) = 0; \ } \ pthread_attr_destroy(&thread_attr); \ } #define XplBeginCountedThreadGroup XplBeginCountedThread #define XplBeginCountedThread(pID, func, stack, args, ret, counter) { \ pthread_attr_t thread_attr; \ pthread_attr_init(&thread_attr); \ pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED); \ pthread_attr_setstacksize(&thread_attr, ((stack) * 2)); \ XplSafeIncrement (counter); \ if (((ret) = pthread_create(pID, &thread_attr, (void *)(func), (void *)(args))) == 0) { \ ; \ } else { \ *(pID) = 0; \ XplSafeDecrement (counter); \ } \ pthread_attr_destroy(&thread_attr); \ } #define XplExitThread(code, status) pthread_exit((void *)status) #define XplSuspendThread(id) ; #define XplResumeThread(id) ; #define XplRenameThread(id, Name) ; #define XplMutex pthread_mutex_t #define XplMutexInit(m) pthread_mutex_init(&(m), 0); #define XplMutexLock(m) pthread_mutex_lock(&(m)); #define XplMutexTryLock(m) pthread_mutex_trylock(&(m)); #define XplMutexUnlock(m) pthread_mutex_unlock(&(m)); #define XplMutexDestroy(m) pthread_mutex_destroy(&(m)); #define XplSemaphore sem_t #define XplOpenLocalSemaphore(sem, init) sem_init(&(sem), 0, init) #define XplCloseLocalSemaphore(sem) sem_destroy(&(sem)) #define XplWaitOnLocalSemaphore(sem) sem_wait(&(sem)) #define XplSignalLocalSemaphore(sem) sem_post(&(sem)) #define XplExamineLocalSemaphore(sem, cnt) sem_getvalue(&(sem), (int *)&(cnt)) #endif