[PD-cvs] pd/portmidi/porttime porttime.c, NONE, 1.1 porttime.dsp, NONE, 1.1 porttime.h, NONE, 1.1 ptlinux.c, NONE, 1.1 ptmacosx_cf.c, NONE, 1.1 ptmacosx_mach.c, NONE, 1.1 ptwinmm.c, NONE, 1.1
Hans-Christoph Steiner
eighthave at users.sourceforge.net
Thu Dec 15 01:57:04 CET 2005
- Previous message: [PD-cvs] pd/portmidi/pm_test latency.c, NONE, 1.1 latency.dsp, NONE, 1.1 midithread.c, NONE, 1.1 midithread.dsp, NONE, 1.1 midithru.c, NONE, 1.1 midithru.dsp, NONE, 1.1 midithru.dsw, NONE, 1.1 sysex.c, NONE, 1.1 sysex.dsp, NONE, 1.1 test.c, NONE, 1.1 test.dsp, NONE, 1.1 txdata.syx, NONE, 1.1
- Next message: [PD-cvs] pd/portmidi/pm_win README_WIN.txt, NONE, 1.1 copy-dll.bat, NONE, 1.1 debugging_dlls.txt, NONE, 1.1 pm_dll.dsp, NONE, 1.1 pmdll.c, NONE, 1.1 pmdll.h, NONE, 1.1 pmwin.c, NONE, 1.1 pmwinmm.c, NONE, 1.1 pmwinmm.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Update of /cvsroot/pure-data/pd/portmidi/porttime
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7035/porttime
Added Files:
porttime.c porttime.dsp porttime.h ptlinux.c ptmacosx_cf.c
ptmacosx_mach.c ptwinmm.c
Log Message:
checking in missing files on behalf of Miller (cleared it with him first). The files are from portmidi17nov04.zip
--- NEW FILE: porttime.dsp ---
# Microsoft Developer Studio Project File - Name="porttime" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Static Library" 0x0104
CFG=porttime - Win32 Debug
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "porttime.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "porttime.mak" CFG="porttime - Win32 Debug"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "porttime - Win32 Release" (based on "Win32 (x86) Static Library")
!MESSAGE "porttime - Win32 Debug" (based on "Win32 (x86) Static Library")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""
# PROP Scc_LocalPath ""
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "porttime - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir "Release"
# PROP BASE Intermediate_Dir "Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir "Release"
# PROP Intermediate_Dir "Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ELSEIF "$(CFG)" == "porttime - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir "Debug"
# PROP BASE Intermediate_Dir "Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir "Debug"
# PROP Intermediate_Dir "Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "_LIB" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "USE_DLL_FOR_CLEANUP" /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LIB32=link.exe -lib
# ADD BASE LIB32 /nologo
# ADD LIB32 /nologo
!ENDIF
# Begin Target
# Name "porttime - Win32 Release"
# Name "porttime - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\porttime.c
# End Source File
# Begin Source File
SOURCE=.\ptwinmm.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\porttime.h
# End Source File
# End Group
# End Target
# End Project
--- NEW FILE: porttime.h ---
/* porttime.h -- portable interface to millisecond timer */
/* CHANGE LOG FOR PORTTIME
10-Jun-03 Mark Nelson & RBD
boost priority of timer thread in ptlinux.c implementation
*/
/* Should there be a way to choose the source of time here? */
#ifdef __cplusplus
extern "C" {
#endif
typedef enum {
ptNoError = 0,
ptHostError = -10000,
ptAlreadyStarted,
ptAlreadyStopped,
ptInsufficientMemory
} PtError;
typedef long PtTimestamp;
typedef void (PtCallback)( PtTimestamp timestamp, void *userData );
PtError Pt_Start(int resolution, PtCallback *callback, void *userData);
PtError Pt_Stop();
int Pt_Started();
PtTimestamp Pt_Time();
#ifdef __cplusplus
}
#endif
--- NEW FILE: porttime.c ---
/* porttime.c -- portable API for millisecond timer */
/* There is no machine-independent implementation code to put here */
--- NEW FILE: ptwinmm.c ---
/* ptwinmm.c -- portable timer implementation for win32 */
#include "porttime.h"
#include "windows.h"
#include "time.h"
TIMECAPS caps;
static long time_offset = 0;
static int time_started_flag = FALSE;
static long time_resolution;
static MMRESULT timer_id;
static PtCallback *time_callback;
void CALLBACK winmm_time_callback(UINT uID, UINT uMsg, DWORD dwUser,
DWORD dw1, DWORD dw2)
{
(*time_callback)(Pt_Time(), (void *) dwUser);
}
PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
{
if (time_started_flag) return ptAlreadyStarted;
timeBeginPeriod(resolution);
time_resolution = resolution;
time_offset = timeGetTime();
time_started_flag = TRUE;
time_callback = callback;
if (callback) {
timer_id = timeSetEvent(resolution, 1, winmm_time_callback,
(DWORD) userData, TIME_PERIODIC | TIME_CALLBACK_FUNCTION);
if (!timer_id) return ptHostError;
}
return ptNoError;
}
PtError Pt_Stop()
{
if (!time_started_flag) return ptAlreadyStopped;
if (time_callback && timer_id) {
timeKillEvent(timer_id);
time_callback = NULL;
timer_id = 0;
}
time_started_flag = FALSE;
timeEndPeriod(time_resolution);
return ptNoError;
}
int Pt_Started()
{
return time_started_flag;
}
PtTimestamp Pt_Time()
{
return timeGetTime() - time_offset;
}
--- NEW FILE: ptmacosx_mach.c ---
/* ptmacosx.c -- portable timer implementation for mac os x */
#include <stdlib.h>
#include <stdio.h>
#include <CoreAudio/HostTime.h>
#import <mach/mach.h>
#import <mach/mach_error.h>
#import <mach/mach_time.h>
#import <mach/clock.h>
#include "porttime.h"
#include "sys/time.h"
#include "pthread.h"
#define NSEC_PER_MSEC 1000000
#define THREAD_IMPORTANCE 30
static int time_started_flag = FALSE;
static UInt64 start_time;
static pthread_t pt_thread_pid;
/* note that this is static data -- we only need one copy */
typedef struct {
int id;
int resolution;
PtCallback *callback;
void *userData;
} pt_callback_parameters;
static int pt_callback_proc_id = 0;
static void *Pt_CallbackProc(void *p)
{
pt_callback_parameters *parameters = (pt_callback_parameters *) p;
int mytime = 1;
kern_return_t error;
thread_extended_policy_data_t extendedPolicy;
thread_precedence_policy_data_t precedencePolicy;
extendedPolicy.timeshare = 0;
error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY,
(thread_policy_t)&extendedPolicy,
THREAD_EXTENDED_POLICY_COUNT);
if (error != KERN_SUCCESS) {
mach_error("Couldn't set thread timeshare policy", error);
}
precedencePolicy.importance = THREAD_IMPORTANCE;
error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY,
(thread_policy_t)&precedencePolicy,
THREAD_PRECEDENCE_POLICY_COUNT);
if (error != KERN_SUCCESS) {
mach_error("Couldn't set thread precedence policy", error);
}
/* to kill a process, just increment the pt_callback_proc_id */
printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id, parameters->id);
while (pt_callback_proc_id == parameters->id) {
/* wait for a multiple of resolution ms */
UInt64 wait_time;
int delay = mytime++ * parameters->resolution - Pt_Time();
if (delay < 0) delay = 0;
wait_time = AudioConvertNanosToHostTime((UInt64)delay * NSEC_PER_MSEC);
wait_time += AudioGetCurrentHostTime();
error = mach_wait_until(wait_time);
(*(parameters->callback))(Pt_Time(), parameters->userData);
}
printf("Pt_CallbackProc exiting\n");
free(parameters);
return NULL;
}
PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
{
if (time_started_flag) return ptAlreadyStarted;
start_time = AudioGetCurrentHostTime();
if (callback) {
int res;
pt_callback_parameters *parms;
parms = (pt_callback_parameters *) malloc(sizeof(pt_callback_parameters));
if (!parms) return ptInsufficientMemory;
parms->id = pt_callback_proc_id;
parms->resolution = resolution;
parms->callback = callback;
parms->userData = userData;
res = pthread_create(&pt_thread_pid, NULL, Pt_CallbackProc, parms);
if (res != 0) return ptHostError;
}
time_started_flag = TRUE;
return ptNoError;
}
PtError Pt_Stop()
{
printf("Pt_Stop called\n");
pt_callback_proc_id++;
time_started_flag = FALSE;
return ptNoError;
}
int Pt_Started()
{
return time_started_flag;
}
PtTimestamp Pt_Time()
{
UInt64 clock_time, nsec_time;
clock_time = AudioGetCurrentHostTime() - start_time;
nsec_time = AudioConvertHostTimeToNanos(clock_time);
return (PtTimestamp)(nsec_time / NSEC_PER_MSEC);
}
--- NEW FILE: ptmacosx_cf.c ---
/* ptmacosx.c -- portable timer implementation for mac os x */
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <CoreFoundation/CoreFoundation.h>
#import <mach/mach.h>
#import <mach/mach_error.h>
#import <mach/mach_time.h>
#import <mach/clock.h>
#include "porttime.h"
#define THREAD_IMPORTANCE 30
#define LONG_TIME 1000000000.0
static int time_started_flag = FALSE;
static CFAbsoluteTime startTime = 0.0;
static CFRunLoopRef timerRunLoop;
typedef struct {
int resolution;
PtCallback *callback;
void *userData;
} PtThreadParams;
void Pt_CFTimerCallback(CFRunLoopTimerRef timer, void *info)
{
PtThreadParams *params = (PtThreadParams*)info;
(*params->callback)(Pt_Time(), params->userData);
}
static void* Pt_Thread(void *p)
{
CFTimeInterval timerInterval;
CFRunLoopTimerContext timerContext;
CFRunLoopTimerRef timer;
PtThreadParams *params = (PtThreadParams*)p;
//CFTimeInterval timeout;
/* raise the thread's priority */
kern_return_t error;
thread_extended_policy_data_t extendedPolicy;
thread_precedence_policy_data_t precedencePolicy;
extendedPolicy.timeshare = 0;
error = thread_policy_set(mach_thread_self(), THREAD_EXTENDED_POLICY,
(thread_policy_t)&extendedPolicy,
THREAD_EXTENDED_POLICY_COUNT);
if (error != KERN_SUCCESS) {
mach_error("Couldn't set thread timeshare policy", error);
}
precedencePolicy.importance = THREAD_IMPORTANCE;
error = thread_policy_set(mach_thread_self(), THREAD_PRECEDENCE_POLICY,
(thread_policy_t)&precedencePolicy,
THREAD_PRECEDENCE_POLICY_COUNT);
if (error != KERN_SUCCESS) {
mach_error("Couldn't set thread precedence policy", error);
}
/* set up the timer context */
timerContext.version = 0;
timerContext.info = params;
timerContext.retain = NULL;
timerContext.release = NULL;
timerContext.copyDescription = NULL;
/* create a new timer */
timerInterval = (double)params->resolution / 1000.0;
timer = CFRunLoopTimerCreate(NULL, startTime+timerInterval, timerInterval,
0, 0, Pt_CFTimerCallback, &timerContext);
timerRunLoop = CFRunLoopGetCurrent();
CFRunLoopAddTimer(timerRunLoop, timer, CFSTR("PtTimeMode"));
/* run until we're told to stop by Pt_Stop() */
CFRunLoopRunInMode(CFSTR("PtTimeMode"), LONG_TIME, false);
CFRunLoopRemoveTimer(CFRunLoopGetCurrent(), timer, CFSTR("PtTimeMode"));
CFRelease(timer);
free(params);
return NULL;
}
PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
{
PtThreadParams *params = (PtThreadParams*)malloc(sizeof(PtThreadParams));
pthread_t pthread_id;
printf("Pt_Start() called\n");
// /* make sure we're not already playing */
if (time_started_flag) return ptAlreadyStarted;
startTime = CFAbsoluteTimeGetCurrent();
if (callback) {
params->resolution = resolution;
params->callback = callback;
params->userData = userData;
pthread_create(&pthread_id, NULL, Pt_Thread, params);
}
time_started_flag = TRUE;
return ptNoError;
}
PtError Pt_Stop()
{
printf("Pt_Stop called\n");
CFRunLoopStop(timerRunLoop);
time_started_flag = FALSE;
return ptNoError;
}
int Pt_Started()
{
return time_started_flag;
}
PtTimestamp Pt_Time()
{
CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
return (PtTimestamp) ((now - startTime) * 1000.0);
}
--- NEW FILE: ptlinux.c ---
/* ptlinux.c -- portable timer implementation for linux */
/* IMPLEMENTATION NOTES (by Mark Nelson):
Unlike Windows, Linux has no system call to request a periodic callback,
so if Pt_Start() receives a callback parameter, it must create a thread
that wakes up periodically and calls the provided callback function.
If running as superuser, use setpriority() to renice thread to -20.
One could also set the timer thread to a real-time priority (SCHED_FIFO
and SCHED_RR), but this is dangerous for This is necessary because
if the callback hangs it'll never return. A more serious reason
is that the current scheduler implementation busy-waits instead
of sleeping when realtime threads request a sleep of <=2ms (as a way
to get around the 10ms granularity), which means the thread would never
let anyone else on the CPU.
CHANGE LOG
18-Jul-03 Roger Dannenberg -- Simplified code to set priority of timer
thread. Simplified implementation notes.
*/
#include "porttime.h"
#include "sys/time.h"
#include "sys/resource.h"
#include "sys/timeb.h"
#include "pthread.h"
#define TRUE 1
#define FALSE 0
static int time_started_flag = FALSE;
static struct timeb time_offset = {0, 0, 0, 0};
static pthread_t pt_thread_pid;
/* note that this is static data -- we only need one copy */
typedef struct {
int id;
int resolution;
PtCallback *callback;
void *userData;
} pt_callback_parameters;
static int pt_callback_proc_id = 0;
static void *Pt_CallbackProc(void *p)
{
pt_callback_parameters *parameters = (pt_callback_parameters *) p;
int mytime = 1;
/* to kill a process, just increment the pt_callback_proc_id */
/* printf("pt_callback_proc_id %d, id %d\n", pt_callback_proc_id,
parameters->id); */
if (geteuid() == 0) setpriority(PRIO_PROCESS, 0, -20);
while (pt_callback_proc_id == parameters->id) {
/* wait for a multiple of resolution ms */
struct timeval timeout;
int delay = mytime++ * parameters->resolution - Pt_Time();
if (delay < 0) delay = 0;
timeout.tv_sec = 0;
timeout.tv_usec = delay * 1000;
select(0, NULL, NULL, NULL, &timeout);
(*(parameters->callback))(Pt_Time(), parameters->userData);
}
printf("Pt_CallbackProc exiting\n");
// free(parameters);
return NULL;
}
PtError Pt_Start(int resolution, PtCallback *callback, void *userData)
{
if (time_started_flag) return ptNoError;
ftime(&time_offset); /* need this set before process runs */
if (callback) {
int res;
pt_callback_parameters *parms = (pt_callback_parameters *)
malloc(sizeof(pt_callback_parameters));
if (!parms) return ptInsufficientMemory;
parms->id = pt_callback_proc_id;
parms->resolution = resolution;
parms->callback = callback;
parms->userData = userData;
res = pthread_create(&pt_thread_pid, NULL,
Pt_CallbackProc, parms);
if (res != 0) return ptHostError;
}
time_started_flag = TRUE;
return ptNoError;
}
PtError Pt_Stop()
{
printf("Pt_Stop called\n");
pt_callback_proc_id++;
time_started_flag = FALSE;
return ptNoError;
}
int Pt_Started()
{
return time_started_flag;
}
PtTimestamp Pt_Time()
{
long seconds, milliseconds;
struct timeb now;
ftime(&now);
seconds = now.time - time_offset.time;
milliseconds = now.millitm - time_offset.millitm;
return seconds * 1000 + milliseconds;
}
- Previous message: [PD-cvs] pd/portmidi/pm_test latency.c, NONE, 1.1 latency.dsp, NONE, 1.1 midithread.c, NONE, 1.1 midithread.dsp, NONE, 1.1 midithru.c, NONE, 1.1 midithru.dsp, NONE, 1.1 midithru.dsw, NONE, 1.1 sysex.c, NONE, 1.1 sysex.dsp, NONE, 1.1 test.c, NONE, 1.1 test.dsp, NONE, 1.1 txdata.syx, NONE, 1.1
- Next message: [PD-cvs] pd/portmidi/pm_win README_WIN.txt, NONE, 1.1 copy-dll.bat, NONE, 1.1 debugging_dlls.txt, NONE, 1.1 pm_dll.dsp, NONE, 1.1 pmdll.c, NONE, 1.1 pmdll.h, NONE, 1.1 pmwin.c, NONE, 1.1 pmwinmm.c, NONE, 1.1 pmwinmm.h, NONE, 1.1
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list