ps2sdk  1.1
A collection of Open Source libraries used for developing applications on Sony's PlayStation 2® (PS2).
sleep.c File Reference
#include <kernel.h>
#include <errno.h>
#include <time.h>
#include <unistd.h>
#include "ps2sdkapi.h"
+ Include dependency graph for sleep.c:

Go to the source code of this file.

Macros

#define MIN_HSYNC_PER_SEC   (240*50)
 
#define MIN_HSYNC_DELAY   100
 
#define MAX_PS2CLOCK_PER_HSYNC   (PS2_CLOCKS_PER_SEC/MIN_HSYNC_PER_SEC)
 

Functions

static void _sleep_waker (s32 alarm_id, u16 time, void *arg2)
 
static u64 timespec_to_us (const struct timespec *pts)
 
static ps2_clock_t us_to_ps2_clock (u64 us)
 
static ps2_clock_t timespec_to_ps2_clock (const struct timespec *pts)
 
int nanosleep (const struct timespec *req, struct timespec *rem)
 
unsigned int sleep (unsigned int seconds)
 

Variables

static unsigned int iPS2ClockPerHSync = MAX_PS2CLOCK_PER_HSYNC
 

Detailed Description

sleep implementation

Definition in file sleep.c.

Macro Definition Documentation

◆ MAX_PS2CLOCK_PER_HSYNC

#define MAX_PS2CLOCK_PER_HSYNC   (PS2_CLOCKS_PER_SEC/MIN_HSYNC_PER_SEC)

Definition at line 26 of file sleep.c.

◆ MIN_HSYNC_DELAY

#define MIN_HSYNC_DELAY   100

Definition at line 25 of file sleep.c.

◆ MIN_HSYNC_PER_SEC

#define MIN_HSYNC_PER_SEC   (240*50)

Definition at line 24 of file sleep.c.

Function Documentation

◆ _sleep_waker()

static void _sleep_waker ( s32  alarm_id,
u16  time,
void *  arg2 
)
static

Definition at line 31 of file sleep.c.

32 {
33  s32 *pSema = (s32 *)arg2;
34  iSignalSema(*pSema);
35  ExitHandler();
36 }
#define ExitHandler()
Definition: kernel.h:28
s32 iSignalSema(s32 sema_id)
signed int s32
Definition: tamtypes.h:58

References ExitHandler, and iSignalSema().

Referenced by nanosleep().

◆ nanosleep()

int nanosleep ( const struct timespec *  req,
struct timespec *  rem 
)

Definition at line 50 of file sleep.c.

51 {
52  ee_sema_t sema;
53  s32 sema_id;
54  ps2_clock_t clock_delay, clock_end, clock_real_end;
55  u16 hsync_delay;
56 
57  clock_delay = timespec_to_ps2_clock(req);
58  clock_end = ps2_clock() + clock_delay;
59  hsync_delay = clock_delay / iPS2ClockPerHSync;
60 
61  if (hsync_delay >= MIN_HSYNC_DELAY) {
62  sema.init_count = 0;
63  sema.max_count = 1;
64  sema.option = 0;
65  sema_id = CreateSema(&sema);
66 
67  SetAlarm(hsync_delay, _sleep_waker, &sema_id);
68  WaitSema(sema_id);
69  DeleteSema(sema_id);
70 
71  // Correct the HSync delay
72  // NOTE: We're always trying to end btween 0 and 1 HSyncs too short
73  clock_real_end = ps2_clock();
74  if (clock_real_end < (clock_end - iPS2ClockPerHSync)) {
75  // We sleeped too short, so HSyncs must be faster
76  // Correct the HSyncs for next time
77  iPS2ClockPerHSync -= (clock_end - iPS2ClockPerHSync - clock_real_end) / hsync_delay;
78  }
79  else if (clock_real_end > clock_end) {
80  // We sleeped too long, so HSyncs must be slower
81  // Correct the HSyncs for next time
82  iPS2ClockPerHSync += (clock_real_end - clock_end) / (hsync_delay-1);
83  }
84  }
85 
86  // Delay whatever time is left
87  while(clock_end > ps2_clock())
88  ;
89 
90  if (rem != NULL) {
91  rem->tv_sec = 0;
92  rem->tv_nsec = 0;
93  }
94 
95  return 0;
96 }
s32 CreateSema(ee_sema_t *sema)
s32 DeleteSema(s32 sema_id)
s32 WaitSema(s32 sema_id)
s32 SetAlarm(u16 time, void(*callback)(s32 alarm_id, u16 time, void *common), void *common)
uint64_t ps2_clock_t
Definition: ps2sdkapi.h:41
ps2_clock_t ps2_clock(void)
#define MIN_HSYNC_DELAY
Definition: sleep.c:25
static ps2_clock_t timespec_to_ps2_clock(const struct timespec *pts)
Definition: sleep.c:46
static void _sleep_waker(s32 alarm_id, u16 time, void *arg2)
Definition: sleep.c:31
static unsigned int iPS2ClockPerHSync
Definition: sleep.c:29
int init_count
Definition: kernel.h:218
int max_count
Definition: kernel.h:217
u32 option
Definition: kernel.h:221
#define NULL
Definition: tamtypes.h:91
unsigned short u16
Definition: tamtypes.h:24

References _sleep_waker(), CreateSema(), DeleteSema(), ee_sema_t::init_count, iPS2ClockPerHSync, ee_sema_t::max_count, MIN_HSYNC_DELAY, NULL, ee_sema_t::option, ps2_clock(), SetAlarm(), timespec_to_ps2_clock(), and WaitSema().

Referenced by sleep().

◆ sleep()

unsigned int sleep ( unsigned int  seconds)

Definition at line 98 of file sleep.c.

99 {
100  struct timespec ts;
101 
102  ts.tv_sec = seconds;
103  ts.tv_nsec = 0;
104 
105  if (!nanosleep(&ts, &ts))
106  return 0;
107 
108  if (errno == EINTR)
109  return ts.tv_sec;
110 
111  return -1;
112 }
#define EINTR
Definition: errno.h:26
int errno
int nanosleep(const struct timespec *req, struct timespec *rem)
Definition: sleep.c:50

References EINTR, errno, and nanosleep().

Referenced by main().

◆ timespec_to_ps2_clock()

static ps2_clock_t timespec_to_ps2_clock ( const struct timespec *  pts)
inlinestatic

Definition at line 46 of file sleep.c.

46  {
47  return us_to_ps2_clock(timespec_to_us(pts));
48 }
static ps2_clock_t us_to_ps2_clock(u64 us)
Definition: sleep.c:42
static u64 timespec_to_us(const struct timespec *pts)
Definition: sleep.c:38

References timespec_to_us(), and us_to_ps2_clock().

Referenced by nanosleep().

◆ timespec_to_us()

static u64 timespec_to_us ( const struct timespec *  pts)
inlinestatic

Definition at line 38 of file sleep.c.

38  {
39  return (pts->tv_sec * 1000000ULL) + (pts->tv_nsec / 1000ULL);
40 }

Referenced by timespec_to_ps2_clock().

◆ us_to_ps2_clock()

static ps2_clock_t us_to_ps2_clock ( u64  us)
inlinestatic

Definition at line 42 of file sleep.c.

42  {
43  return (us * PS2_CLOCKS_PER_MSEC) / 1000;
44 }
#define PS2_CLOCKS_PER_MSEC
Definition: ps2sdkapi.h:39

References PS2_CLOCKS_PER_MSEC.

Referenced by timespec_to_ps2_clock().

Variable Documentation

◆ iPS2ClockPerHSync

unsigned int iPS2ClockPerHSync = MAX_PS2CLOCK_PER_HSYNC
static

Definition at line 29 of file sleep.c.

Referenced by nanosleep().