blob: 40826d4a4813ab3dac3b2587d81460916ca9ab88 [file] [log] [blame]
Andrew Boie489d7472017-06-06 13:51:55 -07001/*
2 * Copyright (c) 2015-2016 Wind River Systems, Inc.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/**
18 * @file C++ Synchronization demo. Uses basic C++ functionality.
19 */
20
21#include <stdio.h>
22#include <zephyr.h>
23#include <arch/cpu.h>
24#include <misc/printk.h>
25
26/**
27 * @class semaphore the basic pure virtual semaphore class
28 */
29class semaphore {
30public:
31 virtual int wait(void) = 0;
32 virtual int wait(int timeout) = 0;
33 virtual void give(void) = 0;
34};
35
36/* specify delay between greetings (in ms); compute equivalent in ticks */
37#define SLEEPTIME 500
38#define STACKSIZE 2000
39
40struct k_thread coop_thread;
Andrew Boiee87eaca2017-06-02 14:08:58 -070041K_THREAD_STACK_DEFINE(coop_stack, STACKSIZE);
Andrew Boie489d7472017-06-06 13:51:55 -070042
43/*
44 * @class cpp_semaphore
Anas Nashifabbaac92017-12-05 09:43:43 -050045 * @brief Semaphore
Andrew Boie489d7472017-06-06 13:51:55 -070046 *
47 * Class derives from the pure virtual semaphore class and
Anas Nashifabbaac92017-12-05 09:43:43 -050048 * implements it's methods for the semaphore
Andrew Boie489d7472017-06-06 13:51:55 -070049 */
50class cpp_semaphore: public semaphore {
51protected:
52 struct k_sem _sema_internal;
53public:
54 cpp_semaphore();
55 virtual ~cpp_semaphore() {}
56 virtual int wait(void);
57 virtual int wait(int timeout);
58 virtual void give(void);
59};
60
61/*
62 * @brief cpp_semaphore basic constructor
63 */
64cpp_semaphore::cpp_semaphore()
65{
66 printk("Create semaphore %p\n", this);
67 k_sem_init(&_sema_internal, 0, UINT_MAX);
68}
69
70/*
71 * @brief wait for a semaphore
72 *
73 * Test a semaphore to see if it has been signaled. If the signal
74 * count is greater than zero, it is decremented.
75 *
76 * @return 1 when semaphore is available
77 */
78int cpp_semaphore::wait(void)
79{
80 k_sem_take(&_sema_internal, K_FOREVER);
81 return 1;
82}
83
84/*
85 * @brief wait for a semaphore within a specified timeout
86 *
87 * Test a semaphore to see if it has been signaled. If the signal
88 * count is greater than zero, it is decremented. The function
89 * waits for timeout specified
90 *
91 * @param timeout the specified timeout in ticks
92 *
93 * @return 1 if semaphore is available, 0 if timed out
94 */
95int cpp_semaphore::wait(int timeout)
96{
97 return k_sem_take(&_sema_internal, timeout);
98}
99
100/**
101 *
102 * @brief Signal a semaphore
103 *
104 * This routine signals the specified semaphore.
105 *
106 * @return N/A
107 */
108void cpp_semaphore::give(void)
109{
110 k_sem_give(&_sema_internal);
111}
112
113cpp_semaphore sem_main;
114cpp_semaphore sem_coop;
115
116void coop_thread_entry(void)
117{
118 struct k_timer timer;
119
120 k_timer_init(&timer, NULL, NULL);
121
122 while (1) {
123 /* wait for main thread to let us have a turn */
124 sem_coop.wait();
125
126 /* say "hello" */
127 printk("%s: Hello World!\n", __FUNCTION__);
128
129 /* wait a while, then let main thread have a turn */
130 k_timer_start(&timer, SLEEPTIME, 0);
131 k_timer_status_sync(&timer);
132 sem_main.give();
133 }
134}
135
Andrew Boieba95aa02017-08-14 14:32:39 -0700136int main(void)
Andrew Boie489d7472017-06-06 13:51:55 -0700137{
138 struct k_timer timer;
139
140 k_thread_create(&coop_thread, coop_stack, STACKSIZE,
141 (k_thread_entry_t) coop_thread_entry,
142 NULL, NULL, NULL, K_PRIO_COOP(7), 0, 0);
143 k_timer_init(&timer, NULL, NULL);
144
145 while (1) {
146 /* say "hello" */
147 printk("%s: Hello World!\n", __FUNCTION__);
148
149 /* wait a while, then let coop thread have a turn */
150 k_timer_start(&timer, SLEEPTIME, 0);
151 k_timer_status_sync(&timer);
152 sem_coop.give();
153
154 /* Wait for coop thread to let us have a turn */
155 sem_main.wait();
156 }
Andrew Boieba95aa02017-08-14 14:32:39 -0700157
158 return 0;
Andrew Boie489d7472017-06-06 13:51:55 -0700159}