aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJoel Bodenmann <joel@unormal.org>2014-09-29 08:08:36 +0200
committerJoel Bodenmann <joel@unormal.org>2014-09-29 08:08:36 +0200
commit32a4969b7d4d92b1d40e60fae676d798bacb780f (patch)
tree9607d00476bff7fe4fc1f5cc4c3f261ca7d5c6bf /src
parent1e8a7ff6ddb5bb9accaf2918c98667427aa1b6b3 (diff)
parent611133cbc0d55f9dd570cfbccbe432ccc63a12aa (diff)
downloaduGFX-32a4969b7d4d92b1d40e60fae676d798bacb780f.tar.gz
uGFX-32a4969b7d4d92b1d40e60fae676d798bacb780f.tar.bz2
uGFX-32a4969b7d4d92b1d40e60fae676d798bacb780f.zip
Merge branch 'newmouse' of bitbucket.org:Tectu/ugfx into newmouse
Diffstat (limited to 'src')
-rw-r--r--src/gos/gos_linux.c171
-rw-r--r--src/gos/gos_linux.h31
-rw-r--r--src/gos/gos_osx.c42
-rw-r--r--src/gwin/gwin_progressbar.c41
-rw-r--r--src/gwin/gwin_progressbar.h7
5 files changed, 166 insertions, 126 deletions
diff --git a/src/gos/gos_linux.c b/src/gos/gos_linux.c
index fc716ec9..e6fbe26c 100644
--- a/src/gos/gos_linux.c
+++ b/src/gos/gos_linux.c
@@ -14,8 +14,6 @@
#include <stdio.h>
#include <unistd.h>
-#include <errno.h>
-#include <sys/time.h>
#include <time.h>
#if USE_SCHED_NOT_PTHREAD_YIELD
#include <sched.h>
@@ -70,16 +68,16 @@ void gfxSleepMilliseconds(delaytime_t ms) {
default:
ts.tv_sec = ms / 1000;
- ts.tv_nsec = (ms % 1000) * 1000;
+ ts.tv_nsec = (ms % 1000) * 1000000;
nanosleep(&ts, 0);
return;
}
}
-void gfxSleepMicroseconds(delaytime_t ms) {
+void gfxSleepMicroseconds(delaytime_t us) {
struct timespec ts;
- switch(ms) {
+ switch(us) {
case TIME_IMMEDIATE:
linuxyield();
return;
@@ -90,8 +88,8 @@ void gfxSleepMicroseconds(delaytime_t ms) {
return;
default:
- ts.tv_sec = ms / 1000000;
- ts.tv_nsec = ms % 1000000;
+ ts.tv_sec = us / 1000000;
+ ts.tv_nsec = (us % 1000000) * 1000;
nanosleep(&ts, 0);
return;
}
@@ -101,8 +99,7 @@ systemticks_t gfxSystemTicks(void) {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
-
- return ts.tv_sec * 1000UL + ts.tv_nsec / 1000UL;
+ return ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
}
gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param) {
@@ -133,81 +130,119 @@ threadreturn_t gfxThreadWait(gfxThreadHandle thread) {
return retval;
}
-void gfxSemInit(gfxSem *pSem, semcount_t val, semcount_t limit) {
- pthread_mutex_init(&pSem->mtx, 0);
- pthread_cond_init(&pSem->cond, 0);
- pthread_mutex_lock(&pSem->mtx);
- pSem->cnt = val;
- pSem->max = limit;
- pthread_mutex_unlock(&pSem->mtx);
-}
-
-void gfxSemDestroy(gfxSem *pSem) {
- pthread_mutex_destroy(&pSem->mtx);
- pthread_cond_destroy(&pSem->cond);
-}
-
-bool_t gfxSemWait(gfxSem *pSem, delaytime_t ms) {
- pthread_mutex_lock(&pSem->mtx);
-
- switch (ms) {
+#if GFX_USE_POSIX_SEMAPHORES
+ void gfxSemInit(gfxSem *pSem, semcount_t val, semcount_t limit) {
+ pSem->max = limit;
+ sem_init(&pSem->sem, 0, val);
+ }
+ void gfxSemDestroy(gfxSem *pSem) {
+ sem_destroy(&pSem->sem);
+ }
+ bool_t gfxSemWait(gfxSem *pSem, delaytime_t ms) {
+ switch (ms) {
case TIME_INFINITE:
- while (!pSem->cnt)
- pthread_cond_wait(&pSem->cond, &pSem->mtx);
- break;
+ return sem_wait(&pSem->sem) ? FALSE : TRUE;
case TIME_IMMEDIATE:
- if (!pSem->cnt) {
- pthread_mutex_unlock(&pSem->mtx);
- return FALSE;
- }
- break;
+ return sem_trywait(&pSem->sem) ? FALSE : TRUE;
default:
{
- struct timeval now;
struct timespec tm;
- gettimeofday(&now, 0);
- tm.tv_sec = now.tv_sec + ms / 1000;
- tm.tv_nsec = (now.tv_usec + ms % 1000) * 1000;
- while (!pSem->cnt) {
- if (pthread_cond_timedwait(&pSem->cond, &pSem->mtx, &tm) == ETIMEDOUT) {
- pthread_mutex_unlock(&pSem->mtx);
- return FALSE;
- }
- }
+ clock_gettime(CLOCK_REALTIME, &tm);
+ tm.tv_sec += ms / 1000;
+ tm.tv_nsec += (ms % 1000) * 1000000;
+ return sem_timedwait(&pSem->sem, &tm) ? FALSE : TRUE;
}
- break;
+ }
}
+ void gfxSemSignal(gfxSem *pSem) {
+ if (gfxSemCounter(pSem) < pSem->max)
+ sem_post(&pSem->sem);
+ }
+ semcount_t gfxSemCounter(gfxSem *pSem) {
+ int res;
- pSem->cnt--;
- pthread_mutex_unlock(&pSem->mtx);
-
- return TRUE;
-}
-
-void gfxSemSignal(gfxSem *pSem) {
- pthread_mutex_lock(&pSem->mtx);
+ res = 0;
+ sem_getvalue(&pSem->sem, &res);
+ return res;
+ }
+#else
+ void gfxSemInit(gfxSem *pSem, semcount_t val, semcount_t limit) {
+ pthread_mutex_init(&pSem->mtx, 0);
+ pthread_cond_init(&pSem->cond, 0);
+ pthread_mutex_lock(&pSem->mtx);
+ pSem->cnt = val;
+ pSem->max = limit;
+ pthread_mutex_unlock(&pSem->mtx);
+ }
+ void gfxSemDestroy(gfxSem *pSem) {
+ pthread_mutex_destroy(&pSem->mtx);
+ pthread_cond_destroy(&pSem->cond);
+ }
+ bool_t gfxSemWait(gfxSem *pSem, delaytime_t ms) {
+ pthread_mutex_lock(&pSem->mtx);
+
+ switch (ms) {
+ case TIME_INFINITE:
+ while (!pSem->cnt)
+ pthread_cond_wait(&pSem->cond, &pSem->mtx);
+ break;
+
+ case TIME_IMMEDIATE:
+ if (!pSem->cnt) {
+ pthread_mutex_unlock(&pSem->mtx);
+ return FALSE;
+ }
+ break;
+
+ default:
+ {
+ struct timespec tm;
+
+ clock_gettime(CLOCK_REALTIME, &tm);
+ tm.tv_sec += ms / 1000;
+ tm.tv_nsec += (ms % 1000) * 1000000;
+ while (!pSem->cnt) {
+ // We used to test the return value for ETIMEDOUT. This doesn't
+ // work in some current pthread libraries which return -1 instead
+ // and set errno to ETIMEDOUT. So, we will return FALSE on any error
+ // including a ETIMEDOUT.
+ if (pthread_cond_timedwait(&pSem->cond, &pSem->mtx, &tm)) {
+ pthread_mutex_unlock(&pSem->mtx);
+ return FALSE;
+ }
+ }
+ }
+ break;
+ }
- if (pSem->cnt < pSem->max) {
- pSem->cnt++;
- pthread_cond_signal(&pSem->cond);
+ pSem->cnt--;
+ pthread_mutex_unlock(&pSem->mtx);
+ return TRUE;
}
+ void gfxSemSignal(gfxSem *pSem) {
+ pthread_mutex_lock(&pSem->mtx);
- pthread_mutex_unlock(&pSem->mtx);
-}
+ if (pSem->cnt < pSem->max) {
+ pSem->cnt++;
+ pthread_cond_signal(&pSem->cond);
+ }
-semcount_t gfxSemCounter(gfxSem *pSem) {
- semcount_t res;
+ pthread_mutex_unlock(&pSem->mtx);
+ }
+ semcount_t gfxSemCounter(gfxSem *pSem) {
+ semcount_t res;
- // The locking is really only required if obtaining the count is a divisible operation
- // which it might be on a 8/16 bit processor with a 32 bit semaphore count.
- pthread_mutex_lock(&pSem->mtx);
- res = pSem->cnt;
- pthread_mutex_unlock(&pSem->mtx);
+ // The locking is really only required if obtaining the count is a divisible operation
+ // which it might be on a 8/16 bit processor with a 32 bit semaphore count.
+ pthread_mutex_lock(&pSem->mtx);
+ res = pSem->cnt;
+ pthread_mutex_unlock(&pSem->mtx);
- return res;
-}
+ return res;
+ }
+#endif // GFX_USE_POSIX_SEMAPHORES
#endif /* GFX_USE_OS_LINUX */
diff --git a/src/gos/gos_linux.h b/src/gos/gos_linux.h
index bd31184e..39cfbc85 100644
--- a/src/gos/gos_linux.h
+++ b/src/gos/gos_linux.h
@@ -10,11 +10,20 @@
#if GFX_USE_OS_LINUX
+// We don't put this in the general sys_options.h as it is Linux specific.
+#ifndef GFX_USE_POSIX_SEMAPHORES
+ #define GFX_USE_POSIX_SEMAPHORES TRUE
+#endif
+
#include <sys/types.h>
#include <stdlib.h>
#include <stdint.h>
#include <pthread.h>
+#if GFX_USE_POSIX_SEMAPHORES
+ #include <semaphore.h>
+#endif
+
/* Already defined int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, size_t */
typedef int8_t bool_t;
@@ -42,7 +51,6 @@ typedef pthread_mutex_t gfxMutex;
#define gfxMutexExit(pmtx) pthread_mutex_unlock(pmtx)
#define gfxSemWaitI(psem) gfxSemWait(psem, TIME_IMMEDIATE)
#define gfxSemSignalI(psem) gfxSemSignal(psem)
-#define gfxSemCounterI(pSem) ((pSem)->cnt)
#define TIME_IMMEDIATE 0
#define TIME_INFINITE ((delaytime_t)-1)
@@ -51,12 +59,21 @@ typedef pthread_mutex_t gfxMutex;
#define NORMAL_PRIORITY 0
#define HIGH_PRIORITY -10
-typedef struct gfxSem {
- pthread_mutex_t mtx;
- pthread_cond_t cond;
- semcount_t cnt;
- semcount_t max;
-} gfxSem;
+#if GFX_USE_POSIX_SEMAPHORES
+ typedef struct gfxSem {
+ sem_t sem;
+ semcount_t max;
+ } gfxSem;
+ #define gfxSemCounterI(psem) gfxSemCounter(psem)
+#else
+ typedef struct gfxSem {
+ pthread_mutex_t mtx;
+ pthread_cond_t cond;
+ semcount_t cnt;
+ semcount_t max;
+ } gfxSem;
+ #define gfxSemCounterI(psem) ((psem)->cnt)
+#endif
/*===========================================================================*/
/* Function declarations. */
diff --git a/src/gos/gos_osx.c b/src/gos/gos_osx.c
index f2e58f77..f21b8a75 100644
--- a/src/gos/gos_osx.c
+++ b/src/gos/gos_osx.c
@@ -21,18 +21,6 @@
static gfxMutex SystemMutex;
-
-void get_ticks(mach_timespec_t *mts){
- clock_serv_t cclock;
- //mach_timespec_t mts;
-
- host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
- clock_get_time(cclock, mts);
- mach_port_deallocate(mach_task_self(), cclock);
-
-
-}
-
void _gosInit(void)
{
/* No initialization of the operating system itself is needed */
@@ -66,35 +54,35 @@ void gfxSleepMilliseconds(delaytime_t ms) {
case TIME_INFINITE: while(1) sleep(60); return;
default:
ts.tv_sec = ms / 1000;
- ts.tv_nsec = (ms % 1000) * 1000;
+ ts.tv_nsec = (ms % 1000) * 1000000;
nanosleep(&ts, 0);
return;
}
}
-void gfxSleepMicroseconds(delaytime_t ms) {
+void gfxSleepMicroseconds(delaytime_t us) {
struct timespec ts;
- switch(ms) {
+ switch(us) {
case TIME_IMMEDIATE: gfxYield(); return;
case TIME_INFINITE: while(1) sleep(60); return;
default:
- ts.tv_sec = ms / 1000000;
- ts.tv_nsec = ms % 1000000;
+ ts.tv_sec = us / 1000000;
+ ts.tv_nsec = (us % 1000000) * 1000;
nanosleep(&ts, 0);
return;
}
}
systemticks_t gfxSystemTicks(void) {
- //struct timespec ts;
- //clock_gettime(CLOCK_MONOTONIC, &ts);
-
- mach_timespec_t ts;
- get_ticks(&ts);
+ mach_timespec_t ts;
+ clock_serv_t cclock;
+ host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock);
+ clock_get_time(cclock, &ts);
+ mach_port_deallocate(mach_task_self(), cclock);
- return ts.tv_sec * 1000UL + ts.tv_nsec / 1000UL;
+ return ts.tv_sec * 1000UL + ts.tv_nsec / 1000000;
}
gfxThreadHandle gfxThreadCreate(void *stackarea, size_t stacksz, threadpriority_t prio, DECLARE_THREAD_FUNCTION((*fn),p), void *param) {
@@ -157,9 +145,13 @@ bool_t gfxSemWait(gfxSem *pSem, delaytime_t ms) {
gettimeofday(&now, 0);
tm.tv_sec = now.tv_sec + ms / 1000;
- tm.tv_nsec = (now.tv_usec + ms % 1000) * 1000;
+ tm.tv_nsec = now.tv_usec * 1000 + (ms % 1000) * 1000000;
while (!pSem->cnt) {
- if (pthread_cond_timedwait(&pSem->cond, &pSem->mtx, &tm) == ETIMEDOUT) {
+ // We used to test the return value for ETIMEDOUT. This doesn't
+ // work in some current pthread libraries which return -1 instead
+ // and set errno to ETIMEDOUT. So, we will return FALSE on any error
+ // including a ETIMEDOUT.
+ if (pthread_cond_timedwait(&pSem->cond, &pSem->mtx, &tm)) {
pthread_mutex_unlock(&pSem->mtx);
return FALSE;
}
diff --git a/src/gwin/gwin_progressbar.c b/src/gwin/gwin_progressbar.c
index ef28e8dc..d5b8721a 100644
--- a/src/gwin/gwin_progressbar.c
+++ b/src/gwin/gwin_progressbar.c
@@ -79,13 +79,12 @@ GHandle gwinGProgressbarCreate(GDisplay *g, GProgressbarObject *gs, const GWidge
gs->pos = 0;
#if GWIN_PROGRESSBAR_AUTO
- gs->delay = 0;
gtimerInit(&gs->gt);
#endif
ResetDisplayPos(gs);
gwinSetVisible((GHandle)gs, pInit->g.show);
-
+
return (GHandle)gs;
}
@@ -183,39 +182,37 @@ void gwinProgressbarDecrement(GHandle gh) {
static void _progressbarCallback(void *param) {
#define gsw ((GProgressbarObject *)gh)
GHandle gh = (GHandle)param;
-
+
if (gh->vmt != (gwinVMT *)&progressbarVMT)
return;
-
+
gwinProgressbarIncrement(gh);
-
- if (gsw->pos < gsw->max)
- gtimerStart(&(gsw->gt), _progressbarCallback, gh, FALSE, gsw->delay);
-
- #undef gsw
+
+ if (gsw->pos >= gsw->max)
+ gtimerStop(&gsw->gt);
+
+ #undef gsw
}
-
+
void gwinProgressbarStart(GHandle gh, delaytime_t delay) {
#define gsw ((GProgressbarObject *)gh)
-
+
if (gh->vmt != (gwinVMT *)&progressbarVMT)
return;
-
- gsw->delay = delay;
-
- gtimerStart(&(gsw->gt), _progressbarCallback, gh, FALSE, gsw->delay);
-
+
+ gtimerStart(&gsw->gt, _progressbarCallback, gh, TRUE, delay);
+
#undef gsw
}
-
+
void gwinProgressbarStop(GHandle gh) {
#define gsw ((GProgressbarObject *)gh)
-
+
if (gh->vmt != (gwinVMT *)&progressbarVMT)
return;
-
- gtimerStop(&(gsw->gt));
-
+
+ gtimerStop(&gsw->gt);
+
#undef gsw
}
#endif /* GWIN_PROGRESSBAR_AUTO */
@@ -226,7 +223,7 @@ void gwinProgressbarDecrement(GHandle gh) {
void gwinProgressbarDraw_Std(GWidgetObject *gw, void *param) {
#define gsw ((GProgressbarObject *)gw)
-
+
const GColorSet * pcol;
(void) param;
diff --git a/src/gwin/gwin_progressbar.h b/src/gwin/gwin_progressbar.h
index 49c11a98..dae9d40a 100644
--- a/src/gwin/gwin_progressbar.h
+++ b/src/gwin/gwin_progressbar.h
@@ -33,7 +33,6 @@ typedef struct GProgressbarObject {
int pos;
#if GWIN_PROGRESSBAR_AUTO
GTimer gt;
- delaytime_t delay;
#endif
} GProgressbarObject;
@@ -59,7 +58,7 @@ extern "C" {
* @note A progressbar does not take any GINPUT inputs.
*
* @api
- */
+ */
GHandle gwinGProgressbarCreate(GDisplay *g, GProgressbarObject *gb, const GWidgetInit *pInit);
#define gwinProgressbarCreate(w, pInit) gwinGProgressbarCreate(GDISP, w, pInit)
@@ -165,14 +164,14 @@ void gwinProgressbarDecrement(GHandle gh);
* @api
*/
void gwinProgressbarStart(GHandle gh, delaytime_t delay);
-
+
/**
* @brief Stop the timer which is started by @p gwinProgressbarStart()
*
* @param[in] gh The window handle (must be a progressbar window)
*
* @api
- */
+ */
void gwinProgressbarStop(GHandle gh);
#endif /* GWIN_PROGRESSBAR_AUTO */