There is only one kthread and I want to control it to run on specific CPU.
Main process creates and wakes up kthread by kthread_create() and wake_up_process() function.
When the kthread is created, maie process stores pid of the kthread at global variable. Let it called "thread_pid".
I create function to change the CPU of kthread.
It looks like "int change_cpu(int cpu_to_change)".
It uses sched_setaffinity() while passing parameter pid as "thread_pid".
i.e. it calls like "sched_setaffinity(thread_pid, cpu_mask_to_change);".
And it stores value of parameter "cpu_to_change" to global variable. Let it called "thread_cpu".
The kthread has assertion such as "ASSERT(smc_processor_id() == thread_cpu)".
The kthread does not run instead wait for completion usually.
I expect that after change_cpu() function is called, the kthread works well without assertion fail.
But it falls to assertion fail, even sched_setaffinity() works successfully.
Why doesn't it works as expected?
I want to know why this way doesn't work.
Here is dummy code for better understanding.
int thread_cpu;
int thread_pid;
int dummy_kthread(void *args)
{
while(1) {
wait_for_completion();
ASSERT( smc_processor_id() == thread_cpu );
'''
do something
'''
complete();
}
}
int change_cpu(int cpu_to_change)
{
struct cpumask * cpu_mask;
thread_cpu = cpu_to_change;
cpu_mask = set_cpumask(cpu_to_change); // this is not actually exist function.
return sched_setaffinity(thread_pid, cpu_mask);
}
int main(){
struct task_struct *dummy;
dummy = kthread_create(dummy_kthread, NULL, "dummy_kthread");
thread_pid = get_pid(dummy); // this is not actually exist function.
}
One possible cause for sched_setaffinity() to appear not to be working correctly is linked to the dynamic power management of cores. When the core powers off, all of the threads running on that core will migrate away from that core. As a result, the cpumask will be updated accordingly.
In order to prevent cores from powering off, you need to choose "no" for HOTPLUG_CPU when configuring your kernel, or you can manually set the default value to 'n' in the Kconfig file (arch/[architecture]/Kconfig) before compiling your kernel.
Related
I'm working with Android 8.1 Pixel2 XL phone.
I have hooked the sys_call_table and have replaced the syscalls with my own functions using the kernel module.
I want to make an application unable to quit.
I'm trying to invalidate an application's sys_exit_group and sys_kill.
What should I do in my own function.
I want to debug an application, but it turns on anti-debugging. So I want to hook the system call
I have tried direct return, but It wasn't work. System will call sys_kill again.But this time, I can't get the application's uid from its pid.
asmlinkage long my_sys_kill(pid_t pid, int sig)
{
char buff[MAX_PATH] = {0};
kuid_t uid = current->cred->uid;
int target_uid = get_uid_from_pid(pid);
if (target_uid == targetuid)
{
printk(KERN_DEBUG "#Tsingxing: kill hooked uid is %d pid is %d, tragetuid is %d, packagename: %s\n",uid.val,pid, target_uid, buff);
return 0;
}
printk(KERN_DEBUG "#Tsingxing:kill called uid is %d,pid is %d, traget_uid is %d\n",uid.val,pid,target_uid);
return origin_sys_kill(pid, sig);
}
asmlinkage long my_sys_exit_group(int error_code)
{
char buff[MAX_PATH] = {0};
kuid_t uid = current->cred->uid;
long tgid = current -> tgid;
long pid = current->pid;
int target_uid = get_uid_from_pid(pid);
if (uid.val == targetuid || target_uid == targetuid)
{
printk(KERN_DEBUG "#Tsingxing:exit group hooked, pid is %ld\n",pid);
return 0;
}
return origin_sys_exit_group(error_code);
}
I have solved this problem. I mixed sys_call_table and compat_sys_call_table. The Target application is using compat_sys_call_table but I'm using the __NR_xxx. I solved the problem using __NR_compat_xxx method. Just return direct in compat_sys_call_exit_group.
At a very high level, this can't work. When an application calls _Exit (possibly/likely at the end of exit), it has no path to any further code to be run. These functions are normally even marked _Noreturn, meaning that the compiler does not leave the registers/calling stack frame in a meaningful state where resumption of execution could occur. Even if it did, the program itself at the source level is not prepared to continue execution.
If the function somehow returned, the next step would be runaway wrong code execution, likely leading to arbitrary code execution under the control of an attacker if the application had been processing untrusted input of any kind.
In practice, the libc side implementation of the exit and _Exit functions likely hardens against kernel bugs (yes, what you're asking for is a bug) whereby SYS_exit_group fails to exit. I haven't verified other implementations lately but I know mine in musl do this, because it's cheap and the alternative is very dangerous.
I'm trying to use multithreading to allow two tasks to run in parallel within one DLL, but my application keeps crashing, apparently due to some bad resource conflict management; here are the details:
I need to call the same function(DoGATrainAndRun) from a certain point along the main logic flow, passing a different value for one of the parameters, let the two run, then go back to the main logic flow, and use the two (different) sets of values returned from the 2 calls.
(this is in the main header file):
typedef struct
{
int PredictorId;
int OutputType;
int Delta;
int Scale;
int Debug;
FILE* LogFile;
int TotalBars;
double CBaseVal;
double* HVal;
int PredictionLen;
double*** Forecast;
} t;
(This is in the main logic flow):
hRunMutex=CreateMutex(NULL, FALSE, NULL);
arg->OutputType=FH;
handle= (HANDLE) _beginthread( DoGATrainAndRun, 32768, (void*) arg);
arg->OutputType=FL;
handle= (HANDLE) _beginthread( DoGATrainAndRun, 32768, (void*) arg);
do {} while (hRunMutex!=0);
CloseHandle(hRunMutex);
(this is at the end of DoGaTrainAndRun):
free(args);
ReleaseMutex( hRunMutex );
I'm pretty new to multi-threading, and I can't seem to figure this one out...
There's a few things:
First, you're passing the same structure into both threads but just changing the OutputType value. If possible that the first thread will see FL and never see the value FH. The reason for this is how threads are scheduled. It's valid for your first thread to start and then be suspended. Then, your main thread creates the second thread, having set OutputType to FL. This thread starts and the first one is resumed as well. However, the first one now sees OutputType as FL.
Next, both threads are using the same structure, but one of them is freeing the memory. If the other thread is still using it after the other releases then you'll get undefined behaviour in the thread that is still using it. This will probably result in a crash.
You're attempt to wait for the threads to exit is wrong. You don't need the mutex and you certainly don't need to be spinning of it testing for zero. Just use WaitForMultipleObjects:
HANDLE handles[2];
handles[0] = (HANDLE)_beginthread(...);
handles[1] = (HANDLE)_beginthread(...);
WaitForMultipleObjects(2, handles, TRUE, INFINITE);
This will stop your main thread from spinning around wasting cpu cycles. When the wait returns you'll know both threads have finished.
Putting this all together should give you something like this:
HANDLE handles[2];
t *arg1=malloc(sizeof(t));
arg1->OutputType=FH
handles[0] = (HANDLE)_beginthread(DoGATrainAndRun, 32768, (void*)arg1);
t *arg2=malloc(sizeof(t));
arg2->OutputType=FL
handles[1] = (HANDLE)_beginthread(DoGATrainAndRun, 32768, (void*)arg2);
WaitForMultipleObjects(2, handles, TRUE, INFINITE);
free(arg1);
free(arg2)
And don't release any memory in DoGATrainAndRun.
I have a function that looks like this that I need to implement.
Threads call this function with these parameters. It's supposed to return with the correct time it accessed the CPU and if it can't access the CPU, it will wait until it can access it.
With regards to the correct time, I keep a global variable that gets updated each time, it calls it.
How do I implement the waits and synchronize it correctly.
int MLFQ(float currentTime, int tid, int remainingTime, int tprio)
My code looks something like this so far and it doesn't quite work.
update globalTime (globalTime = currentTime)
Mutex_lock
Add to MLFQ if needed (either to 5, 10, 15, 20, or 25 MLFQ)
if (canAccessCPU)
getCPU
unlock mutex
return globalTime
else
mutex_unlock
return MLFQ(globalTime, tid, remainingTime, tprio);
Your post uses pseudo code, and there are some ambiguities, so comment if I make the wrong assumptions here:
How do I implement the waits and synchronize it correctly[?]
Waits,
Waits in threads are often implemented in such a way as to not block other threads. Sleep() at the bottom of a thread worker function allows some time for the called thread to sleep, i.e. share time with other processes. In Windows, it is prototyped as:
VOID WINAPI Sleep(
_In_ DWORD dwMilliseconds
);
Linux sleep() here
Synchronizing:
Can be done in many ways. Assuming you are referring to keeping the order in which calls come in from several threads, you can create a simple struct that can be passed back as an argument that could contain a TRUE/FALSE indication of whether the uP was accessed, and the time the attempt was made:
In someheader.h file:
typedef struct {
int uPAccess;
time_t time;
}UP_CALL;
extern UP_CALL uPCall, *pUPCall;
In all of the the .c file(s) you will use:
#include "someheader.h"
In one of the .c files you must initialize the struct: perhaps in the
main fucntion:
int main(void)
{
pUPCall = &uPCall;
//other code
return 0;
}
You can now include a pointer to struct in the thread worker function, (normally globals are at risk of access contention between threads, but you are protecting using mutex), to get time of access attempt, and success of attempt
I am trying to implement a user level thread library and need to schedule threads in a round robin fashion. I am currently trying to make switching work for 2 threads that I have created using makecontext, getcontext and swapcontext. setitimer with ITIMER_PROF value is used and sigaction is assigned a handler to schedule a new thread whenever the SIGPROF signal is generated.
However, the signal handler is not invoked and the threads therefore never get scheduled. What could be the reason? Here are some snippets of the code:
void userthread_init(long period){
/*long time_period = period;
//Includes all the code like initializing the timer and attaching the signal
// handler function "schedule()" to the signal SIGPROF.
// create a linked list of threads - each thread's context gets added to the list/updated in the list
// in userthread_create*/
struct itimerval it;
struct sigaction act;
act.sa_flags = SA_SIGINFO;
act.sa_sigaction = &schedule;
sigemptyset(&act.sa_mask);
sigaction(SIGPROF,&act,NULL);
time_period = period;
it.it_interval.tv_sec = 4;
it.it_interval.tv_usec = period;
it.it_value.tv_sec = 1;
it.it_value.tv_usec = 100000;
setitimer(ITIMER_PROF, &it,NULL);
//for(;;);
}
The above code is to initialize a timer and attach a handler schedule to the signal handler. I am assuming the signal SIGPROF will be given to the above function which will invoke the scheduler() function. The scheduler function is given below:
void schedule(int sig, siginfo_t *siginf, ucontext_t* context1){
printf("\nIn schedule");
ucontext_t *ucp = NULL;
ucp = malloc(sizeof(ucontext_t));
getcontext(ucp);
//ucp = &sched->context;
sched->context = *context1;
if(sched->next != NULL){
sched = sched->next;
}
else{
sched = first;
}
setcontext(&sched->context);
}
I have a queue of ready threads in which their respective contexts are stored. Each thread should get scheduled whenever setcontext instruction is executed. However, scheduler() is not invoked! Can anyone please point out my mistake??
Completely revising this answer after looking at the code. There are a few issues:
There are several compiler warnings
You are never initializing your thread ID's, not outside or inside your thread creation method, so I'm surprised the code even works!
You are reading from uninitialized memory in your gtthread_create() function, I tested on both OSX & Linux, on OSX it crashes, on Linux by some miracle it's initialized.
In some places you call malloc(), and overwrite it with a pointer to something else - leaking memory
Your threads don't remove themselves from the linked list after they've finished, so weird things are happening after the routines finish.
When I add in the while(1) loop, I do see schedule() being called and output from thread 2, but thread 1 vanishes into fat air (probably because of the uninitialized thread ID). I think you need to have a huge code cleanup.
Here's what I'd suggest:
Fix ALL of your compiler warnings — even if you think they don't matter, the noise may lead to you missing things (such as incompatible pointer types, etc). You're compiling with -Wall & -pedantic; that's a good thing - so now take the next step & fix them.
Put \n at the END of your printf statements, not the start — The two threads ARE outputting to stdout, but it's not getting flushed so you can't see it. Change your printf("\nMessage"); calls to printf("Message\n");
Use Valgrind to detect memory issues — valgrind is the single most amazing tool you will ever use for C/C++ development. It's available through apt-get & yum. Instead of running ./test1, run valgrind ./test1 and it will highlight memory corruption, memory leaks, uninitialized reads, etc. I can't stress this enough; Valgrind is amazing.
If a system call returns a value, check it — in your code, check the return values to all of getcontext, swapcontext, sigaction, setitimer
Only call async-signal-safe methods from your scheduler (or any signal handler) — so far you've fixed malloc() and printf() from inside your scheduler. Check out the signal(7) man page - see "Async-signal-safe functions"
Modularize your code — your linked list implementation could be tidier, and if it was separated out, then 1) your scheduler would have less code & be simpler, and 2) you can isolate issues in your linked list without having to debug scheduler code.
You're almost there, so keep at it - but keep in mind these three simple rules:
Clean as you go
Keep the compiler warnings fixed
When weird things are happening, use valgrind
Good luck!
Old answer:
You should check the return value of any system call. Whether or not it helps you find the answer, you should do it anyway :)
Check the return value of sigaction(), if it's -1, check errno. sigaction() can fail for a few reasons. If your signal handler isn't getting fired, it's possible it hasn't been set up.
Edit: and make sure you check the return of setitimer() too!
Edit 2: Just a thought, can you try getting rid of the malloc()? malloc is not signal safe. eg: like this:
void schedule(int sig, siginfo_t *siginf, ucontext_t* context1){
printf("In schedule\n");
getcontext(&sched->context);
if(sched->next != NULL){
sched = sched->next;
}
else{
sched = first;
}
setcontext(&sched->context);
}
Edit 3: According to this discussion, you can't use printf() inside a signal handler. You can try replacing it with a call to write(), which is async-signal safe:
// printf("In schedule\n");
const char message[] = "In schedule\n";
write( 1, message, sizeof( message ) );
I have a function say void *WorkerThread ( void *ptr).
The function *WorkerThread( void *ptr) has infinite loop which reads and writes continously from Serial Port
example
void *WorkerThread( void *ptr)
{
while(1)
{
// READS AND WRITE from Serial Port USING MUXTEX_LOCK AND MUTEX_UNLOCK
} //while ends
}
The other function I worte is ThreadTest
example
int ThreadTest()
{
pthread_t Worker;
int iret1;
pthread_mutex_init(&stop_mutex, NULL);
if( iret1 = pthread_create(&Worker, NULL, WorkerThread, NULL) == 0)
{
pthread_mutex_lock(&stop_mutex);
stopThread = true;
pthread_mutex_unlock(&stop_mutex);
}
if (stopThread != false)
stopThread = false;
pthread_mutex_destroy(&stop_mutex);
return 0;
}
In main function
I have something like
int main(int argc, char **argv)
{
fd = OpenSerialPort();
if( ConfigurePort(fd) < 0) return 0;
while (true)
{
ThreadTest();
}
return 0;
}
Now, when I run this sort of code with debug statement it runs fine for few hours and then throw message like "can't able to create thread" and application terminates.
Does anyone have an idea where I am making mistakes.
Also if there is way to run ThreadTest in main with using while(true) as I am already using while(1) in ThreadWorker to read and write infinitely.
All comments and criticism are welcome.
Thanks & regards,
SamPrat.
You are creating threads continually and might be hitting the limit on number of threads.
Pthread_create man page says:
EAGAIN Insufficient resources to create another thread, or a system-imposed
limit on the number of threads was encountered. The latter case may
occur in two ways: the RLIMIT_NPROC soft resource limit (set via
setrlimit(2)), which limits the number of process for a real user ID,
was reached; or the kernel's system-wide limit on the number of
threads, /proc/sys/kernel/threads-max, was reached.
You should rethink of the design of your application. Creating an infinite number of threads is not a god design.
[UPDATE]
you are using lock to set an integer variable:
pthread_mutex_lock(&stop_mutex);
stopThread = true;
pthread_mutex_unlock(&stop_mutex);
However, this is not required as setting an int is atomic (on probably all architectures?). You should use a lock when you are doing not-atomic operations, eg: test and set
take_lock ();
if (a != 1)
a = 1
release_lock ();
You create a new thread each time ThreadTest is called, and never destroy these threads. So eventually you (or the OS) run out of thread handles (a limited resource).
Threads consume resources (memory & processing), and you're creating a thread each time your main loop calls ThreadTest(). And resources are finite, while your loop is not, so this will eventually throw a memory allocation error.
You should get rid of the main loop, and make ThreadTest return the newly created thread (pthread_t). Finally, make main wait for the thread termination using pthread_join.
Your pthreads are zombies and consume system resources. For Linux you can use ulimit -s to check your active upper limits -- but they are not infinite either. Use pthread_join() to let a thread finish and release the resources it consumed.
Do you know that select() is able to read from multiple (device) handles ? You can also define a user defined source to stop select(), or a timeout. With this in mind you are able to start one thread and let it sleeping if nothing occurs. If you intent to stop it, you can send a event (or timeout) to break the select() function call.
An additional design concept you have to consider is message queues to share information between your main application and/or pthread. select() is compatible with this technique so you can use one concept for data sources (devices and message queues).
Here a reference to a good pthread reading and the best pthread book available: Programming with POSIX(R) Threads, ISBN-13:978-0201633924
Looks like you've not called pthread_join() which cleans up state after non-detached threads are finished. I'd speculate that you've hit some per process resource limit here as a result.
As others have noted this is not great design though - why not re-use the thread rather than creating a new one on every loop?