diff options
Diffstat (limited to 'kernel/posix-cpu-timers.c')
| -rw-r--r-- | kernel/posix-cpu-timers.c | 110 |
1 files changed, 52 insertions, 58 deletions
diff --git a/kernel/posix-cpu-timers.c b/kernel/posix-cpu-timers.c index 05bb7173850..67fea9d25d5 100644 --- a/kernel/posix-cpu-timers.c +++ b/kernel/posix-cpu-timers.c | |||
| @@ -176,7 +176,8 @@ static inline cputime_t virt_ticks(struct task_struct *p) | |||
| 176 | return p->utime; | 176 | return p->utime; |
| 177 | } | 177 | } |
| 178 | 178 | ||
| 179 | int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) | 179 | static int |
| 180 | posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) | ||
| 180 | { | 181 | { |
| 181 | int error = check_clock(which_clock); | 182 | int error = check_clock(which_clock); |
| 182 | if (!error) { | 183 | if (!error) { |
| @@ -194,7 +195,8 @@ int posix_cpu_clock_getres(const clockid_t which_clock, struct timespec *tp) | |||
| 194 | return error; | 195 | return error; |
| 195 | } | 196 | } |
| 196 | 197 | ||
| 197 | int posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp) | 198 | static int |
| 199 | posix_cpu_clock_set(const clockid_t which_clock, const struct timespec *tp) | ||
| 198 | { | 200 | { |
| 199 | /* | 201 | /* |
| 200 | * You can never reset a CPU clock, but we check for other errors | 202 | * You can never reset a CPU clock, but we check for other errors |
| @@ -317,7 +319,7 @@ static int cpu_clock_sample_group(const clockid_t which_clock, | |||
| 317 | } | 319 | } |
| 318 | 320 | ||
| 319 | 321 | ||
| 320 | int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) | 322 | static int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) |
| 321 | { | 323 | { |
| 322 | const pid_t pid = CPUCLOCK_PID(which_clock); | 324 | const pid_t pid = CPUCLOCK_PID(which_clock); |
| 323 | int error = -EINVAL; | 325 | int error = -EINVAL; |
| @@ -379,7 +381,7 @@ int posix_cpu_clock_get(const clockid_t which_clock, struct timespec *tp) | |||
| 379 | * This is called from sys_timer_create() and do_cpu_nanosleep() with the | 381 | * This is called from sys_timer_create() and do_cpu_nanosleep() with the |
| 380 | * new timer already all-zeros initialized. | 382 | * new timer already all-zeros initialized. |
| 381 | */ | 383 | */ |
| 382 | int posix_cpu_timer_create(struct k_itimer *new_timer) | 384 | static int posix_cpu_timer_create(struct k_itimer *new_timer) |
| 383 | { | 385 | { |
| 384 | int ret = 0; | 386 | int ret = 0; |
| 385 | const pid_t pid = CPUCLOCK_PID(new_timer->it_clock); | 387 | const pid_t pid = CPUCLOCK_PID(new_timer->it_clock); |
| @@ -425,7 +427,7 @@ int posix_cpu_timer_create(struct k_itimer *new_timer) | |||
| 425 | * If we return TIMER_RETRY, it's necessary to release the timer's lock | 427 | * If we return TIMER_RETRY, it's necessary to release the timer's lock |
| 426 | * and try again. (This happens when the timer is in the middle of firing.) | 428 | * and try again. (This happens when the timer is in the middle of firing.) |
| 427 | */ | 429 | */ |
| 428 | int posix_cpu_timer_del(struct k_itimer *timer) | 430 | static int posix_cpu_timer_del(struct k_itimer *timer) |
| 429 | { | 431 | { |
| 430 | struct task_struct *p = timer->it.cpu.task; | 432 | struct task_struct *p = timer->it.cpu.task; |
| 431 | int ret = 0; | 433 | int ret = 0; |
| @@ -665,8 +667,8 @@ static int cpu_timer_sample_group(const clockid_t which_clock, | |||
| 665 | * If we return TIMER_RETRY, it's necessary to release the timer's lock | 667 | * If we return TIMER_RETRY, it's necessary to release the timer's lock |
| 666 | * and try again. (This happens when the timer is in the middle of firing.) | 668 | * and try again. (This happens when the timer is in the middle of firing.) |
| 667 | */ | 669 | */ |
| 668 | int posix_cpu_timer_set(struct k_itimer *timer, int flags, | 670 | static int posix_cpu_timer_set(struct k_itimer *timer, int flags, |
| 669 | struct itimerspec *new, struct itimerspec *old) | 671 | struct itimerspec *new, struct itimerspec *old) |
| 670 | { | 672 | { |
| 671 | struct task_struct *p = timer->it.cpu.task; | 673 | struct task_struct *p = timer->it.cpu.task; |
| 672 | union cpu_time_count old_expires, new_expires, old_incr, val; | 674 | union cpu_time_count old_expires, new_expires, old_incr, val; |
| @@ -820,7 +822,7 @@ int posix_cpu_timer_set(struct k_itimer *timer, int flags, | |||
| 820 | return ret; | 822 | return ret; |
| 821 | } | 823 | } |
| 822 | 824 | ||
| 823 | void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) | 825 | static void posix_cpu_timer_get(struct k_itimer *timer, struct itimerspec *itp) |
| 824 | { | 826 | { |
| 825 | union cpu_time_count now; | 827 | union cpu_time_count now; |
| 826 | struct task_struct *p = timer->it.cpu.task; | 828 | struct task_struct *p = timer->it.cpu.task; |
| @@ -1481,11 +1483,13 @@ static int do_cpu_nanosleep(const clockid_t which_clock, int flags, | |||
| 1481 | return error; | 1483 | return error; |
| 1482 | } | 1484 | } |
| 1483 | 1485 | ||
| 1484 | int posix_cpu_nsleep(const clockid_t which_clock, int flags, | 1486 | static long posix_cpu_nsleep_restart(struct restart_block *restart_block); |
| 1485 | struct timespec *rqtp, struct timespec __user *rmtp) | 1487 | |
| 1488 | static int posix_cpu_nsleep(const clockid_t which_clock, int flags, | ||
| 1489 | struct timespec *rqtp, struct timespec __user *rmtp) | ||
| 1486 | { | 1490 | { |
| 1487 | struct restart_block *restart_block = | 1491 | struct restart_block *restart_block = |
| 1488 | ¤t_thread_info()->restart_block; | 1492 | ¤t_thread_info()->restart_block; |
| 1489 | struct itimerspec it; | 1493 | struct itimerspec it; |
| 1490 | int error; | 1494 | int error; |
| 1491 | 1495 | ||
| @@ -1501,56 +1505,47 @@ int posix_cpu_nsleep(const clockid_t which_clock, int flags, | |||
| 1501 | 1505 | ||
| 1502 | if (error == -ERESTART_RESTARTBLOCK) { | 1506 | if (error == -ERESTART_RESTARTBLOCK) { |
| 1503 | 1507 | ||
| 1504 | if (flags & TIMER_ABSTIME) | 1508 | if (flags & TIMER_ABSTIME) |
| 1505 | return -ERESTARTNOHAND; | 1509 | return -ERESTARTNOHAND; |
| 1506 | /* | 1510 | /* |
| 1507 | * Report back to the user the time still remaining. | 1511 | * Report back to the user the time still remaining. |
| 1508 | */ | 1512 | */ |
| 1509 | if (rmtp != NULL && copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) | 1513 | if (rmtp && copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) |
| 1510 | return -EFAULT; | 1514 | return -EFAULT; |
| 1511 | 1515 | ||
| 1512 | restart_block->fn = posix_cpu_nsleep_restart; | 1516 | restart_block->fn = posix_cpu_nsleep_restart; |
| 1513 | restart_block->arg0 = which_clock; | 1517 | restart_block->nanosleep.index = which_clock; |
| 1514 | restart_block->arg1 = (unsigned long) rmtp; | 1518 | restart_block->nanosleep.rmtp = rmtp; |
| 1515 | restart_block->arg2 = rqtp->tv_sec; | 1519 | restart_block->nanosleep.expires = timespec_to_ns(rqtp); |
| 1516 | restart_block->arg3 = rqtp->tv_nsec; | ||
| 1517 | } | 1520 | } |
| 1518 | return error; | 1521 | return error; |
| 1519 | } | 1522 | } |
| 1520 | 1523 | ||
| 1521 | long posix_cpu_nsleep_restart(struct restart_block *restart_block) | 1524 | static long posix_cpu_nsleep_restart(struct restart_block *restart_block) |
| 1522 | { | 1525 | { |
| 1523 | clockid_t which_clock = restart_block->arg0; | 1526 | clockid_t which_clock = restart_block->nanosleep.index; |
| 1524 | struct timespec __user *rmtp; | ||
| 1525 | struct timespec t; | 1527 | struct timespec t; |
| 1526 | struct itimerspec it; | 1528 | struct itimerspec it; |
| 1527 | int error; | 1529 | int error; |
| 1528 | 1530 | ||
| 1529 | rmtp = (struct timespec __user *) restart_block->arg1; | 1531 | t = ns_to_timespec(restart_block->nanosleep.expires); |
| 1530 | t.tv_sec = restart_block->arg2; | ||
| 1531 | t.tv_nsec = restart_block->arg3; | ||
| 1532 | 1532 | ||
| 1533 | restart_block->fn = do_no_restart_syscall; | ||
| 1534 | error = do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t, &it); | 1533 | error = do_cpu_nanosleep(which_clock, TIMER_ABSTIME, &t, &it); |
| 1535 | 1534 | ||
| 1536 | if (error == -ERESTART_RESTARTBLOCK) { | 1535 | if (error == -ERESTART_RESTARTBLOCK) { |
| 1536 | struct timespec __user *rmtp = restart_block->nanosleep.rmtp; | ||
| 1537 | /* | 1537 | /* |
| 1538 | * Report back to the user the time still remaining. | 1538 | * Report back to the user the time still remaining. |
| 1539 | */ | 1539 | */ |
| 1540 | if (rmtp != NULL && copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) | 1540 | if (rmtp && copy_to_user(rmtp, &it.it_value, sizeof *rmtp)) |
| 1541 | return -EFAULT; | 1541 | return -EFAULT; |
| 1542 | 1542 | ||
| 1543 | restart_block->fn = posix_cpu_nsleep_restart; | 1543 | restart_block->nanosleep.expires = timespec_to_ns(&t); |
| 1544 | restart_block->arg0 = which_clock; | ||
| 1545 | restart_block->arg1 = (unsigned long) rmtp; | ||
| 1546 | restart_block->arg2 = t.tv_sec; | ||
| 1547 | restart_block->arg3 = t.tv_nsec; | ||
| 1548 | } | 1544 | } |
| 1549 | return error; | 1545 | return error; |
| 1550 | 1546 | ||
| 1551 | } | 1547 | } |
| 1552 | 1548 | ||
| 1553 | |||
| 1554 | #define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED) | 1549 | #define PROCESS_CLOCK MAKE_PROCESS_CPUCLOCK(0, CPUCLOCK_SCHED) |
| 1555 | #define THREAD_CLOCK MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED) | 1550 | #define THREAD_CLOCK MAKE_THREAD_CPUCLOCK(0, CPUCLOCK_SCHED) |
| 1556 | 1551 | ||
| @@ -1594,38 +1589,37 @@ static int thread_cpu_timer_create(struct k_itimer *timer) | |||
| 1594 | timer->it_clock = THREAD_CLOCK; | 1589 | timer->it_clock = THREAD_CLOCK; |
| 1595 | return posix_cpu_timer_create(timer); | 1590 | return posix_cpu_timer_create(timer); |
| 1596 | } | 1591 | } |
| 1597 | static int thread_cpu_nsleep(const clockid_t which_clock, int flags, | 1592 | |
| 1598 | struct timespec *rqtp, struct timespec __user *rmtp) | 1593 | struct k_clock clock_posix_cpu = { |
| 1599 | { | 1594 | .clock_getres = posix_cpu_clock_getres, |
| 1600 | return -EINVAL; | 1595 | .clock_set = posix_cpu_clock_set, |
| 1601 | } | 1596 | .clock_get = posix_cpu_clock_get, |
| 1602 | static long thread_cpu_nsleep_restart(struct restart_block *restart_block) | 1597 | .timer_create = posix_cpu_timer_create, |
| 1603 | { | 1598 | .nsleep = posix_cpu_nsleep, |
| 1604 | return -EINVAL; | 1599 | .nsleep_restart = posix_cpu_nsleep_restart, |
| 1605 | } | 1600 | .timer_set = posix_cpu_timer_set, |
| 1601 | .timer_del = posix_cpu_timer_del, | ||
| 1602 | .timer_get = posix_cpu_timer_get, | ||
| 1603 | }; | ||
| 1606 | 1604 | ||
| 1607 | static __init int init_posix_cpu_timers(void) | 1605 | static __init int init_posix_cpu_timers(void) |
| 1608 | { | 1606 | { |
| 1609 | struct k_clock process = { | 1607 | struct k_clock process = { |
| 1610 | .clock_getres = process_cpu_clock_getres, | 1608 | .clock_getres = process_cpu_clock_getres, |
| 1611 | .clock_get = process_cpu_clock_get, | 1609 | .clock_get = process_cpu_clock_get, |
| 1612 | .clock_set = do_posix_clock_nosettime, | 1610 | .timer_create = process_cpu_timer_create, |
| 1613 | .timer_create = process_cpu_timer_create, | 1611 | .nsleep = process_cpu_nsleep, |
| 1614 | .nsleep = process_cpu_nsleep, | 1612 | .nsleep_restart = process_cpu_nsleep_restart, |
| 1615 | .nsleep_restart = process_cpu_nsleep_restart, | ||
| 1616 | }; | 1613 | }; |
| 1617 | struct k_clock thread = { | 1614 | struct k_clock thread = { |
| 1618 | .clock_getres = thread_cpu_clock_getres, | 1615 | .clock_getres = thread_cpu_clock_getres, |
| 1619 | .clock_get = thread_cpu_clock_get, | 1616 | .clock_get = thread_cpu_clock_get, |
| 1620 | .clock_set = do_posix_clock_nosettime, | 1617 | .timer_create = thread_cpu_timer_create, |
| 1621 | .timer_create = thread_cpu_timer_create, | ||
| 1622 | .nsleep = thread_cpu_nsleep, | ||
| 1623 | .nsleep_restart = thread_cpu_nsleep_restart, | ||
| 1624 | }; | 1618 | }; |
| 1625 | struct timespec ts; | 1619 | struct timespec ts; |
| 1626 | 1620 | ||
| 1627 | register_posix_clock(CLOCK_PROCESS_CPUTIME_ID, &process); | 1621 | posix_timers_register_clock(CLOCK_PROCESS_CPUTIME_ID, &process); |
| 1628 | register_posix_clock(CLOCK_THREAD_CPUTIME_ID, &thread); | 1622 | posix_timers_register_clock(CLOCK_THREAD_CPUTIME_ID, &thread); |
| 1629 | 1623 | ||
| 1630 | cputime_to_timespec(cputime_one_jiffy, &ts); | 1624 | cputime_to_timespec(cputime_one_jiffy, &ts); |
| 1631 | onecputick = ts.tv_nsec; | 1625 | onecputick = ts.tv_nsec; |
