1
0
mirror of https://github.com/deadw00d/AROS.git synced 2026-03-17 07:41:59 +00:00
Files
AROS-v0/rom/log/log_event.c

302 lines
9.8 KiB
C
Raw Permalink Blame History

/*
Copyright (C) 2023-2025, The AROS Development Team. All rights reserved.
*/
#include <proto/exec.h>
#include <proto/kernel.h>
#include <proto/dos.h>
#include <proto/utility.h>
#include <proto/timer.h>
#include <proto/log.h>
#include <proto/alib.h>
#include <aros/libcall.h>
#include <aros/asmcall.h>
#include <aros/symbolsets.h>
#include <resources/log.h>
#include <stddef.h>
#include <string.h>
#include "log_intern.h"
#include LC_LIBDEFS_FILE
extern BOOL GM_UNIQUENAME(HaveDOS)(LIBBASETYPEPTR LIBBASE);
extern BOOL GM_UNIQUENAME(OpenUtility)(LIBBASETYPEPTR LIBBASE);
extern BOOL GM_UNIQUENAME(HaveTimer)(LIBBASETYPEPTR LIBBASE);
#define DOSBase LIBBASE->lrb_DosBase
#define TimerBase LIBBASE->lrb_TimerIOReq.tr_node.io_Device
#define UtilityBase LIBBASE->lrb_UtilityBase
#define KernelBase LIBBASE->lrb_KernelBase
AROS_LH1(VOID, logLockEntries,
AROS_LHA(ULONG, flags, D0),
LIBBASETYPEPTR, LIBBASE, 13, log)
{
AROS_LIBFUNC_INIT
struct ExecBase *SysBase = GM_SYSBASE_FIELD(LIBBASE);
ObtainSemaphore(&LIBBASE->lrb_ReentrantLock);
AROS_LIBFUNC_EXIT
}
AROS_LH1(VOID, logUnlockEntries,
AROS_LHA(ULONG, flags, D0),
LIBBASETYPEPTR, LIBBASE, 15, log)
{
AROS_LIBFUNC_INIT
struct ExecBase *SysBase = GM_SYSBASE_FIELD(LIBBASE);
ReleaseSemaphore(&LIBBASE->lrb_ReentrantLock);
AROS_LIBFUNC_EXIT
}
AROS_LH1(APTR, logNextEntry,
AROS_LHA(APTR *, entryHandle, A0),
LIBBASETYPEPTR, LIBBASE, 14, log)
{
AROS_LIBFUNC_INIT
struct logEntryPrivate *leP;
struct logEntry *le;
if (entryHandle) {
if (*entryHandle == (APTR)LOGEntry_First) {
leP = (struct logEntryPrivate *)GetHead(&LIBBASE->lrb_LRProvider.lrh_Entries);
if (leP)
*entryHandle = &leP->le_Node;
else
*entryHandle = (APTR)LOGEntry_Last;
}
else if (*entryHandle != (APTR)LOGEntry_Last) {
le = *entryHandle;
if (le->le_Node.ln_Type == NT_LOGENTRY) {
leP = (struct logEntryPrivate *)((IPTR)le - offsetof(struct logEntryPrivate, le_Node));
leP = (struct logEntryPrivate *)GetSucc(leP);
if (leP)
*entryHandle = &leP->le_Node;
else
*entryHandle = (APTR)LOGEntry_Last;
}
else
*entryHandle = (APTR)LOGEntry_Last;
} else {
// Return the last entry if called with LOGEntry_Last
}
return *entryHandle;
}
return NULL;
AROS_LIBFUNC_EXIT
}
AROS_LH2(IPTR, logGetEntryAttrs,
AROS_LHA(APTR, entryHandle, A0),
AROS_LHA(struct TagItem *, tags, A1),
LIBBASETYPEPTR, LIBBASE, 9, log)
{
AROS_LIBFUNC_INIT
struct logEntry *le = (struct logEntry *)entryHandle;
IPTR count = 0;
if (le && (le->le_Node.ln_Type == NT_LOGENTRY) && (GM_UNIQUENAME(OpenUtility)(LIBBASE))) {
struct logEntryPrivate *leP;
struct TagItem *ti;
leP = (struct logEntryPrivate *)((IPTR)le - offsetof(struct logEntryPrivate, le_Node));
if((ti = FindTagItem(LOGMA_Flags, tags))) {
*((ULONG *) ti->ti_Data) = (leP->lectx_Flags & ~LOGM_Flag_PrivateMask);
count++;
}
if((ti = FindTagItem(LOGMA_DateStamp, tags))) {
*((struct DateStamp **) ti->ti_Data) = &leP->le_DateStamp;
count++;
}
if((ti = FindTagItem(LOGMA_EventID, tags))) {
*((ULONG *) ti->ti_Data) = leP->le_eid;
count++;
}
if((ti = FindTagItem(LOGMA_Origin, tags))) {
*((char**) ti->ti_Data) = leP->lectx_Originator;
count++;
}
if((ti = FindTagItem(LOGMA_Component, tags))) {
if (leP->lep_Producer) {
struct LogResHandle *lrHandle = (struct LogResHandle *)leP->lep_Producer;
*((char**) ti->ti_Data) = lrHandle->lrh_Node.ln_Name;
count++;
}
}
if((ti = FindTagItem(LOGMA_SubComponent, tags))) {
*((char**) ti->ti_Data) = leP->lep_Node.ln_Name;
count++;
}
if((ti = FindTagItem(LOGMA_LogTag, tags))) {
*((char**) ti->ti_Data) = leP->le_Node.ln_Name;
count++;
}
if((ti = FindTagItem(LOGMA_Entry, tags))) {
*((char**) ti->ti_Data) = leP->le_Entry;
count++;
}
}
return count;
AROS_LIBFUNC_EXIT
}
/*****************************************************************************
NAME */
AROS_LH7(struct logEntry *, logAddEntryA,
/* SYNOPSIS */
AROS_LHA(ULONG, flags, D0),
AROS_LHA(APTR, loghandle, A0),
AROS_LHA(STRPTR, sub, A1),
AROS_LHA(STRPTR, src, A2),
AROS_LHA(ULONG, eventid, D1),
AROS_LHA(STRPTR, fmtstr, A3),
AROS_LHA(RAWARG, fmtdata, A4),
/* LOCATION */
LIBBASETYPEPTR, LIBBASE, 10, log)
/* FUNCTION
Creates and queues a new log entry associated with the given
logging handle. The entry includes timestamp, event ID,
optional subsystem/source strings, originator information,
and a formatted message string built from 'fmtstr' and 'fmtdata'.
INPUTS
flags - Logging flags and priority level (LOGM_*).
loghandle - Handle to an open log resource (struct LogResHandle *).
sub - Optional subsystem string, may be NULL.
src - Optional source string, may be NULL.
eventid - User-supplied event identifier.
fmtstr - Format string for the log message.
fmtdata - Argument data matching the format string.
RESULT
Pointer to a logEntry structure if successful,
or NULL if the entry could not be created.
NOTES
The returned logEntry is owned by log.resource and should not
be modified or freed by the caller. The timestamp source depends
on availability of DOS, timer.device, or kernel facilities.
EXAMPLE
struct logEntry *e = logAddEntryA(LOGM_Flag_Info, myLogHandle,
"filesystem", "disk.device", 42,
"Mounted volume %s", (RAWARG)"DH0:");
BUGS
Kernel timestamp support is incomplete (marked TODO in source).
SEE ALSO
INTERNALS
Allocates a logEntryPrivate from the handle<6C>s pool.
Uses logCopyStrFmtA() to duplicate the formatted message.
Links the entry into the handle<6C>s list unless producer is provider.
Posts an EHMB_ADDENTRY message to the log resource service port.
******************************************************************************/
{
AROS_LIBFUNC_INIT
struct LogResHandle *lrHandle = (struct LogResHandle *)loghandle;
if ((LIBBASE->lrb_Task) && (lrHandle)) {
struct ExecBase *SysBase = GM_SYSBASE_FIELD(LIBBASE);
struct logEntryPrivate *leP;
if ((leP = AllocVecPooled(lrHandle->lrh_Pool, sizeof(struct logEntryPrivate)))) {
memset(leP, 0, sizeof(struct logEntryPrivate));
leP->lep_Node.ln_Pri = (flags & LOGM_Flag_LevelMask);
leP->lectx_Level = flags;
leP->lep_Producer = loghandle;
if((leP->le_Entry = logCopyStrFmtA(fmtstr, fmtdata))) {
struct Task *thisTask = FindTask(NULL);
if (sub)
leP->lep_Node.ln_Name = logCopyStr(sub);
if (src)
leP->le_Node.ln_Name = logCopyStr(src);
leP->lectx_Originator = logCopyStrFmt("0x%p %s", thisTask, ((struct Node *)thisTask)->ln_Name);
leP->le_eid = eventid;
if(GM_UNIQUENAME(HaveDOS)(LIBBASE)) {
DateStamp(&leP->le_DateStamp);
leP->lectx_Flags &= ~(LOGF_Flag_Private_STMPTimer|LOGF_Flag_Private_STMPKrn);
} else if (GM_UNIQUENAME(HaveTimer)(LIBBASE)) {
struct timerequest tr;
CopyMem(&LIBBASE->lrb_TimerIOReq, &tr, sizeof(struct timerequest));
tr.tr_node.io_Command = TR_GETSYSTIME;
DoIO((struct IORequest *) &tr);
leP->le_DateStamp.ds_Days = tr.tr_time.tv_secs / (24*60*60);
leP->le_DateStamp.ds_Minute = (tr.tr_time.tv_secs / 60) % 60;
leP->le_DateStamp.ds_Tick = (tr.tr_time.tv_secs % 60) * 50;
leP->lectx_Flags |= LOGF_Flag_Private_STMPTimer;
} else {
leP->lectx_Flags |= LOGF_Flag_Private_STMPKrn;
if (KernelBase) {
UQUAD stamp = KrnTimeStamp();
if (stamp != 0) {
// TODO:
}
}
}
Forbid();
if (leP->lep_Producer != &LIBBASE->lrb_LRProvider)
AddTail(&lrHandle->lrh_Entries, &leP->le_Node);
Permit();
leP->le_Node.ln_Type = EHMB_ADDENTRY;
PutMsg(LIBBASE->lrb_ServicePort, (struct Message *)leP);
return((struct logEntry *)&leP->le_Node);
}
FreeVecPooled(lrHandle->lrh_Pool, leP);
}
}
return(NULL);
AROS_LIBFUNC_EXIT
}
AROS_LH1(void, logRemEntry,
AROS_LHA(struct logEntry *, le, A0),
LIBBASETYPEPTR, LIBBASE, 11, log)
{
AROS_LIBFUNC_INIT
if (le) {
struct ExecBase *SysBase = GM_SYSBASE_FIELD(LIBBASE);
struct logEntryPrivate *leP;
leP = (struct logEntryPrivate *)((IPTR)le - offsetof(struct logEntryPrivate, le_Node));
Forbid();
Remove(&leP->lep_Node);
if (leP->lep_Producer != &LIBBASE->lrb_LRProvider)
Remove(&leP->le_Node);
Permit();
if (LIBBASE->lrb_Task) {
leP->le_Node.ln_Type = EHMB_REMENTRY;
PutMsg(LIBBASE->lrb_ServicePort, (struct Message *)leP);
}
}
AROS_LIBFUNC_EXIT
}