alarm.cc revision 1afbe154a89ad462de739704ce70eed0e32cbc00
131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project/****************************************************************************** 231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Copyright (C) 2014 Google, Inc. 431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * you may not use this file except in compliance with the License. 731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * You may obtain a copy of the License at: 831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 1031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 1131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 1231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 1331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * See the License for the specific language governing permissions and 1531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * limitations under the License. 1631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project * 17a5902524d4403885eb4c50360bf3465c6be796efJoe Onorato ******************************************************************************/ 1831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 198edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka#define LOG_TAG "bt_osi_alarm" 208edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka 21495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell#include <assert.h> 220280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka#include <errno.h> 238edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka#include <hardware/bluetooth.h> 24b1254a6bdb11024042fb6c27e179210c1bbd6e1cChet Haase#include <inttypes.h> 250280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka#include <time.h> 260280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka#include <utils/Log.h> 27cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 28cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy#include "alarm.h" 298edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka#include "list.h" 30cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy#include "osi.h" 3168846fdce6c01bbe474bd0c8307e1ccaac161cbcWinson Chung 328f573952b8729b4319043ae0908997ecd2d68951Dianne Hackbornstruct alarm_t { 33629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy // The lock is held while the callback for this alarm is being executed. 34629de3ef739883c0962423cc0c3a26299f162d3dRomain Guy // It allows us to release the coarse-grained monitor lock while a potentially 35a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // long-running callback is executing. |alarm_cancel| uses this lock to provide 36a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung // a guarantee to its caller that the callback will not be in progress when it 37495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell // returns. 3831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pthread_mutex_t callback_lock; 3931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project period_ms_t deadline; 40495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell alarm_callback_t callback; 415c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy void *data; 427247f6315baf16eacb3286f21bd80321385c1defPatrick Dubroy}; 4331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 444be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratoextern bt_os_callouts_t *bt_os_callouts; 456b879f0a5885274a85333531e091283405d490ccAdam Lesinski 4631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project// If the next wakeup time is less than this threshold, we should acquire 47a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka// a wakelock instead of setting a wake alarm so we're not bouncing in 48a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung// and out of suspend frequently. This value is externally visible to allow 4931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project// unit tests to run faster. It should not be modified by production code. 50a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungint64_t TIMER_INTERVAL_FOR_WAKELOCK_IN_MS = 3000; 514be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onoratostatic const clockid_t CLOCK_ID = CLOCK_BOOTTIME; 52f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectstatic const char *WAKE_LOCK_ID = "bluedroid_timer"; 535c16f3ecd6b47bff3abbe40deb3d39c66a3b0012Romain Guy 54956091ba7863bd72086275e61084864994dd6fa7Joe Onorato// This mutex ensures that the |alarm_set|, |alarm_cancel|, and alarm callback 55495f2892288504f4ab87e62957b3f71144dd73c2Adam Powell// functions execute serially and not concurrently. As a result, this mutex also 5631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project// protects the |alarms| list. 57291ad12232c98e383d44d76ffe09e97e204c61bcDaniel Sandlerstatic pthread_mutex_t monitor; 58580e27748137ff08599aa719d106b31215a28353Winson Chungstatic list_t *alarms; 59a34abf8c781485b788fddacb352d586bffca886cWinson Chungstatic timer_t timer; 60a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungstatic bool timer_set; 6131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 6231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectstatic bool lazy_initialize(void); 63cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroystatic period_ms_t now(void); 64f96811cdf564469a7a654a0c876288c9fd14f35eThe Android Open Source Projectstatic void timer_callback(void *data); 65a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chungstatic void reschedule(void); 6631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 678edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurkaalarm_t *alarm_new(void) { 688edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka // Make sure we have a list we can insert alarms into. 698edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka if (!alarms && !lazy_initialize()) 70edcce099c98a6c40d10109ac092ab50f9d2668f3Romain Guy return NULL; 7131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 720142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka pthread_mutexattr_t attr; 730142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka pthread_mutexattr_init(&attr); 74aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 7531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project alarm_t *ret = calloc(1, sizeof(alarm_t)); 760142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (!ret) { 77dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka ALOGE("%s unable to allocate memory for alarm.", __func__); 78e47f55c30b9c24f01f2be861247c92f17fbe4a61Romain Guy goto error; 793a8820bdbad90642cf5cda4b00a8c92ecb699159Joe Onorato } 800142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 81dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // Make this a recursive mutex to make it safe to call |alarm_cancel| from 82dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka // within the callback function of the alarm. 83dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka int error = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 84a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen if (error) { 85d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka ALOGE("%s unable to create a recursive mutex: %s", __func__, strerror(error)); 86d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka goto error; 87d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka } 88f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 89f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen error = pthread_mutex_init(&ret->callback_lock, &attr); 90a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen if (error) { 91a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen ALOGE("%s unable to initialize mutex: %s", __func__, strerror(error)); 92a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen goto error; 931b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen } 94a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen 951b0aaac0b3abd777ed319341f95a8dfff23c79f4Adam Cohen pthread_mutexattr_destroy(&attr); 96a985e598f6071f4caca15ba3cb6b2cd3e38b217dAdam Cohen return ret; 9768d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen 9868d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohenerror:; 999171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung pthread_mutexattr_destroy(&attr); 100f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen free(ret); 101f135c6c364e92cddb84c1b4a94ed535214b712a6Winson Chung return NULL; 1029171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung} 1039171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 1049171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chungvoid alarm_free(alarm_t *alarm) { 1059171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung if (!alarm) 1069171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung return; 1079171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 1089171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung alarm_cancel(alarm); 1099171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung pthread_mutex_destroy(&alarm->callback_lock); 110472b281d5cb4f5660df981a6c912266b9f5703feChet Haase free(alarm); 111472b281d5cb4f5660df981a6c912266b9f5703feChet Haase} 1129171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung 1138d006d5e144ae33e509ea42e0b9760ef6c5bc884Winson Chung// Runs in exclusion with alarm_cancel and timer_callback. 1148d006d5e144ae33e509ea42e0b9760ef6c5bc884Winson Chungvoid alarm_set(alarm_t *alarm, period_ms_t deadline, alarm_callback_t cb, void *data) { 115f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen assert(alarms != NULL); 11668d739365bf650fe7fecf99cd3bfe63a0d41bd12Adam Cohen assert(alarm != NULL); 117e0f66b546994a9bdee452851c17a148db02ec300Adam Cohen assert(cb != NULL); 118f34bab59fc0260f926aec44d044883dce1b4191fAdam Cohen 11988127038178b3bbf0eb91103a31e682cc0615074Winson Chung pthread_mutex_lock(&monitor); 12088127038178b3bbf0eb91103a31e682cc0615074Winson Chung 12188127038178b3bbf0eb91103a31e682cc0615074Winson Chung // If the alarm is currently set and it's at the start of the list, 12288127038178b3bbf0eb91103a31e682cc0615074Winson Chung // we'll need to re-schedule since we've adjusted the earliest deadline. 12388127038178b3bbf0eb91103a31e682cc0615074Winson Chung bool needs_reschedule = (!list_is_empty(alarms) && list_front(alarms) == alarm); 1248f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn if (alarm->callback) 125aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung list_remove(alarms, alarm); 1260142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka 12731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project alarm->deadline = now() + deadline; 12821f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen alarm->callback = cb; 129d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka alarm->data = data; 13021f12b52a54d2658ed14fcf7bb1ca17a198f62beAdam Cohen 13131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Add it into the timer list sorted by deadline (earliest deadline first). 13231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (list_is_empty(alarms)) 13331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project list_prepend(alarms, alarm); 13431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project else 135aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung for (list_node_t *node = list_begin(alarms); node != list_end(alarms); node = list_next(node)) { 13670864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey list_node_t *next = list_next(node); 13770864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey if (next == list_end(alarms) || ((alarm_t *)list_node(next))->deadline >= alarm->deadline) { 13870864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey list_insert_after(alarms, node, alarm); 13970864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey break; 14031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 1416569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy } 1426569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy 1436569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy // If the new alarm has the earliest deadline, we need to re-evaluate our schedule. 1446569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy if (needs_reschedule || (!list_is_empty(alarms) && list_front(alarms) == alarm)) 1456569f2c80e179c2f8ed73dae6b01d971ec20f005Patrick Dubroy reschedule(); 14631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1470589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato pthread_mutex_unlock(&monitor); 14800acb123c5100f06b8e89e8ec8978ebafc6f6d26Joe Onorato} 149aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung 1504516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurkavoid alarm_cancel(alarm_t *alarm) { 1514516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka assert(alarms != NULL); 15231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project assert(alarm != NULL); 15370864289fba6daf07b8de98524cdfb765a62552dJeff Sharkey 1540280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka pthread_mutex_lock(&monitor); 155a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka 1564516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka bool needs_reschedule = (!list_is_empty(alarms) && list_front(alarms) == alarm); 1574516c11039d77066281f69f9b5d30fdaf1bc05aeMichael Jurka 158a63c452f5bd491ba9b28c332ccedc6c6c7e2f3ccMichael Jurka list_remove(alarms, alarm); 1590280c3be4d9f8fc6fdf015b7ecd276eb26f76f2dMichael Jurka alarm->deadline = 0; 16031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project alarm->callback = NULL; 161c2f7f4794867cd1b3e97fd0f379ad8ad15958a6cMichael Jurka alarm->data = NULL; 162d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka 163d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen if (needs_reschedule) 164d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen reschedule(); 16531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 1668a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy pthread_mutex_unlock(&monitor); 1678a73c51ee87b6d9b12daba188034889caf7a905bRomain Guy 168aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung // If the callback for |alarm| is in progress, wait here until it completes. 1691262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy pthread_mutex_lock(&alarm->callback_lock); 170dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka pthread_mutex_unlock(&alarm->callback_lock); 171c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka} 172c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka 173bea15195346bab3c52b0156e92f2b71f0811b210Michael Jurkastatic bool lazy_initialize(void) { 174b8e14479da7209ca811a753b3256fe4a0b49a873Michael Jurka assert(alarms == NULL); 175af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka 176af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka pthread_mutex_init(&monitor, NULL); 177d3ef3065ab0941567c45e9aec98783138b623c68Michael Jurka 178883f55b1d261862b0de1b43af0b17d351761a9c6Michael Jurka alarms = list_new(NULL); 179af91de06b99e2d5d41ce79fefa34ce2111e51917Michael Jurka if (!alarms) { 1803c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka ALOGE("%s unable to allocate alarm list.", __func__); 181dee0589388ba0f6373912e18bf86243282fb3b9bMichael Jurka return false; 18254fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroy } 1831262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy 1841262e369484ce7f2565655ed80e6299232c70bd7Patrick Dubroy return true; 18554fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroy} 18654fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroy 18754fa3b95557c283976e8c1aa8a157b460b0b4513Patrick Dubroystatic period_ms_t now(void) { 1888e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy assert(alarms != NULL); 1894be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato 1908e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy struct timespec ts; 1918e58e916061cbe2623697efac0924f2aa3753a92Patrick Dubroy if (clock_gettime(CLOCK_ID, &ts) == -1) { 1924be866d3a1665aa2098cb5d38d535b1ad1aab6d6Joe Onorato ALOGE("%s unable to get current time: %s", __func__, strerror(errno)); 193cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy return 0; 194cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy } 195cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy 196cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy return (ts.tv_sec * 1000LL) + (ts.tv_nsec / 1000000LL); 197cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy} 198a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 199a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung// Warning: this function is called in the context of an unknown thread. 200a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung// As a result, it must be thread-safe relative to other operations on 2016b879f0a5885274a85333531e091283405d490ccAdam Lesinski// the alarm list. 2026b879f0a5885274a85333531e091283405d490ccAdam Lesinskistatic void timer_callback(void *ptr) { 2036b879f0a5885274a85333531e091283405d490ccAdam Lesinski alarm_t *alarm = (alarm_t *)ptr; 2046b879f0a5885274a85333531e091283405d490ccAdam Lesinski assert(alarm != NULL); 2056b879f0a5885274a85333531e091283405d490ccAdam Lesinski 206c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka pthread_mutex_lock(&monitor); 207c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 208c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka bool alarm_valid = list_remove(alarms, alarm); 209c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka alarm_callback_t callback = alarm->callback; 210c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka void *data = alarm->data; 211c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 212c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka alarm->deadline = 0; 213c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka alarm->callback = NULL; 214c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka alarm->data = NULL; 215c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka 216c5b262ccf639fedac2aff5bb8238342f95396338Michael Jurka reschedule(); 21731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 21831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // The alarm was cancelled before we got to it. Release the monitor 21931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // lock and exit right away since there's nothing left to do. 22031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (!alarm_valid) { 2210142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka pthread_mutex_unlock(&monitor); 22231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 22331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 22431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project // Downgrade lock. 22631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pthread_mutex_lock(&alarm->callback_lock); 22731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project pthread_mutex_unlock(&monitor); 22831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 22931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project callback(data); 23031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 2310142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka pthread_mutex_unlock(&alarm->callback_lock); 23231dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project} 23331dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 23431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project// NOTE: must be called with monitor lock. 23531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Projectstatic void reschedule(void) { 2360142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka assert(alarms != NULL); 2375f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka 2385f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka if (timer_set) { 2395f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka timer_delete(timer); 2405f1c509d5ad1954a7e38e77db4d5f27c7345fd39Michael Jurka timer_set = false; 24131dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 2428f573952b8729b4319043ae0908997ecd2d68951Dianne Hackborn 243aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung if (list_is_empty(alarms)) { 244aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung bt_os_callouts->release_wake_lock(WAKE_LOCK_ID); 245aafa03cbb925c74be1c13f8bb99d928be429e62fWinson Chung return; 246d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen } 247d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen 2480142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka alarm_t *next = list_front(alarms); 24931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project int64_t next_exp = next->deadline - now(); 25031dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project if (next_exp < TIMER_INTERVAL_FOR_WAKELOCK_IN_MS) { 251d22015cd37ea6ef53762eca5be57daca123ff607Adam Cohen int status = bt_os_callouts->acquire_wake_lock(WAKE_LOCK_ID); 2520d44e9482b95d8f163b28bf20131c4349185b589Joe Onorato if (status != BT_STATUS_SUCCESS) { 2530142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka ALOGE("%s unable to acquire wake lock: %d", __func__, status); 25431dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project return; 25531dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project } 25631dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project 25731dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project struct sigevent sigevent; 25831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project memset(&sigevent, 0, sizeof(sigevent)); 25931dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project sigevent.sigev_notify = SIGEV_THREAD; 2600142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka sigevent.sigev_notify_function = (void (*)(union sigval))timer_callback; 2610589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato sigevent.sigev_value.sival_ptr = next; 2620142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka if (timer_create(CLOCK_ID, &sigevent, &timer) == -1) { 2630142d49e1378a7155bcca1fb59965d9e73016dbcMichael Jurka ALOGE("%s unable to create timer: %s", __func__, strerror(errno)); 2640589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato return; 2650589f0f66ce498512c6ee47482c649d88294c9d0Joe Onorato } 266a9abd0e0bdedb5cbbd12b84cb83037a735e79a20Winson Chung 267cd68ff5b88de9b5136ff5a9ef698e4db2fc5db66Patrick Dubroy struct itimerspec wakeup_time; 26831dd503c6aa69018e694d91724d46db49ea09327The Android Open Source Project memset(&wakeup_time, 0, sizeof(wakeup_time)); 269b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung wakeup_time.it_value.tv_sec = (next->deadline / 1000); 270b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung wakeup_time.it_value.tv_nsec = (next->deadline % 1000) * 1000000LL; 271b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung if (timer_settime(timer, TIMER_ABSTIME, &wakeup_time, NULL) == -1) { 2728d006d5e144ae33e509ea42e0b9760ef6c5bc884Winson Chung ALOGE("%s unable to set timer: %s", __func__, strerror(errno)); 273b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung timer_delete(timer); 274b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung return; 275b4b7fa7c0383b6af58d73d3e024b91d586148cf8Winson Chung } 2769171e6d8a2b7b5aa136617b9779a8bbadc5259f7Winson Chung timer_set = true; 2778edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka } else { 2783c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka if (!bt_os_callouts->set_wake_alarm(next_exp, true, timer_callback, next)) 279c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka ALOGE("%s unable to set wake alarm for %" PRId64 "ms.", __func__, next_exp); 280c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka 281bea15195346bab3c52b0156e92f2b71f0811b210Michael Jurka bt_os_callouts->release_wake_lock(WAKE_LOCK_ID); 282c0e8fcae492730210b2b8b6d5bb3d65636bad245Michael Jurka } 2833c4c20fbe682cb4b3ef94f09afe0af09171583f3Michael Jurka} 2848edd75c8bb0729a10cb39f614183e3e9ae4288e8Michael Jurka