From 689edfad404b2207fd553e6c273ea9279dd7b5bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrea=20Palmat=C3=A8?= Date: Mon, 27 May 2024 13:40:09 +0200 Subject: [PATCH 1/3] Fixing pthread_timer_cond bug and some time problems --- library/c.lib_rev.h | 6 +-- library/include/time.h | 3 +- library/pthread/common.c | 64 +++++++++++++++++++---------- library/pthread/common.h | 2 +- library/pthread/pthread.c | 80 ++++++++++++++++++++----------------- library/stdio/gets.c | 1 + library/time/gettimeofday.c | 42 +++---------------- library/time/time.c | 19 ++++----- 8 files changed, 106 insertions(+), 111 deletions(-) diff --git a/library/c.lib_rev.h b/library/c.lib_rev.h index 7773d7a9..fc5f947c 100755 --- a/library/c.lib_rev.h +++ b/library/c.lib_rev.h @@ -2,7 +2,7 @@ #define REVISION 0 #define SUBREVISION 0 -#define DATE "23.05.2024" +#define DATE "27.05.2024" #define VERS "clib4.library 1.0.0" -#define VSTRING "clib4.library 1.0.0 (23.05.2024)\r\n" -#define VERSTAG "\0$VER: clib4.library 1.0.0 (23.05.2024)" \ No newline at end of file +#define VSTRING "clib4.library 1.0.0 (27.05.2024)\r\n" +#define VERSTAG "\0$VER: clib4.library 1.0.0 (27.05.2024)" \ No newline at end of file diff --git a/library/include/time.h b/library/include/time.h index 85fece39..3612a3a6 100755 --- a/library/include/time.h +++ b/library/include/time.h @@ -92,7 +92,7 @@ struct timespec64 { /* BSD time macros used by RTEMS code */ /* Convenience macros for operations on timevals. NOTE: `timercmp' does not work for >= or <=. */ -#ifndef __USE_OLD_TIMEVAL__ +#ifdef __USE_OLD_TIMEVAL__ #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) #define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) #define timercmp(a, b, CMP) \ @@ -115,6 +115,7 @@ struct timespec64 { (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ if ((result)->tv_usec < 0) \ { \ + printf("gillo\n"); \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ diff --git a/library/pthread/common.c b/library/pthread/common.c index b1e334b5..819d9981 100644 --- a/library/pthread/common.c +++ b/library/pthread/common.c @@ -74,33 +74,45 @@ pthread_t GetThreadId(struct Task *task) { return i; } -BOOL -OpenTimerDevice(struct IORequest *io, struct MsgPort *mp, struct Task *task) { - BYTE signal; - - // prepare MsgPort - mp->mp_Node.ln_Type = NT_MSGPORT; - mp->mp_Node.ln_Pri = 0; - mp->mp_Node.ln_Name = NULL; - mp->mp_Flags = PA_SIGNAL; - mp->mp_SigTask = task; - signal = AllocSignal(-1); +struct timerequest * +OpenTimerDevice() { + BYTE signal = AllocSignal(-1); + struct TimeRequest *io; + struct MsgPort *mp; + if (signal == -1) { signal = SIGB_TIMER_FALLBACK; SetSignal(SIGF_TIMER_FALLBACK, 0); } - mp->mp_SigBit = signal; - NewList(&mp->mp_MsgList); - - // prepare IORequest - io->io_Message.mn_Node.ln_Type = NT_MESSAGE; - io->io_Message.mn_Node.ln_Pri = 0; - io->io_Message.mn_Node.ln_Name = NULL; - io->io_Message.mn_ReplyPort = mp; - io->io_Message.mn_Length = sizeof(struct TimeRequest); + // Allocate MsgPort + mp = AllocSysObjectTags(ASOT_PORT, + ASOPORT_AllocSig, FALSE, + ASOPORT_Signal, signal); + if (!mp) + return TRUE; + + // allocate IORequest + io = AllocSysObjectTags(ASOT_IOREQUEST, + ASOIOR_ReplyPort, mp, + ASOIOR_Size, sizeof(struct TimeRequest), + TAG_END); + if (!io) { + FreeSysObject(ASOT_PORT, mp); + mp = NULL; + return TRUE; + } // open timer.device - return !OpenDevice((STRPTR) TIMERNAME, UNIT_MICROHZ, io, 0); + if (OpenDevice((STRPTR) TIMERNAME, UNIT_MICROHZ, io, 0)) { + if (mp->mp_SigBit != SIGB_TIMER_FALLBACK) + FreeSignal(mp->mp_SigBit); + FreeSysObject(ASOT_PORT, mp); + FreeSysObject(ASOT_IOREQUEST, io); + io = NULL; + mp = NULL; + return NULL; + } + return (struct timerequest *) io; } void @@ -116,6 +128,16 @@ CloseTimerDevice(struct IORequest *io) { CloseDevice(io); mp = io->io_Message.mn_ReplyPort; + if (mp->mp_SigBit != SIGB_TIMER_FALLBACK) FreeSignal(mp->mp_SigBit); + + if (mp) { + FreeSysObject(ASOT_PORT, mp); + mp = NULL; + } + if (io) { + FreeSysObject(ASOT_IOREQUEST, io); + io = NULL; + } } \ No newline at end of file diff --git a/library/pthread/common.h b/library/pthread/common.h index ffe3b4bf..9d4c7104 100644 --- a/library/pthread/common.h +++ b/library/pthread/common.h @@ -117,7 +117,7 @@ int SemaphoreIsMine(struct SignalSemaphore *sem); int MutexIsMine(pthread_mutex_t *mutex); ThreadInfo *GetThreadInfo(pthread_t thread); pthread_t GetThreadId(struct Task *task); -BOOL OpenTimerDevice(struct IORequest *io, struct MsgPort *mp, struct Task *task); +struct timerequest *OpenTimerDevice(); void CloseTimerDevice(struct IORequest *io); // Private functions diff --git a/library/pthread/pthread.c b/library/pthread/pthread.c index 055289bc..9772ef5e 100644 --- a/library/pthread/pthread.c +++ b/library/pthread/pthread.c @@ -21,7 +21,6 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ - #define __USE_OLD_TIMEVAL__ #ifndef _TIME_HEADERS_H #include "time_headers.h" @@ -91,48 +90,50 @@ _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr, BOO int _pthread_obtain_sema_timed(struct SignalSemaphore *sema, const struct timespec *abstime, int shared) { - struct MsgPort msgport; + struct MsgPort *msgport; struct SemaphoreMessage msg; - struct TimeRequest timerio; - struct Task *task; + struct timerequest *timerio; struct Message *m1, *m2; - task = FindTask(NULL); + timerio = OpenTimerDevice(); + if (!timerio) + return EINVAL; - if (!OpenTimerDevice((struct IORequest *) &timerio, &msgport, task)) { - CloseTimerDevice((struct IORequest *) &timerio); + msgport = AllocSysObject(ASOT_PORT, NULL); + if (!msgport) return EINVAL; - } - timerio.Request.io_Command = TR_ADDREQUEST; - timerio.Request.io_Flags = 0; - TIMESPEC_TO_OLD_TIMEVAL(&timerio.Time, abstime); + timerio->tr_node.io_Command = TR_ADDREQUEST; + timerio->tr_node.io_Flags = 0; + TIMESPEC_TO_TIMEVAL(timerio.tr_time, abstime); //if (!relative) { - struct TimeVal starttime; + struct timeval starttime; // absolute time has to be converted to relative // GetSysTime can't be used due to the timezone offset in abstime - gettimeofday((struct timeval *)&starttime, NULL); - timersub(&timerio.Time, &starttime, &timerio.Time); - if (!timerisset(&timerio.Time)) { - CloseTimerDevice((struct IORequest *) &timerio); + gettimeofday(&starttime, NULL); + timersub(timerio->tr_time, &starttime, timerio->tr_time); + if (!timerisset(timerio->tr_time)) { + CloseTimerDevice((struct IORequest *) timerio); return ETIMEDOUT; } } - SendIO((struct IORequest *) &timerio); + SendIO((struct IORequest *) timerio); msg.ssm_Message.mn_Node.ln_Type = NT_MESSAGE; msg.ssm_Message.mn_Node.ln_Name = (char *) shared; - msg.ssm_Message.mn_ReplyPort = &msgport; + msg.ssm_Message.mn_ReplyPort = msgport; Procure(sema, &msg); - WaitPort(&msgport); - m1 = GetMsg(&msgport); - m2 = GetMsg(&msgport); - if (m1 == &timerio.Request.io_Message || m2 == &timerio.Request.io_Message) + WaitPort(msgport); + m1 = GetMsg(msgport); + m2 = GetMsg(msgport); + if (m1 == timerio->tr_node.io_Message || m2 == timerio->tr_node.io_Message) Vacate(sema, &msg); - CloseTimerDevice((struct IORequest *) &timerio); + FreeSysObject(msgport); + + CloseTimerDevice((struct IORequest *) timerio); if (msg.ssm_Semaphore == NULL) return ETIMEDOUT; @@ -152,7 +153,7 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru BYTE signal; ULONG sigs = SIGBREAKF_CTRL_C; struct MsgPort timermp; - struct TimeRequest timerio; + struct timerequest *timerio; struct Task *task; if (cond == NULL || mutex == NULL) @@ -166,28 +167,32 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru if (abstime) { // open timer.device - if (!OpenTimerDevice((struct IORequest *) &timerio, &timermp, task)) { - CloseTimerDevice((struct IORequest *) &timerio); + timerio = OpenTimerDevice(); + if (!timerio) { return EINVAL; } // prepare the device command and send it - timerio.Request.io_Command = TR_ADDREQUEST; - timerio.Request.io_Flags = 0; - TIMESPEC_TO_OLD_TIMEVAL(&timerio.Time, abstime); + timerio->tr_node.io_Command = TR_ADDREQUEST; + timerio->tr_node.io_Flags = 0; + TIMESPEC_TO_TIMEVAL(&timerio->tr_time, abstime); if (!relative) { - struct TimeVal starttime; + struct timeval starttime; // absolute time has to be converted to relative // GetSysTime can't be used due to the timezone offset in abstime - gettimeofday((struct timeval *)&starttime, NULL); - timersub(&timerio.Time, &starttime, &timerio.Time); - if (!timerisset(&timerio.Time)) { - CloseTimerDevice((struct IORequest *) &timerio); + + gettimeofday(&starttime, NULL); + timersub(timerio->tr_time, &starttime, timerio->tr_time); + printf("2) SECS: %ld - USECS: %ld\n", timerio->tr_time.tv_sec, timerio->tr_time.tv_usec); + if (timerio->tr_time.tv_usec < 0) + timerio->tr_time.tv_usec = 0; + if (!timerisset(timerio->tr_time)) { + CloseTimerDevice((struct IORequest *) timerio); return ETIMEDOUT; } } sigs |= (1 << timermp.mp_SigBit); - SendIO((struct IORequest *) &timerio); + SendIO((struct IORequest *) timerio); } // prepare a waiter node @@ -197,6 +202,7 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru signal = SIGB_COND_FALLBACK; SetSignal(SIGF_COND_FALLBACK, 0); } + waiter.sigbit = signal; sigs |= 1 << waiter.sigbit; @@ -208,7 +214,9 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru // wait for the condition to be signalled or the timeout mutex->incond++; pthread_mutex_unlock(mutex); + Printf("wait\n"); sigs = Wait(sigs); + Printf("done\n"); pthread_mutex_lock(mutex); mutex->incond--; @@ -222,7 +230,7 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru if (abstime) { // clean up the TimeRequest - CloseTimerDevice((struct IORequest *) &timerio); + CloseTimerDevice((struct IORequest *) timerio); // did we timeout? if (sigs & (1 << timermp.mp_SigBit)) diff --git a/library/stdio/gets.c b/library/stdio/gets.c index 8799ce83..6bb8333e 100644 --- a/library/stdio/gets.c +++ b/library/stdio/gets.c @@ -67,6 +67,7 @@ gets(char *s) { file->iob_BufferPosition += num_characters_in_line; s[num_characters_in_line] = 0; /* And that concludes the line read operation. */ + (*s) = '\0'; goto out; } diff --git a/library/time/gettimeofday.c b/library/time/gettimeofday.c index 172cf8b8..e264cf49 100644 --- a/library/time/gettimeofday.c +++ b/library/time/gettimeofday.c @@ -19,7 +19,7 @@ #endif /* _UNISTD_HEADERS_H */ int -gettimeofday(struct timeval *tp, struct timezone *tzp) { +gettimeofday(struct timeval *tv, struct timezone *tzp) { struct _clib4 *__clib4 = __CLIB4; int32 gmtoffset = 0; int8 dstime = -1; @@ -31,7 +31,7 @@ gettimeofday(struct timeval *tp, struct timezone *tzp) { ENTER(); if (!__clib4->__ITimer) { - tp->tv_sec = tp->tv_usec = tzp->tz_minuteswest = tzp->tz_dsttime = 0; + tv->tv_sec = tv->tv_usec = tzp->tz_minuteswest = tzp->tz_dsttime = 0; RETURN(0); } @@ -40,44 +40,12 @@ gettimeofday(struct timeval *tp, struct timezone *tzp) { GetTimezoneAttrs(NULL, TZA_UTCOffset, &gmtoffset, TZA_TimeFlag, &dstime, TAG_DONE); /* Obtain the current system time. */ -#if defined(__NEW_TIMEVAL_DEFINITION_USED__) - { - struct TimeVal tv; - - GetSysTime(&tv); - - seconds = tv.Seconds; - microseconds = tv.Microseconds; - } -#else - { - struct timeval tv; - - GetSysTime(&tv); - - seconds = tv.tv_sec; - microseconds = tv.tv_usec; - } -#endif /* __NEW_TIMEVAL_DEFINITION_USED__ */ + GetSysTime((struct TimeVal *) tv); ReleaseSemaphore(__clib4->__timer_semaphore); - /* Convert the number of seconds so that they match the Unix epoch, which - starts (January 1st, 1970) eight years before the AmigaOS epoch. */ - seconds += UNIX_TIME_OFFSET; - - /* If possible, adjust for the local time zone. We do this because the - AmigaOS system time is returned in local time and we want to return - it in UTC. */ - seconds += 60 * gmtoffset; - - if (tp != NULL) { - tp->tv_sec = (long) seconds; - tp->tv_usec = (long) microseconds; - - SHOWVALUE(tp->tv_sec); - SHOWVALUE(tp->tv_usec); - } + /* 2922 is the number of days between 1.1.1970 and 1.1.1978 */ + tv->tv_sec += (2922 * 24 * 60 + gmtoffset) * 60; if (tzp != NULL) { tzp->tz_minuteswest = gmtoffset; diff --git a/library/time/time.c b/library/time/time.c index ac2930ef..8ae32b88 100644 --- a/library/time/time.c +++ b/library/time/time.c @@ -12,18 +12,13 @@ time_t time(time_t *tptr) { - struct DateStamp ds; - time_t result; - DateStamp(&ds); + struct timeval now; - /* This converts the DateStamp contents into the number of - seconds elapsed since January 1st 1970. The time is - given as relative to UTC, not local time. */ - result = __convert_datestamp_to_time(&ds); - - if (tptr != NULL) - (*tptr) = result; - - return (result); + if (gettimeofday(&now, (struct timezone *) 0) >= 0) { + if (tptr) + *tptr = now.tv_sec; + return now.tv_sec; + } + return -1; } From 725f8350acb1eae119b8fd0270d171fd560252a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrea=20Palmat=C3=A8?= Date: Tue, 28 May 2024 17:45:01 +0200 Subject: [PATCH 2/3] More changes to track down pthread problem --- library/c.lib_rev.h | 6 ++-- library/pthread/common.c | 10 +++--- library/pthread/common.h | 2 +- library/pthread/pthread.c | 76 +++++++++++++++++++-------------------- 4 files changed, 47 insertions(+), 47 deletions(-) diff --git a/library/c.lib_rev.h b/library/c.lib_rev.h index fc5f947c..b81c4291 100755 --- a/library/c.lib_rev.h +++ b/library/c.lib_rev.h @@ -2,7 +2,7 @@ #define REVISION 0 #define SUBREVISION 0 -#define DATE "27.05.2024" +#define DATE "28.05.2024" #define VERS "clib4.library 1.0.0" -#define VSTRING "clib4.library 1.0.0 (27.05.2024)\r\n" -#define VERSTAG "\0$VER: clib4.library 1.0.0 (27.05.2024)" \ No newline at end of file +#define VSTRING "clib4.library 1.0.0 (28.05.2024)\r\n" +#define VERSTAG "\0$VER: clib4.library 1.0.0 (28.05.2024)" \ No newline at end of file diff --git a/library/pthread/common.c b/library/pthread/common.c index 819d9981..05418ac8 100644 --- a/library/pthread/common.c +++ b/library/pthread/common.c @@ -74,7 +74,7 @@ pthread_t GetThreadId(struct Task *task) { return i; } -struct timerequest * +struct TimeRequest * OpenTimerDevice() { BYTE signal = AllocSignal(-1); struct TimeRequest *io; @@ -89,7 +89,7 @@ OpenTimerDevice() { ASOPORT_AllocSig, FALSE, ASOPORT_Signal, signal); if (!mp) - return TRUE; + return NULL; // allocate IORequest io = AllocSysObjectTags(ASOT_IOREQUEST, @@ -99,11 +99,11 @@ OpenTimerDevice() { if (!io) { FreeSysObject(ASOT_PORT, mp); mp = NULL; - return TRUE; + return NULL; } // open timer.device - if (OpenDevice((STRPTR) TIMERNAME, UNIT_MICROHZ, io, 0)) { + if (OpenDevice((STRPTR) TIMERNAME, UNIT_MICROHZ, (struct IORequest *) io, 0)) { if (mp->mp_SigBit != SIGB_TIMER_FALLBACK) FreeSignal(mp->mp_SigBit); FreeSysObject(ASOT_PORT, mp); @@ -112,7 +112,7 @@ OpenTimerDevice() { mp = NULL; return NULL; } - return (struct timerequest *) io; + return io; } void diff --git a/library/pthread/common.h b/library/pthread/common.h index 9d4c7104..3f320c8f 100644 --- a/library/pthread/common.h +++ b/library/pthread/common.h @@ -117,7 +117,7 @@ int SemaphoreIsMine(struct SignalSemaphore *sem); int MutexIsMine(pthread_mutex_t *mutex); ThreadInfo *GetThreadInfo(pthread_t thread); pthread_t GetThreadId(struct Task *task); -struct timerequest *OpenTimerDevice(); +struct TimeRequest *OpenTimerDevice(); void CloseTimerDevice(struct IORequest *io); // Private functions diff --git a/library/pthread/pthread.c b/library/pthread/pthread.c index 9772ef5e..22af3246 100644 --- a/library/pthread/pthread.c +++ b/library/pthread/pthread.c @@ -21,7 +21,7 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ -#define __USE_OLD_TIMEVAL__ + #ifndef _TIME_HEADERS_H #include "time_headers.h" #endif /* _TIME_HEADERS_H */ @@ -92,7 +92,7 @@ int _pthread_obtain_sema_timed(struct SignalSemaphore *sema, const struct timespec *abstime, int shared) { struct MsgPort *msgport; struct SemaphoreMessage msg; - struct timerequest *timerio; + struct TimeRequest *timerio; struct Message *m1, *m2; timerio = OpenTimerDevice(); @@ -105,15 +105,15 @@ _pthread_obtain_sema_timed(struct SignalSemaphore *sema, const struct timespec * timerio->tr_node.io_Command = TR_ADDREQUEST; timerio->tr_node.io_Flags = 0; - TIMESPEC_TO_TIMEVAL(timerio.tr_time, abstime); + TIMESPEC_TO_OLD_TIMEVAL(&timerio->tr_time, abstime); //if (!relative) { - struct timeval starttime; + struct TimeVal starttime; // absolute time has to be converted to relative // GetSysTime can't be used due to the timezone offset in abstime gettimeofday(&starttime, NULL); - timersub(timerio->tr_time, &starttime, timerio->tr_time); - if (!timerisset(timerio->tr_time)) { + timersub(&timerio->Time, &starttime, &timerio->Time); + if (!timerisset(&timerio->tr_time)) { CloseTimerDevice((struct IORequest *) timerio); return ETIMEDOUT; } @@ -128,10 +128,10 @@ _pthread_obtain_sema_timed(struct SignalSemaphore *sema, const struct timespec * WaitPort(msgport); m1 = GetMsg(msgport); m2 = GetMsg(msgport); - if (m1 == timerio->tr_node.io_Message || m2 == timerio->tr_node.io_Message) + if (m1 == &timerio->tr_node.io_Message || m2 == &timerio->tr_node.io_Message) Vacate(sema, &msg); - FreeSysObject(msgport); + FreeSysObject(ASOT_PORT, msgport); CloseTimerDevice((struct IORequest *) timerio); @@ -152,19 +152,33 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru CondWaiter waiter; BYTE signal; ULONG sigs = SIGBREAKF_CTRL_C; - struct MsgPort timermp; - struct timerequest *timerio; + struct TimeRequest *timerio; struct Task *task; if (cond == NULL || mutex == NULL) return EINVAL; - // initialize static conditions + /* initialize static conditions */ if (SemaphoreIsInvalid(cond->semaphore)) pthread_cond_init(cond, NULL); task = FindTask(NULL); + // prepare a waiter node + waiter.task = task; + signal = AllocSignal(-1); + if (signal == -1) { + signal = SIGB_COND_FALLBACK; + SetSignal(SIGF_COND_FALLBACK, 0); + } + waiter.sigbit = signal; + sigs |= 1 << waiter.sigbit; + + // add it to the end of the list + ObtainSemaphore(cond->semaphore); + AddTail((struct List *) cond->waiters, (struct Node *) &waiter); + ReleaseSemaphore(cond->semaphore); + if (abstime) { // open timer.device timerio = OpenTimerDevice(); @@ -173,44 +187,26 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru } // prepare the device command and send it - timerio->tr_node.io_Command = TR_ADDREQUEST; - timerio->tr_node.io_Flags = 0; - TIMESPEC_TO_TIMEVAL(&timerio->tr_time, abstime); + timerio->Request.io_Command = TR_ADDREQUEST; + timerio->Request.io_Flags = 0; + TIMESPEC_TO_OLD_TIMEVAL(&timerio->Time, abstime); if (!relative) { struct timeval starttime; // absolute time has to be converted to relative // GetSysTime can't be used due to the timezone offset in abstime gettimeofday(&starttime, NULL); - timersub(timerio->tr_time, &starttime, timerio->tr_time); - printf("2) SECS: %ld - USECS: %ld\n", timerio->tr_time.tv_sec, timerio->tr_time.tv_usec); - if (timerio->tr_time.tv_usec < 0) - timerio->tr_time.tv_usec = 0; - if (!timerisset(timerio->tr_time)) { + timersub(&timerio->Time, &starttime, &timerio->Time); + if (!timerisset(&timerio->Time)) { CloseTimerDevice((struct IORequest *) timerio); return ETIMEDOUT; } } - sigs |= (1 << timermp.mp_SigBit); + sigs |= (1 << ((struct IORequest *) timerio)->io_Message.mn_ReplyPort->mp_SigBit); + SetSignal(0, ((struct IORequest *) timerio)->io_Message.mn_ReplyPort->mp_SigBit); SendIO((struct IORequest *) timerio); } - // prepare a waiter node - waiter.task = task; - signal = AllocSignal(-1); - if (signal == -1) { - signal = SIGB_COND_FALLBACK; - SetSignal(SIGF_COND_FALLBACK, 0); - } - - waiter.sigbit = signal; - sigs |= 1 << waiter.sigbit; - - // add it to the end of the list - ObtainSemaphore(cond->semaphore); - AddTail((struct List *) cond->waiters, (struct Node *) &waiter); - ReleaseSemaphore(cond->semaphore); - // wait for the condition to be signalled or the timeout mutex->incond++; pthread_mutex_unlock(mutex); @@ -229,14 +225,18 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru FreeSignal(waiter.sigbit); if (abstime) { + BOOL timeout = sigs & (1 << ((struct IORequest *) timerio)->io_Message.mn_ReplyPort->mp_SigBit); + // clean up the TimeRequest CloseTimerDevice((struct IORequest *) timerio); // did we timeout? - if (sigs & (1 << timermp.mp_SigBit)) + if (timeout) { return ETIMEDOUT; - else if (sigs & SIGBREAKF_CTRL_C) + } + else if (sigs & SIGBREAKF_CTRL_C) { pthread_testcancel(); + } } else { if (sigs & SIGBREAKF_CTRL_C) pthread_testcancel(); From 08f5d21467085765d23adeae7c1b5f1cccd15787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andrea=20Palmat=C3=A8?= Date: Tue, 28 May 2024 20:05:19 +0200 Subject: [PATCH 3/3] Fixed a problem in timersub --- library/include/time.h | 11 ++-- library/pthread/common.c | 64 +++++++-------------- library/pthread/common.h | 2 +- library/pthread/pthread.c | 116 ++++++++++++++++++-------------------- 4 files changed, 81 insertions(+), 112 deletions(-) diff --git a/library/include/time.h b/library/include/time.h index 3612a3a6..f4924afe 100755 --- a/library/include/time.h +++ b/library/include/time.h @@ -92,7 +92,7 @@ struct timespec64 { /* BSD time macros used by RTEMS code */ /* Convenience macros for operations on timevals. NOTE: `timercmp' does not work for >= or <=. */ -#ifdef __USE_OLD_TIMEVAL__ +#ifndef __USE_OLD_TIMEVAL__ #define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) #define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) #define timercmp(a, b, CMP) \ @@ -102,7 +102,7 @@ struct timespec64 { { \ (result)->tv_sec = (a)->tv_sec + (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec + (b)->tv_usec; \ - if ((result)->tv_usec >= 1000000) \ + if ((int32) ((result)->tv_usec) >= 1000000) \ { \ ++(result)->tv_sec; \ (result)->tv_usec -= 1000000; \ @@ -113,9 +113,8 @@ struct timespec64 { { \ (result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \ (result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \ - if ((result)->tv_usec < 0) \ + if ((int32) ((result)->tv_usec) < 0) \ { \ - printf("gillo\n"); \ --(result)->tv_sec; \ (result)->tv_usec += 1000000; \ } \ @@ -130,7 +129,7 @@ struct timespec64 { { \ (result)->Seconds = (a)->Seconds + (b)->Seconds; \ (result)->Microseconds = (a)->Microseconds + (b)->Microseconds; \ - if ((result)->Microseconds >= 1000000) \ + if ((int32) ((result)->Microseconds) >= 1000000) \ { \ ++(result)->Seconds; \ (result)->Microseconds -= 1000000; \ @@ -141,7 +140,7 @@ struct timespec64 { { \ (result)->Seconds = (a)->Seconds - (b)->Seconds; \ (result)->Microseconds = (a)->Microseconds - (b)->Microseconds; \ - if ((result)->Microseconds < 0) \ + if ((int32) ((result)->Microseconds) < 0) \ { \ --(result)->Seconds; \ (result)->Microseconds += 1000000; \ diff --git a/library/pthread/common.c b/library/pthread/common.c index 05418ac8..b1e334b5 100644 --- a/library/pthread/common.c +++ b/library/pthread/common.c @@ -74,45 +74,33 @@ pthread_t GetThreadId(struct Task *task) { return i; } -struct TimeRequest * -OpenTimerDevice() { - BYTE signal = AllocSignal(-1); - struct TimeRequest *io; - struct MsgPort *mp; - +BOOL +OpenTimerDevice(struct IORequest *io, struct MsgPort *mp, struct Task *task) { + BYTE signal; + + // prepare MsgPort + mp->mp_Node.ln_Type = NT_MSGPORT; + mp->mp_Node.ln_Pri = 0; + mp->mp_Node.ln_Name = NULL; + mp->mp_Flags = PA_SIGNAL; + mp->mp_SigTask = task; + signal = AllocSignal(-1); if (signal == -1) { signal = SIGB_TIMER_FALLBACK; SetSignal(SIGF_TIMER_FALLBACK, 0); } - // Allocate MsgPort - mp = AllocSysObjectTags(ASOT_PORT, - ASOPORT_AllocSig, FALSE, - ASOPORT_Signal, signal); - if (!mp) - return NULL; - - // allocate IORequest - io = AllocSysObjectTags(ASOT_IOREQUEST, - ASOIOR_ReplyPort, mp, - ASOIOR_Size, sizeof(struct TimeRequest), - TAG_END); - if (!io) { - FreeSysObject(ASOT_PORT, mp); - mp = NULL; - return NULL; - } + mp->mp_SigBit = signal; + NewList(&mp->mp_MsgList); + + // prepare IORequest + io->io_Message.mn_Node.ln_Type = NT_MESSAGE; + io->io_Message.mn_Node.ln_Pri = 0; + io->io_Message.mn_Node.ln_Name = NULL; + io->io_Message.mn_ReplyPort = mp; + io->io_Message.mn_Length = sizeof(struct TimeRequest); // open timer.device - if (OpenDevice((STRPTR) TIMERNAME, UNIT_MICROHZ, (struct IORequest *) io, 0)) { - if (mp->mp_SigBit != SIGB_TIMER_FALLBACK) - FreeSignal(mp->mp_SigBit); - FreeSysObject(ASOT_PORT, mp); - FreeSysObject(ASOT_IOREQUEST, io); - io = NULL; - mp = NULL; - return NULL; - } - return io; + return !OpenDevice((STRPTR) TIMERNAME, UNIT_MICROHZ, io, 0); } void @@ -128,16 +116,6 @@ CloseTimerDevice(struct IORequest *io) { CloseDevice(io); mp = io->io_Message.mn_ReplyPort; - if (mp->mp_SigBit != SIGB_TIMER_FALLBACK) FreeSignal(mp->mp_SigBit); - - if (mp) { - FreeSysObject(ASOT_PORT, mp); - mp = NULL; - } - if (io) { - FreeSysObject(ASOT_IOREQUEST, io); - io = NULL; - } } \ No newline at end of file diff --git a/library/pthread/common.h b/library/pthread/common.h index 3f320c8f..ffe3b4bf 100644 --- a/library/pthread/common.h +++ b/library/pthread/common.h @@ -117,7 +117,7 @@ int SemaphoreIsMine(struct SignalSemaphore *sem); int MutexIsMine(pthread_mutex_t *mutex); ThreadInfo *GetThreadInfo(pthread_t thread); pthread_t GetThreadId(struct Task *task); -struct TimeRequest *OpenTimerDevice(); +BOOL OpenTimerDevice(struct IORequest *io, struct MsgPort *mp, struct Task *task); void CloseTimerDevice(struct IORequest *io); // Private functions diff --git a/library/pthread/pthread.c b/library/pthread/pthread.c index 22af3246..055289bc 100644 --- a/library/pthread/pthread.c +++ b/library/pthread/pthread.c @@ -22,6 +22,7 @@ 3. This notice may not be removed or altered from any source distribution. */ +#define __USE_OLD_TIMEVAL__ #ifndef _TIME_HEADERS_H #include "time_headers.h" #endif /* _TIME_HEADERS_H */ @@ -90,50 +91,48 @@ _pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr, BOO int _pthread_obtain_sema_timed(struct SignalSemaphore *sema, const struct timespec *abstime, int shared) { - struct MsgPort *msgport; + struct MsgPort msgport; struct SemaphoreMessage msg; - struct TimeRequest *timerio; + struct TimeRequest timerio; + struct Task *task; struct Message *m1, *m2; - timerio = OpenTimerDevice(); - if (!timerio) - return EINVAL; + task = FindTask(NULL); - msgport = AllocSysObject(ASOT_PORT, NULL); - if (!msgport) + if (!OpenTimerDevice((struct IORequest *) &timerio, &msgport, task)) { + CloseTimerDevice((struct IORequest *) &timerio); return EINVAL; + } - timerio->tr_node.io_Command = TR_ADDREQUEST; - timerio->tr_node.io_Flags = 0; - TIMESPEC_TO_OLD_TIMEVAL(&timerio->tr_time, abstime); + timerio.Request.io_Command = TR_ADDREQUEST; + timerio.Request.io_Flags = 0; + TIMESPEC_TO_OLD_TIMEVAL(&timerio.Time, abstime); //if (!relative) { struct TimeVal starttime; // absolute time has to be converted to relative // GetSysTime can't be used due to the timezone offset in abstime - gettimeofday(&starttime, NULL); - timersub(&timerio->Time, &starttime, &timerio->Time); - if (!timerisset(&timerio->tr_time)) { - CloseTimerDevice((struct IORequest *) timerio); + gettimeofday((struct timeval *)&starttime, NULL); + timersub(&timerio.Time, &starttime, &timerio.Time); + if (!timerisset(&timerio.Time)) { + CloseTimerDevice((struct IORequest *) &timerio); return ETIMEDOUT; } } - SendIO((struct IORequest *) timerio); + SendIO((struct IORequest *) &timerio); msg.ssm_Message.mn_Node.ln_Type = NT_MESSAGE; msg.ssm_Message.mn_Node.ln_Name = (char *) shared; - msg.ssm_Message.mn_ReplyPort = msgport; + msg.ssm_Message.mn_ReplyPort = &msgport; Procure(sema, &msg); - WaitPort(msgport); - m1 = GetMsg(msgport); - m2 = GetMsg(msgport); - if (m1 == &timerio->tr_node.io_Message || m2 == &timerio->tr_node.io_Message) + WaitPort(&msgport); + m1 = GetMsg(&msgport); + m2 = GetMsg(&msgport); + if (m1 == &timerio.Request.io_Message || m2 == &timerio.Request.io_Message) Vacate(sema, &msg); - FreeSysObject(ASOT_PORT, msgport); - - CloseTimerDevice((struct IORequest *) timerio); + CloseTimerDevice((struct IORequest *) &timerio); if (msg.ssm_Semaphore == NULL) return ETIMEDOUT; @@ -152,18 +151,45 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru CondWaiter waiter; BYTE signal; ULONG sigs = SIGBREAKF_CTRL_C; - struct TimeRequest *timerio; + struct MsgPort timermp; + struct TimeRequest timerio; struct Task *task; if (cond == NULL || mutex == NULL) return EINVAL; - /* initialize static conditions */ + // initialize static conditions if (SemaphoreIsInvalid(cond->semaphore)) pthread_cond_init(cond, NULL); task = FindTask(NULL); + if (abstime) { + // open timer.device + if (!OpenTimerDevice((struct IORequest *) &timerio, &timermp, task)) { + CloseTimerDevice((struct IORequest *) &timerio); + return EINVAL; + } + + // prepare the device command and send it + timerio.Request.io_Command = TR_ADDREQUEST; + timerio.Request.io_Flags = 0; + TIMESPEC_TO_OLD_TIMEVAL(&timerio.Time, abstime); + if (!relative) { + struct TimeVal starttime; + // absolute time has to be converted to relative + // GetSysTime can't be used due to the timezone offset in abstime + gettimeofday((struct timeval *)&starttime, NULL); + timersub(&timerio.Time, &starttime, &timerio.Time); + if (!timerisset(&timerio.Time)) { + CloseTimerDevice((struct IORequest *) &timerio); + return ETIMEDOUT; + } + } + sigs |= (1 << timermp.mp_SigBit); + SendIO((struct IORequest *) &timerio); + } + // prepare a waiter node waiter.task = task; signal = AllocSignal(-1); @@ -179,40 +205,10 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru AddTail((struct List *) cond->waiters, (struct Node *) &waiter); ReleaseSemaphore(cond->semaphore); - if (abstime) { - // open timer.device - timerio = OpenTimerDevice(); - if (!timerio) { - return EINVAL; - } - - // prepare the device command and send it - timerio->Request.io_Command = TR_ADDREQUEST; - timerio->Request.io_Flags = 0; - TIMESPEC_TO_OLD_TIMEVAL(&timerio->Time, abstime); - if (!relative) { - struct timeval starttime; - // absolute time has to be converted to relative - // GetSysTime can't be used due to the timezone offset in abstime - - gettimeofday(&starttime, NULL); - timersub(&timerio->Time, &starttime, &timerio->Time); - if (!timerisset(&timerio->Time)) { - CloseTimerDevice((struct IORequest *) timerio); - return ETIMEDOUT; - } - } - sigs |= (1 << ((struct IORequest *) timerio)->io_Message.mn_ReplyPort->mp_SigBit); - SetSignal(0, ((struct IORequest *) timerio)->io_Message.mn_ReplyPort->mp_SigBit); - SendIO((struct IORequest *) timerio); - } - // wait for the condition to be signalled or the timeout mutex->incond++; pthread_mutex_unlock(mutex); - Printf("wait\n"); sigs = Wait(sigs); - Printf("done\n"); pthread_mutex_lock(mutex); mutex->incond--; @@ -225,18 +221,14 @@ _pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const stru FreeSignal(waiter.sigbit); if (abstime) { - BOOL timeout = sigs & (1 << ((struct IORequest *) timerio)->io_Message.mn_ReplyPort->mp_SigBit); - // clean up the TimeRequest - CloseTimerDevice((struct IORequest *) timerio); + CloseTimerDevice((struct IORequest *) &timerio); // did we timeout? - if (timeout) { + if (sigs & (1 << timermp.mp_SigBit)) return ETIMEDOUT; - } - else if (sigs & SIGBREAKF_CTRL_C) { + else if (sigs & SIGBREAKF_CTRL_C) pthread_testcancel(); - } } else { if (sigs & SIGBREAKF_CTRL_C) pthread_testcancel();