• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 *
3 * SPDX-License-Identifier: GPL-2.0
4 *
5 * Copyright (C) 2011-2018 ARM or its affiliates
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13 * for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 *
18 */
19 
20 #include "acamera_event_queue.h"
21 #include "acamera_logger.h"
22 #include "system_spinlock.h"
23 
24 static uint32_t reset_threshold = 1;
25 static uint64_t avail_event_mask;
26 
acamera_event_queue_reset(acamera_loop_buf_ptr_t p_buf)27 static void acamera_event_queue_reset( acamera_loop_buf_ptr_t p_buf )
28 {
29     p_buf->head = p_buf->tail = 0;
30     avail_event_mask = 0;
31 }
32 
acamera_event_queue_push(acamera_event_queue_ptr_t p_queue,int event)33 void acamera_event_queue_push( acamera_event_queue_ptr_t p_queue, int event )
34 {
35     int err = 0;
36     acamera_loop_buf_ptr_t p_buf = &( p_queue->buf );
37     unsigned long flags;
38 
39     flags = system_spinlock_lock( p_queue->lock );
40 
41     if ( ( p_buf->head < 0 ) ||
42          ( p_buf->head >= p_buf->data_buf_size ) ||
43          ( p_buf->tail < 0 ) ||
44          ( p_buf->tail >= p_buf->data_buf_size ) ) {
45         err = -1;
46     }
47 
48     if ((1 << event) & avail_event_mask) {
49         err = 0;
50         LOG( LOG_DEBUG, "event %d is duplicated, skip it at this time", event);
51     } else {
52         int pos = acamera_loop_buffer_write_u8( p_buf, 0, (uint8_t)event );
53         if ( pos != p_buf->tail ) {
54             p_buf->head = pos;
55             avail_event_mask |= (1 << event);
56         } else {
57             err = -2;
58             acamera_event_queue_reset( p_buf );
59         }
60     }
61 
62     system_spinlock_unlock( p_queue->lock, flags );
63 
64     if ( -1 == err ) {
65         LOG( LOG_ERR, "Event Queue Corrupted\n" );
66     } else if ( -2 == err ) {
67         static uint32_t counter = 0;
68         if ( !( counter++ & 0x3F ) )
69             LOG( LOG_CRIT, "Event Queue overflow\n" );
70     }
71 }
72 
acamera_event_queue_pop(acamera_event_queue_ptr_t p_queue)73 int acamera_event_queue_pop( acamera_event_queue_ptr_t p_queue )
74 {
75     int rc = 0;
76     unsigned long flags;
77     acamera_loop_buf_ptr_t p_buf = &( p_queue->buf );
78 
79     flags = system_spinlock_lock( p_queue->lock );
80 
81     if ( p_buf->head == p_buf->tail ) {
82         rc = -1;
83     }
84 
85     if ( ( p_buf->head < 0 ) ||
86          ( p_buf->head >= p_buf->data_buf_size ) ||
87          ( p_buf->tail < 0 ) ||
88          ( p_buf->tail >= p_buf->data_buf_size ) ) {
89         rc = -2;
90     }
91 
92     if ( !rc ) {
93         int pos;
94         rc = acamera_loop_buffer_read_u8( p_buf, 0 );
95 
96         pos = p_buf->tail + 1;
97         if ( pos >= p_buf->data_buf_size ) {
98             pos -= p_buf->data_buf_size;
99         }
100 
101         p_buf->tail = pos;
102         if (rc >= 0 && rc < 64) {
103             if (((1 << rc) & avail_event_mask) == 0)
104                LOG( LOG_DEBUG, "event %d is missed, mask is 0x%x", rc, avail_event_mask);
105             else
106                avail_event_mask &= ~(1 << rc);
107         }
108     }
109 
110     system_spinlock_unlock( p_queue->lock, flags );
111 
112     if ( -2 == rc ) {
113         LOG( LOG_ERR, "Event Queue Corrupted\n" );
114     }
115 
116     return rc;
117 }
118 
119 
acamera_event_queue_not_empty(acamera_event_queue_ptr_t p_queue)120 int32_t acamera_event_queue_not_empty( acamera_event_queue_ptr_t p_queue )
121 {
122     int32_t result = -1;
123     uint32_t flags = 0;
124     uint32_t pos = 0;
125     uint64_t event = 0;
126     unsigned char event_id = 0;
127     acamera_loop_buf_ptr_t p_buf = &( p_queue->buf );
128     flags = system_spinlock_lock( p_queue->lock );
129     if ( p_buf->head == p_buf->tail )
130         result = 0;
131 
132     if (result) {
133         while (p_buf->head > (p_buf->tail + pos)) {
134             event_id = p_buf->p_data_buf[pos + p_buf->tail];
135             event |= (1 << event_id);
136             pos++;
137         }
138 
139         LOG( LOG_DEBUG, "p_buf->head:%d, p_buf->tail:%d, remained event mask: 0x%llx" , p_buf->head, p_buf->tail, event);
140         acamera_event_queue_reset(p_buf);
141 
142         if (pos >= reset_threshold)
143             result = pos;
144         else
145             result = 0;
146     }
147     system_spinlock_unlock( p_queue->lock, flags );
148     return result;
149 }
150