LCOV - code coverage report
Current view: top level - src - excimer_os_timer_posix.c (source / functions) Hit Total Coverage
Test: mediawiki/php/excimer test coverage report Lines: 32 44 72.7 %
Date: 2024-02-28 22:03:29 Functions: 6 6 100.0 %

          Line data    Source code
       1             : /* Copyright 2024 Wikimedia Foundation
       2             :  *
       3             :  * Licensed under the Apache License, Version 2.0 (the "License");
       4             :  * you may not use this file except in compliance with the License.
       5             :  * You may obtain a copy of the License at
       6             :  *
       7             :  *     http://www.apache.org/licenses/LICENSE-2.0
       8             :  *
       9             :  * Unless required by applicable law or agreed to in writing, software
      10             :  * distributed under the License is distributed on an "AS IS" BASIS,
      11             :  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      12             :  * See the License for the specific language governing permissions and
      13             :  * limitations under the License.
      14             :  */
      15             : 
      16             : #include "excimer_os_timer.h"
      17             : 
      18             : #include <signal.h>
      19             : #include <stdint.h>
      20             : #include <stdio.h>
      21             : #include <string.h>
      22             : #include "php.h"
      23             : #include <pthread.h>
      24             : 
      25          12 : int excimer_os_timer_create(int event_type, intptr_t timer_id, excimer_os_timer_t* os_timer, excimer_os_timer_notify_function_t* notify_function) {
      26             : 
      27             :     struct sigevent ev;
      28             : 
      29          12 :     memset(&ev, 0, sizeof(ev));
      30          12 :     ev.sigev_notify = SIGEV_THREAD;
      31          12 :     ev.sigev_notify_function = notify_function;
      32          12 :     ev.sigev_value.sival_ptr = (void*)timer_id;
      33             : 
      34             :     clockid_t clock_id;
      35             : 
      36          12 :     if (event_type == EXCIMER_CPU) {
      37           1 :         if (pthread_getcpuclockid(pthread_self(), &clock_id) != 0) {
      38           0 :             php_error_docref(NULL, E_WARNING, "Unable to get thread clock ID: %s",
      39           0 :                 strerror(errno));
      40           0 :             return FAILURE;
      41             :         }
      42             :     } else {
      43          11 :         clock_id = CLOCK_MONOTONIC;
      44             :     }
      45             : 
      46          12 :     if (timer_create(clock_id, &ev, &os_timer->os_timer_id) != 0) {
      47           0 :         php_error_docref(NULL, E_WARNING, "Unable to create timer: %s",
      48           0 :             strerror(errno));
      49           0 :         return FAILURE;
      50             :     }
      51             : 
      52          12 :     os_timer->id = timer_id;
      53             : 
      54          12 :     return SUCCESS;
      55             : }
      56             : 
      57          12 : int excimer_os_timer_start(excimer_os_timer_t* os_timer, struct timespec *period, struct timespec *initial) {
      58             :     struct itimerspec its;
      59          12 :     its.it_interval = *period;
      60          12 :     its.it_value = *initial;
      61             : 
      62          12 :     if (timer_settime(os_timer->os_timer_id, 0, &its, NULL) != 0) {
      63           0 :         php_error_docref(NULL, E_WARNING, "timer_settime(): %s", strerror(errno));
      64           0 :         return FAILURE;
      65             :     }
      66             : 
      67          12 :     return SUCCESS;
      68             : }
      69             : 
      70          12 : int excimer_os_timer_stop(excimer_os_timer_t* os_timer) {
      71             :     struct itimerspec its;
      72          12 :     struct timespec zero = {0, 0};
      73          12 :     its.it_interval = zero;
      74          12 :     its.it_value = zero;
      75             : 
      76          12 :     if (timer_settime(os_timer->os_timer_id, 0, &its, NULL) != 0) {
      77           0 :         php_error_docref(NULL, E_WARNING, "timer_settime(): %s", strerror(errno));
      78           0 :         return FAILURE;
      79             :     }
      80             : 
      81          12 :     return SUCCESS;
      82             : }
      83             : 
      84          12 : int excimer_os_timer_delete(excimer_os_timer_t *os_timer) {
      85          12 :     if (timer_delete(os_timer->os_timer_id) != 0) {
      86           0 :         php_error_docref(NULL, E_WARNING, "timer_delete(): %s", strerror(errno));
      87           0 :         return FAILURE;
      88             :     }
      89             : 
      90          12 :     return SUCCESS;
      91             : }
      92             : 
      93          77 : zend_long excimer_os_timer_get_overrun_count(excimer_os_timer_t* os_timer) {
      94          77 :     return timer_getoverrun(os_timer->os_timer_id);
      95             : }
      96             : 
      97           1 : void excimer_os_timer_get_time(excimer_os_timer_t *timer, struct timespec *remaining) {
      98             :     struct itimerspec its;
      99             : 
     100           1 :     timer_gettime(timer->os_timer_id, &its);
     101           1 :     remaining->tv_sec = its.it_value.tv_sec;
     102           1 :     remaining->tv_nsec = its.it_value.tv_nsec;
     103           1 : }

Generated by: LCOV version 1.13