• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2021 The TensorFlow Authors. All Rights Reserved.
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 #ifndef TENSORFLOW_LITE_EXPERIMENTAL_ACCELERATION_MINI_BENCHMARK_LIBC_HANDLE_H_
16 #define TENSORFLOW_LITE_EXPERIMENTAL_ACCELERATION_MINI_BENCHMARK_LIBC_HANDLE_H_
17 
18 #ifdef __ANDROID__
19 #include <dlfcn.h>
20 #endif
21 
22 #include <cstdio>
23 #include <memory>
24 #include <utility>
25 
26 #include "tensorflow/lite/experimental/acceleration/mini_benchmark/decode_jpeg_status.h"
27 
28 namespace tflite {
29 namespace acceleration {
30 namespace decode_jpeg_kernel {
31 
32 // This class offers a handle to C Standard Library (LibC) shared object
33 // library on Android. It offers pointers to functions in LibC.
34 // Fmemopen is available as native API from Android SDK 23 onwards. In order to
35 // support Android devices from SDK 21 onwards, we load fmemopen dynamically
36 // from the libc shared object library.
37 // TODO(b/172544567): Support Apple.
38 class LibCHandle {
39  public:
40   // Factory to get an initialised instance of LibCHandle.
41   // Loads the libc dynamic library and gets handle to all the
42   // required functions. Stores the initialisation status in `status`.
43   static LibCHandle Create(Status& status);
44   LibCHandle(LibCHandle const&) = delete;
45   LibCHandle& operator=(const LibCHandle&) = delete;
LibCHandle(LibCHandle && other)46   LibCHandle(LibCHandle&& other)
47       : libc_(std::exchange(other.libc_, nullptr)),
48         fmemopen_(std::exchange(other.fmemopen_, nullptr)) {}
49   LibCHandle& operator=(LibCHandle&& other) {
50     if (&other != this) {
51       CloseHandle();
52       libc_ = std::exchange(other.libc_, nullptr);
53       fmemopen_ = std::exchange(other.fmemopen_, nullptr);
54     }
55     return *this;
56   }
~LibCHandle()57   ~LibCHandle() { CloseHandle(); }
58   // Definition can be found here
59   // https://man7.org/linux/man-pages/man3/fmemopen.3.html
60   FILE* fmemopen(void* buf, size_t size, const char* mode) const;
61 
62  private:
63   using FmemopenPtr = FILE* (*)(void*, size_t, const char*);
LibCHandle(void * libc,FmemopenPtr ptr)64   LibCHandle(void* libc, FmemopenPtr ptr) : libc_(libc), fmemopen_(ptr) {}
65   // Closes the dynamic library loaded in libc_.
CloseHandle()66   void CloseHandle() {
67 #ifdef __ANDROID__
68     if (libc_ != nullptr) {
69       dlclose(libc_);
70     }
71 #endif
72   }
73   void* libc_ = nullptr;
74   FmemopenPtr fmemopen_ = nullptr;
75 };
76 
77 }  // namespace decode_jpeg_kernel
78 }  // namespace acceleration
79 }  // namespace tflite
80 
81 #endif  // TENSORFLOW_LITE_EXPERIMENTAL_ACCELERATION_MINI_BENCHMARK_LIBC_HANDLE_H_
82