Prepare for a nooby question.
I'm writing some ultra-simple code for this new PIC which I've just got. All I'm trying to do is to flash an LED. Below are two code samples - the first works but the second doesn't. Why?? I can't see any problem with the second one.
WORKS:
while(1)
{
i=99999;
while(i--) {
LATAbits.LATA0 = 0; // set RA0 to logic 1
}
i=99999;
while(i--) {
LATAbits.LATA0 = 1; // set RA0 to logic 0
}
}
DOESN'T WORK:
while(1)
{
LATAbits.LATA0 = 1; // set RA0 to logic 1
for(i=0;i<99999;i++) {}
LATAbits.LATA0 = 0; // set RA0 to logic 0
for(i=0;i<99999;i++) {}
}
Thanks in advance for the help!
Try this:
while(1)
{
for(i=0;i<99999;i++)
{
LATAbits.LATA0 = 1; // set RA0 to logic 1
}
for(i=0;i<99999;i++)
{
LATAbits.LATA0 = 0; // set RA0 to logic 0
}
}
Maybe your compiler is optimizing and ignoring the for statements as they have no code to execute inside. What I did was put the RA0 assignment inside these statements, forcing the compiler to keep the delay loops.
You can also pass the argument -S to your compiler to see the assembly code generated and confirm that the for statements were removed. The -S option generates an intermediate file with a ".S" extension.
What's your definition of i? char i? int i? long i?
What PIC are you using?
If you're using an int, the 8-bit PICs use a 16-bit int.
So what happens:
// Try to stuff 99999 into 16-bits, but it becomes 34463
i=99999;
// Count-down from 34463 to zero
while(i--) {}
// Successfully exit delay
As opposed to:
// Count up from zero
// Get to 65535 and then reset to zero
// Never reach 99999
for(i=0;i<99999;i++) {}
// Never exit delay
Try using unsigned long int for i, which tends to be 32-bit on PICs and see if it starts to work.
Related
I am trying to solve the classic dining philosophers problem. The Dining Philosopher Problem states that K philosophers seated around a circular table with one chopstick between each pair of philosophers. There is one chopstick between each philosopher. A philosopher may eat if he can pickup the two chopsticks adjacent to him. One chopstick may be picked up by any one of its adjacent followers but not both. I am trying to solve this with multi processing which means that every chopstick is a mutex and every philosopher is a process.
HANDLE forks[NUMBER_OF_FORKS];
int main()
{
STARTUPINFO si[NUMBER_OF_PHILOSOPHERS]; // NUMBER_OF_PHILOSOPHERS is 5
PROCESS_INFORMATION pi[NUMBER_OF_PHILOSOPHERS]; // NUMBER_OF_PHILOSOPHERS is 5
initForks(NUMBER_OF_PHILOSOPHERS); // The function initializing all the Mutexs
std::string param;
LPWSTR test;
for (int i = 0; i < NUMBER_OF_PHILOSOPHERS; i++)
{
ZeroMemory(&si[i], sizeof(si[i]));
si[i].cb = sizeof(si[i]);
ZeroMemory(&pi[i], sizeof(pi[i]));
// Converting the param to LPWSTR(The param represent the number of the philosopher).
param = std::to_string(i);
test = ConvertString(param);
if (!CreateProcess(L"..\\Debug\\Philosopher.exe", test, NULL, NULL, FALSE, 0, NULL, NULL, &si[i], &pi[i]))
{
std::cout << GetLastError() << std::endl;;
}
}
for (int i = 0; i < NUMBER_OF_PHILOSOPHERS; i++)
{
WaitForSingleObject(pi[i].hProcess, INFINITE);
}
}
At line 17 when I am using the CreateProcess function I am getting this Error:
showing the error
Can someone help me spot the problem? Thank you for help guys!
As can be seen from the image,
Expression : _p !- nullptr
You did not initialize the test variable, try this,
LPWSTR test = new WCHAR[100];
memset(test, NULL, 200);
...
Or,
std::string param;
WCHAR test[100];
param = std::to_string(i);
mbstowcs(test, param.c_str(), param.size() + 1); //Converts a multibyte character string from the array whose first element is pointed to by src to its wide character representation.
I have 2 threads to decode RTSP stream video, my code as below:
int key = 0;
std::queue<AVpacket> Packet_buf;
int thread1 (void)
{
AVPacket packet;
packet = read_packet();
Packet_buf.push(packet);
av_packet_unref(&packet);
key = 1;
}
int thread2 (void)
{
AVPacket *packet;
while(key==0) {} // wait to read the first packet
*packet = Packet_buf.front(); // program halt here
avcodec_send_packet(pCodecCtx,packet);
}
int main();
{
thread p1(thread1);
thread p2(thread2);
}
My program crash at line: *packet = Packet_buf.front();
Can you help me to find the problem, Thanks !
Your code have more the one issues, some of them:
1) std::queue<AVpacket> Packet_buf;
I think this would be:
std::queue<AVPacket> Packet_buf; notice AVpacket and AVPacket is whole different thing. (Yes, I'm guessing this just a typo).
2) while(key==0) {} This is not a good way to wait on a variable change. Especially if the variable (key) is not volatile. It may work and probably is working. But I suggest you use pthread signal and condition variables here instead. Also check next issue (3) which is closely related.
3) *packet = Packet_buf.front(); Caling std::queue.front() before checking whether the container is empty() or not is NOT good idea. If container (queue) is empty than front() method here will result in undefined behavior.
Hope that helps.
In my attempt to add suspend / resume functionality to my Worker [thread] class, I've happened upon an issue that I cannot explain. (C++1y / VS2015)
The issue looks like a deadlock, however I cannot seem to reproduce it once a debugger is attached and a breakpoint is set before a certain point (see #1) - so it looks like it's a timing issue.
The fix that I could find (#2) doesn't make a lot of sense to me because it requires to hold on to a mutex longer and where client code might attempt to acquire other mutexes, which I understand to actually increase the chance of a deadlock.
But it does fix the issue.
The Worker loop:
Job* job;
while (true)
{
{
std::unique_lock<std::mutex> lock(m_jobsMutex);
m_workSemaphore.Wait(lock);
if (m_jobs.empty() && m_finishing)
{
break;
}
// Take the next job
ASSERT(!m_jobs.empty());
job = m_jobs.front();
m_jobs.pop_front();
}
bool done = false;
bool wasSuspended = false;
do
{
// #2
{ // Removing this extra scoping seemingly fixes the issue BUT
// incurs us holding on to m_suspendMutex while the job is Process()ing,
// which might 1, be lengthy, 2, acquire other locks.
std::unique_lock<std::mutex> lock(m_suspendMutex);
if (m_isSuspended && !wasSuspended)
{
job->Suspend();
}
wasSuspended = m_isSuspended;
m_suspendCv.wait(lock, [this] {
return !m_isSuspended;
});
if (wasSuspended && !m_isSuspended)
{
job->Resume();
}
wasSuspended = m_isSuspended;
}
done = job->Process();
}
while (!done);
}
Suspend / Resume is just:
void Worker::Suspend()
{
std::unique_lock<std::mutex> lock(m_suspendMutex);
ASSERT(!m_isSuspended);
m_isSuspended = true;
}
void Worker::Resume()
{
{
std::unique_lock<std::mutex> lock(m_suspendMutex);
ASSERT(m_isSuspended);
m_isSuspended = false;
}
m_suspendCv.notify_one(); // notify_all() doesn't work either.
}
The (Visual Studio) test:
struct Job: Worker::Job
{
int durationMs = 25;
int chunks = 40;
int executed = 0;
bool Process()
{
auto now = std::chrono::system_clock::now();
auto until = now + std::chrono::milliseconds(durationMs);
while (std::chrono::system_clock::now() < until)
{ /* busy, busy */
}
++executed;
return executed < chunks;
}
void Suspend() { /* nothing here */ }
void Resume() { /* nothing here */ }
};
auto worker = std::make_unique<Worker>();
Job j;
worker->Enqueue(j);
std::this_thread::sleep_for(std::chrono::milliseconds(j.durationMs)); // Wait at least one chunk.
worker->Suspend();
Assert::IsTrue(j.executed < j.chunks); // We've suspended before we finished.
const int testExec = j.executed;
std::this_thread::sleep_for(std::chrono::milliseconds(j.durationMs * 4));
Assert::IsTrue(j.executed == testExec); // We haven't moved on.
// #1
worker->Resume(); // Breaking before this call means that I won't see the issue.
worker->Finalize();
Assert::IsTrue(j.executed == j.chunks); // Now we've finished.
What am I missing / doing wrong? Why does the Process()ing of the job have to be guarded by the suspend mutex?
EDIT: Resume() should not have been holding on to the mutex at the time of notification; that's fixed -- the issue persists.
Of course the Process()ing of the job does not have to be guarded by the suspend mutex.
The access of j.executed - for the asserts as well as for the incrementing - however does need to be synchronized (either by making it an std::atomic<int> or by guarding it with a mutex etc.).
It's still not clear why the issue manifested the way it did (since I'm not writing to the variable on the main thread) -- might be a case of undefined behaviour propagating backwards in time.
class Program
{
static void Main()
{
int i ;
for ( i=0; i < 10;i++ )
{
// p: Console.WriteLine("hello");
p: if(i%2!=0)
{
if(i==5)
{
goto p;
}
}
Console.WriteLine(i);
}
Console.ReadKey();
}
}
//output : 0 1 2 3 4
The goto is being executed. Unfortunately, nothing has changed in the variables so that execution takes the exact same path as before: It reaches the goto again. This is an infinite loop.
Note, that in particular i has the same value before and after the jump. Maybe this is your misunderstanding.
You should learn to use the debugger. You can see this when single-stepping through the program.
I have a thread class with two functions:
using namespace System::Threading;
public ref class SecThr
{
public:
int j;
void wralot()
{
for (int i=0; i<=400000;i++)
{
j=i;
if ((i%10000)==0)
Console::WriteLine(j);
}
}
void setalot()
{
Monitor::Enter(this);
for (int i=0; i<=400000;i++)
{
j=7;
}
Monitor::Exit(this);
}
};
int main(array<System::String ^> ^args)
{
Console::WriteLine("Hello!");
SecThr^ thrcl=gcnew SecThr;
Thread^ o1=gcnew Thread(gcnew ThreadStart(thrcl, &SecThr::wralot));
Thread^ o2=gcnew Thread(gcnew ThreadStart(thrcl, &SecThr::setalot));
o2->Start();
o1->Start();
o1->Join();
o2->Join();
So, for locking "setalot" function i've used MOnitor::Enter-Exit block. But the output is like i'm running only one thread with function "wralot"
0
10000
20000
30000
40000
7 //here's "setalot" func
60000
e t.c.
Why all the output data is not changed to const (7) by "setalot" func
I think you've misunderstood what Monitor::Enter does. It's only a cooperative lock - and as wralot doesn't try to obtain the lock at all, the actions of setalot don't affect it. It's not really clear why you expected to get a constant output of 7 due to setalot - if wralot did try to obtain the lock, it would just mean that one of them would "win" and the other would have to wait. If wralot had to wait, there'd be no output while setalot was running, and then wralot would go do its thing - including setting j to i on every iteration.
So basically, both threads are starting, and setalot very quickly sets j to 7 a lot of times... that's likely to complete in the twinkling of an eye in computer terms, compared with a Console.WriteLine call. I suggest you add a call to Console::WriteLine at the end of setalot so you can see when it's finished. Obviously after that, it's completely irrelevant - which is why you're seeing 60000, 70000 etc.