I'm working on spinlock code in linux kernel source of 4.9.89 version.
After I've done some modification on "include/linux/spinlock.h" and "include/linux/spinlock_types.h", I build the kernel.
But some errors occurred as following:
./include/linux/seqlock.h:406:2: error: unknown type name ‘spinlock_t’
spinlock_t lock;
^
./include/linux/seqlock.h: In function ‘write_seqlock’:
./include/linux/seqlock.h:448:2: error: implicit declaration of function ‘spin_lock’ [-Werror=implicit-function-declaration]
spin_lock(&sl->lock);
^
./include/linux/seqlock.h: In function ‘write_sequnlock’:
./include/linux/seqlock.h:455:2: error: implicit declaration of function ‘spin_unlock’ [-Werror=implicit-function-declaration]
spin_unlock(&sl->lock);
^
./include/linux/seqlock.h: In function ‘write_seqlock_bh’:
./include/linux/seqlock.h:460:2: error: implicit declaration of function ‘spin_lock_bh’ [-Werror=implicit-function-declaration]
spin_lock_bh(&sl->lock);
^
./include/linux/seqlock.h: In function ‘write_sequnlock_bh’:
./include/linux/seqlock.h:467:2: error: implicit declaration of function ‘spin_unlock_bh’ [-Werror=implicit-function-declaration]
spin_unlock_bh(&sl->lock);
^
./include/linux/seqlock.h: In function ‘write_seqlock_irq’:
./include/linux/seqlock.h:472:2: error: implicit declaration of function ‘spin_lock_irq’ [-Werror=implicit-function-declaration]
spin_lock_irq(&sl->lock);
^
./include/linux/seqlock.h: In function ‘write_sequnlock_irq’:
./include/linux/seqlock.h:479:2: error: implicit declaration of function ‘spin_unlock_irq’ [-Werror=implicit-function-declaration]
spin_unlock_irq(&sl->lock);
^
./include/linux/seqlock.h: In function ‘__write_seqlock_irqsave’:
./include/linux/seqlock.h:486:2: error: implicit declaration of function ‘spin_lock_irqsave’ [-Werror=implicit-function-declaration]
spin_lock_irqsave(&sl->lock, flags);
^
./include/linux/seqlock.h: In function ‘write_sequnlock_irqrestore’:
./include/linux/seqlock.h:498:2: error: implicit declaration of function ‘spin_unlock_irqrestore’ [-Werror=implicit-function-declaration]
spin_unlock_irqrestore(&sl->lock, flags);
I did not find anything weird in my code and I'm stuck here.
What I did in the kernel source is that I try to estimate lock holding time and lock waiting time only:
// function modifications
static __always_inline void spin_lock(spinlock_t *lock)
{
struct timeval start, end;
do_gettimeofday(&start);
raw_spin_lock(&lock->rlock);
do_gettimeofday(&end);
atomic_add(&waiting_time, (end.tv_usec - start.tv_usec));
lock->holding_time = end.tv_usec;
}
static __always_inline void spin_unlock(spinlock_t *lock)
{
struct timeval end;
raw_spin_unlock(&lock->rlock);
do_gettimeofday(&end);
atomic_add(&holding_time, (end.tv_usec - lock->holding_time));
}
// macro modification
#define spin_lock_nested(lock, subclass) \
do { \
struct timeval start, end; \
do_gettimeofday(&start); \
raw_spin_lock_nested(spinlock_check(lock), subclass); \
do_gettimeofday(&end); \
atomic_add(&waiting_time, (end.tv_usec - start.tv_usec)); \
lock->holding_time = end.tv_usec; \
} while (0)
// I added 2 atomic values to cumulate the lock time values in spinlock.h file
atomic_t waiting_time;
atomic_t holding_time;
// I added an unsigned int value (holding_time) to estimate lock holding time in spinlock struct
typedef struct spinlock {
union {
struct raw_spinlock rlock;
#ifdef CONFIG_DEBUG_LOCK_ALLOC
# define LOCK_PADSIZE (offsetof(struct raw_spinlock, dep_map))
struct {
u8 __padding[LOCK_PADSIZE];
struct lockdep_map dep_map;
};
#endif
};
unsigned int holding_time;
} spinlock_t;
Why did the error occur?
I'm waiting for you help.
Thanks!
Related
I try yo compile in C++11 the following piece of code without success. My goal is to use lambda expression instead of bind in order to fill a queue with tasks.
Could you please help me?
Is any case to create a dangling reference ?
#include <iostream>
#include <functional>
#include <queue>
using namespace std;
std::queue<std::function<void()>> funcs;
class A
{
public:
void foo(int a )
{
cout << "Hello word" << endl;
}
};
class ThePool
{
public:
template<typename _Callable, typename Object, typename... _Args>
void QueueFunction(_Callable __f, Object obj, _Args... __args)
{
funcs.push([=]()
{
(obj.*__f)((__args...));
});
}
void print(int i )
{
cout << "Hello Word"<< i <<endl;
}
};
int main(int argc, char** argv) {
ThePool t;
A a ;
t.QueueFunction(&A::foo,a,5);
std::function<void()> func = funcs.back();
func();
return 0;
}
The error that is generated is the following
main.cpp:24:38: error:
parameter packs not expanded with '...':
(obj.__f)((__args...));
^ main.cpp:24:38: note: '__args' main.cpp:24:44: error: expected ')' before '...' token
(obj.__f)((__args...));
^ main.cpp:24:49: error: expected ')' before ';' token
(obj.*__f)((__args...));
^ main.cpp: In function 'int main(int, char**)': main.cpp:39:45: error: conversion
from 'std::function' to non-scalar type
'std::function' requested
std::function func = funcs.back();
^ main.cpp: In instantiation of 'struct ThePool::QueueFunction(_Callable, Object,
_Args ...) [with _Callable = void (A::)(int); Object = A; _Args = {int}]::__lambda0': main.cpp:22:12: required from 'void
ThePool::QueueFunction(_Callable, Object, _Args ...) [with _Callable =
void (A::)(int); Object = A; _Args = {int}]' main.cpp:38:32:
required from here main.cpp:24:38: error: using invalid field
'ThePool::QueueFunction(_Callable, Object, _Args
...)::__lambda0::____args'
(obj.*__f)((__args...));
I am trying to create a system call in Linux ubuntu-studio that has the following functionality:
bring virtual memory the larger process and how much bytes it occupies.
below is the implementation code of the system call:
#include <linux/module.h>
#include <linux/printk.h>
#include <linux/sched.h>
struct pid_size{
int pid;
unsigned long size;
};
struct pid_size pid maiorMemoriaVirtual(void)
{
struct task_struct *task;
struct task_struct *maior = NULL;
for_each_process(task)
{
if(maior == NULL)
maior = task;
else if(task->it_virt_value > maior->it_virt_value)
maior = task;
}
struct pid_size retorno;
retorno.pid = maior->pid;
retorno.size = maior->it_virt_value;
return retorno;
}
When compiling to try compiling the kernel got the following error:
kernel/maiorMemoriaVirtual.c: In function ‘sys_maiorMemoriaVirtual’:
kernel/maiorMemoriaVirtual.c:19:21: error: ‘struct task_struct’ has no member named ‘it_virt_value’
else if(task->it_virt_value > maior->it_virt_value)
^
kernel/maiorMemoriaVirtual.c:19:44: error: ‘struct task_struct’ has no member named ‘it_virt_value’
else if(task->it_virt_value > maior->it_virt_value)
^
kernel/maiorMemoriaVirtual.c:23:5: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
struct pid_size retorno;
^
kernel/maiorMemoriaVirtual.c:25:25: error: ‘struct task_struct’ has no member named ‘it_virt_value’
retorno.size = maior->it_virt_value;
^
make[1]: ** [kernel/maiorMemoriaVirtual.o] Erro 1
I came across a similar problem while working on an assignment and I have realized that there are quite a few changes that have been made to the definition of the 'task_struct' structure.
My guess is that you are looking for accumulated virtual memory usage. You might find this link useful. Accumulated Virtual Memory usage
Link to the task_struct definition in kernel 2.6.36
I have some homework, and I have troubles understanding, (probably) how passing parameters to std::thread constructor works.
Assume following code (I deleted unneeded parts)
template<typename T, typename Task>
class Scheduler
{
private:
typedef std::unordered_map<std::size_t, T> Results;
class Solver
{
public:
Solver(Task&& task) : m_thread(&Solver::thread_function, std::move(task))
{
m_thread.detach();
}
Solver(Solver&& solver) = default; // required for vector::emplace_back
~Solver() = default;
private:
void thread_function(Task&& task)
{
task();
}
std::thread m_thread;
};
public:
Scheduler() = default;
~Scheduler() = default;
void add_task(Task&& task)
{
m_solvers.emplace_back(std::move(task));
}
private:
std::vector<Solver> m_solvers;
};
template<typename T>
struct Ftor
{
explicit Ftor(const T& t) : data(t) { }
T operator()() { std::cout << "Computed" << std::endl; return data; }
T data;
};
int main()
{
Scheduler<int, Ftor<int>> scheduler_ftor;
Scheduler<int, std::function<int(void)>> scheduler_lambda;
Ftor<int> s(5);
scheduler_ftor.add_task(std::move(s));
scheduler_lambda.add_task([](){ std::cout << "Computed" << std::endl; return 1; });
}
Why it doesn't compile?
MVS2015 is complaining about
functional(1195): error C2064: term does not evaluate to a function taking 1 arguments
functional(1195): note: class does not define an 'operator()' or a user defined conversion operator to a pointer-to-function or reference-to-function that takes appropriate number of arguments
note: while compiling class template member function 'Scheduler<int,Ftor<int> >::Solver::Solver(Task &&)'
While G++ 4.9.2
functional: In instantiation of ‘struct std::_Bind_simple<std::_Mem_fn<void (Scheduler<int, Ftor<int> >::Solver::*)(Ftor<int>&&)>(Ftor<int>)>’:
required from ‘void Scheduler<T, Task>::add_task(Task&&) [with T = int; Task = Ftor<int>]’
functional:1665:61: error: no type named ‘type’ in ‘class std::result_of<std::_Mem_fn<void (Scheduler<int, Ftor<int> >::Solver::*)(Ftor<int>&&)>(Ftor<int>)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
I suppose there are some problems with std::moving to std::thread.
If you use member function as first thread argument, second argument supposed to be this pointer, pointing to the object to which member function could be called to
UPDATE
Good discussion here
Start thread with member function
I don't follow your code, but addressing the question, a extrapolated answer will be( most of the code is psuedocode)
lets assume that there is a function int test(int name).
thread t0;
t0 = thread(test,32);
thread t1(test,43);
Passing a argument to function.
int temp = 0;
int testfunc(int& q)
{
cout<<q;
}
thread t1;
t1 = thread(testfunc,ref(temp));
In short, you just pass the name of the function that must be run in the thread as the first argument, and the functions parameters follow it in same order as they are in the function definition, for passing by reference you can use the ref() wrapper.See the below example.
#include <iostream>
#include <thread>
#include <string>
using namespace std;
void test(int a,int &a,string test)
{
\\do something
}
int main()
{
int test1 = 0;
string tt = "hello";
thread t1;
t1 = thread(23,&test1,tt);
t1.detach();
return 0;
}
if you are wondering about the use of join() and detach(), refer to this thread: When should I use std::thread::detach?, refer to my answer post in that thread.
I am trying to make a threaded grabber for my OpenCV application. I am unable to figure out why this code doesn't compile. It gives me an error that I believe means that the function call is wrong. However, it is the exact same way how I start a thread using std::thread usually! I want to use std::thread to accomplish it because it will offer more platform-independent compatibility, so please don't tell me to use a platform-specific library. I also want this to be STL-based, so no Boost or DLib. In my main.cpp, I have a working thread application, the code below:
#include <iostream>
#include <fstream>
#include <string>
#include <thread>
#include <mutex>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#define read_failure_threshold 512
long grabbers_active = 0;
namespace dev
{
class grabber
{
private:
bool enabled = false;
std::mutex lock;
int capture_mode;
int capture_id;
unsigned long read_failures = 0;
std::string stream;
std::string grabber_name;
cv::Mat image;
public:
void grabber_t()
{
.......[unimportant code]........
}
grabber(std::string name, int captureMode, int captureId, std::string location)
{
.......[unimportant code]........
}
void start()
{
if(!enabled)
{
std::thread grabber_thread(grabber_t);
grabber_thread.detach();
}
enabled = true;
grabbers_active++;
}
cv::Mat getImage()
{
.......[unimportant code]........
}
};
}
[ERRORS:]
In file included from /media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/main.cpp:1:0:
/media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/template.hpp: In member function ‘void dev::grabber::start()’:
/media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/template.hpp:119:52: error: no matching function for call to ‘std::thread::thread(<unresolved overloaded function type>)’
std::thread grabber_thread(grabber_t);
^
/media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/template.hpp:119:52: note: candidates are:
In file included from /media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/template.hpp:4:0,
from /media/storage/programming/yash101/repos/Other/STL+OpenCV/threaded_grabber_template/main.cpp:1:
/usr/include/c++/4.8/thread:133:7: note: std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (dev::grabber::*)(); _Args = {}]
thread(_Callable&& __f, _Args&&... __args)
^
/usr/include/c++/4.8/thread:133:7: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘void (dev::grabber::*&&)()’
/usr/include/c++/4.8/thread:128:5: note: std::thread::thread(std::thread&&)
thread(thread&& __t) noexcept
^
/usr/include/c++/4.8/thread:128:5: note: no known conversion for argument 1 from ‘<unresolved overloaded function type>’ to ‘std::thread&&’
/usr/include/c++/4.8/thread:122:5: note: std::thread::thread()
thread() noexcept = default;
^
/usr/include/c++/4.8/thread:122:5: note: candidate expects 0 arguments, 1 provided
make[2]: *** [CMakeFiles/build.dir/main.cpp.o] Error 1
make[1]: *** [CMakeFiles/build.dir/all] Error 2
make: *** [all] Error 2
The error log is also at the end of the code. The only errors I am worried about are the threading ones. The other ones are simple fixes, but require me to have the threading working.
I am in Ubuntu, using g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2. I have C++0x enabled in my CMakeLists.txt. Everything works perfectly in there
My main objective is to figure out why I am getting this error. I have been googling and trying different tricks for many hours, but nothing is working!
Thanks in advanced for your help :)
Change that :
std::thread grabber_thread(grabber_t);
Into that :
std::thread grabber_thread(&grabber::grabber_t, this);
grabber_t is a reference to non-static member function, you need to pass its address, but &grabber_t can't work as you must explicitly qualify name of member function when taking its address, thus resulting in &grabber::grabber_t.
Consider my test code:
#include <thread>
class Foo {
public:
void threadFunc() {}
void startThread() {
_th = std::thread(&Foo::threadFunc, *this);
}
private:
std::thread _th;
};
int main(int argc, char *argv[])
{
Foo f;
f.startThread();
return 0;
}
This is an error it produces:
../untitled/main.cpp:13:14: warning: unused parameter 'argc' [-Wunused-parameter]
int main(int argc, char *argv[])
^
../untitled/main.cpp:13:26: warning: unused parameter 'argv' [-Wunused-parameter]
int main(int argc, char *argv[])
^
In file included from ../untitled/main.cpp:1:
In file included from /usr/bin/../lib/c++/v1/thread:90:
In file included from /usr/bin/../lib/c++/v1/__functional_base:15:
/usr/bin/../lib/c++/v1/type_traits:1372:12: error: call to implicitly-deleted copy constructor of 'typename decay<Foo &>::type' (aka 'Foo')
return _VSTD::forward<_Tp>(__t);
^~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/c++/v1/__config:273:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_NAMESPACE
^
/usr/bin/../lib/c++/v1/thread:351:33: note: in instantiation of function template specialization 'std::__1::__decay_copy<Foo &>' requested here
__decay_copy(_VSTD::forward<_Args>(__args))...));
^
../untitled/main.cpp:7:15: note: in instantiation of function template specialization 'std::__1::thread::thread<void (Foo::*)(), Foo &, void>' requested here
_th = std::thread(&Foo::threadFunc, *this);
^
../untitled/main.cpp:10:17: note: copy constructor of 'Foo' is implicitly deleted because field '_th' has an inaccessible copy constructor
std::thread _th;
^
And if I create a thread like this: _th = std::thread(&Foo::threadFunc, std::ref(*this));
I get:
../untitled/main.cpp:13:14: warning: unused parameter 'argc' [-Wunused-parameter]
int main(int argc, char *argv[])
^
../untitled/main.cpp:13:26: warning: unused parameter 'argv' [-Wunused-parameter]
int main(int argc, char *argv[])
^
In file included from ../untitled/main.cpp:1:
/usr/bin/../lib/c++/v1/thread:330:5: error: attempt to use a deleted function
__invoke(_VSTD::move(_VSTD::get<0>(__t)), _VSTD::move(_VSTD::get<_Indices>(__t))...);
^
/usr/bin/../lib/c++/v1/thread:340:5: note: in instantiation of function template specialization 'std::__1::__threaad_execute<void (Foo::*)(), std::__1::reference_wrapper<Foo> , 1>' requested here
__threaad_execute(*__p, _Index());
^
/usr/bin/../lib/c++/v1/thread:352:41: note: in instantiation of function template specialization 'std::__1::__thread_proxy<std::__1::tuple<void (Foo::*)(), std::__1::reference_wrapper<Foo> > >' requested here
int __ec = pthread_create(&__t_, 0, &__thread_proxy<_Gp>, __p.get());
^
../untitled/main.cpp:7:15: note: in instantiation of function template specialization 'std::__1::thread::thread<void (Foo::*)(), std::__1::reference_wrapper<Foo> , void>' requested here
_th = std::thread(&Foo::threadFunc, std::ref(*this));
^
/usr/bin/../lib/c++/v1/type_traits:833:5: note: function has been explicitly marked deleted here
~__nat() = delete;
^
What am I doing wrong? I don't have such problem on Windows with VS2012. I also didn't have this problem with default stdlib implementation on Mac, but now I have to use libc++.
My compiler flags:
-std=c++11 -mmacosx-version-min=10.7 -stdlib=libc++
_th = std::thread(&Foo::threadFunc, *this);
This tries to make a copy of *this to store in the new thread object, but your type is not copyable because its member _th is not copyable.
You probably want to store a pointer to the object, not a copy of the object:
_th = std::thread(&Foo::threadFunc, this);
N.B. your program will terminate because you do not join the thread. In your type's destructor you should do something like:
~Foo() { if (_th.joinable()) _th.join(); }