I am creating a syscall to return some information about a process and its children threads. I am testing this in Ubuntu 14.04. Here is the code that I have written:
#include <linux/list.h>
#include <linux/linkage.h>
#include <linux/sched.h>
#include <linux/uaccess.h>
#define NUM_THREADS 5
struct thread_info_prj {
int pid;
int nthreads;
int tid[NUM_THREADS];
};
asmlinkage void sys_threadinfo_prj(void *ptr)
{
struct task_struct *task;
struct thread_info_prj t_info;
struct list_head *list;
int num_threads = 0;
t_info.pid = current->pid;
list_for_each(list, ¤t->children) {
//task = list_entry(&p_task->children, struct task_struct, sibling);
task = list_entry(list, struct task_struct, sibling);
t_info.tid[num_threads] = task->pid;
num_threads++;
}
t_info.nthreads = num_threads;
copy_to_user(ptr, &t_info, sizeof(struct thread_info_prj));
}
This code is built into the kernel as a syscall , and tested with the following program.
#include <pthread.h>
#include <stdio.h>
#include <sys/syscall.h>
#include <errno.h>
#define NUM_THREADS 5
struct thread_info_prj {
int pid;
int nthreads;
int tid[NUM_THREADS];
};
void * thread_fn(void *ptr) {
printf("Im a thread!\n");
sleep(4);
pthread_exit(NULL);
}
int main() {
pthread_t threads[NUM_THREADS];
pthread_attr_t attr;
int i;
struct thread_info_prj t_info;
void *status;
pthread_attr_init(&attr);
//pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
for (i = 0; i < NUM_THREADS; i++)
pthread_create(&(threads[i]), &attr, thread_fn, NULL);
sleep(1);
syscall(352, &t_info);
//for (i = 0; i < NUM_THREADS; i++)
// pthread_join(threads[i], &status);
printf("PID: %d\n", t_info.pid);
printf("Num Threads: %d\n", t_info.nthreads);
for (i = 0; i < t_info.nthreads; i++) {
printf("Thread ID: %d\n", t_info.tid[i]);
}
printf("%s\n",strerror(errno));
return 0;
}
Unfortunately, the only output is the proper parent pid. Otherwise, it returns that there are no threads and does not print any additional PIDs. By adding a printk inside the for loop, I discovered that it never even enters the for loop. Any suggestions?
Thanks so much.
Related
The program below creates two processes.
The parent process prints the numbers from 0 to 9, while the
child process prints the characters from A to J.
How can I make it alternate the printing using only signals? so no using semaphores or any IPCs.
#include <stdio.h>
int main()
{
int i = 0;
if (fork() == 0) /* Child process */
{
for (i = 0; i < 10; i++) {
printf("%c\n", i + 65);
}
} else /* Parent process */
{
for (i = 0; i < 10; i++) {
printf("%d\n", i);
}
}
}
I figured it out.
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <signal.h>
int main()
{
int i=0;
int status;
int childPID = fork();
if (childPID == 0) /* Child process */
{
for(i=0;i<10;i++){
printf("%c\n",i+65);
kill(getpid(), SIGSTOP);
}
} else /* Parent process */
{
for(i=0;i<10;i++) {
waitpid(childPID,&status,WUNTRACED);
printf("%d\n",i);
kill(childPID, SIGCONT);
}
}
}
I am trying to understand procfs for communication between userspace and kernel module. My module has basic two functions for procfs write_proc, driver_mmap.
I call multiple times write_proc by calling fputs("123456789",fd). where fd is file descriptor to procfs entry in /proc directory. But I don't see write_proc called multiple time. Code is attached by here.
<code>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/initval.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mm.h> /* mmap related stuff */
#define BUF_SIZE 64 * 1024
int *MmapBuffer;
int Factor = 1;
static int write_proc(struct file *filp, int *buf, size_t count, loff_t *offp)
{
int rc,i;
printk("in Write \n");
for (i = 1; i <= 16*1024 ; i++)
MmapBuffer[i-1] = (i+1)*Factor;
Factor++;
return count;
}
static int driver_mmap(struct file *file, struct vm_area_struct *vma)
{
int ret;
vma->vm_flags |= VM_LOCKED|VM_SHARED;
ret = remap_pfn_range(vma, vma->vm_start,
virt_to_phys(MmapBuffer) >> PAGE_SHIFT,
vma->vm_end-vma->vm_start, vma->vm_page_prot);
if(ret != 0)
printk("MMAP Failed \n");
SetPageReserved(virt_to_page(MmapBuffer));
printk("MMAP Succeeded \n");
return 0;
}
// file operations
struct file_operations proc_fops =
{
.write = write_proc,
.mmap = driver_mmap,
};
// init module
int init_module_test(void)
{
printk("<1>Hello world\n");
MmapBuffer = kzalloc(BUF_SIZE,__GFP_COLD|GFP_DMA);
if(MmapBuffer == NULL)
printk("Kzalloc failed. reduce buffer size \n");
proc_create ("Test_fs",0,NULL, &proc_fops);
return 0;
}
// exit module
void cleanup_module_test(void)
{
kfree(MmapBuffer);
remove_proc_entry ("Test_fs", NULL);
printk("Goodbye world\n");
}
module_init(init_module_test);
module_exit(cleanup_module_test);
MODULE_LICENSE("GPL");
</code>
Application code
<code>
#include<stdio.h>
#include<stdlib.h>
#include<sys/mman.h>
#include<errno.h>
#include <fcntl.h>
int main(void)
{
int fd;
int i,j;
int *msg ;
printf("Allocation started \n ");
msg=(int*)malloc(64*1024);
if(msg == NULL)
printf("Allocation failed \n");
//unsigned int *addr;
printf("Starting opening \n ");
if((fd=open("/proc/Test_fs", O_RDONLY ))<0)
{
printf("File not opened ");
}
printf("Starting mapping \n ");
msg = mmap(NULL, 64*1024, PROT_READ, MAP_SHARED , fd, 0);
printf("done from module \n ");
if(msg == MAP_FAILED)
{
printf("MAP failed and error is %s", strerror(errno));
return 0;
}
close(fd);
printf("Successful mapping");
FILE *f;
f=fopen("/proc/Test_fs", "wr");
if(!f)
{
printf("File not opened ");
}
for (j = 0; j < 10 ; j++)
{
if(fputs("1234567890,",f) <= 0)
printf("write failed, ");
for (i = 0; i < 16*1024 ; i++)
printf("%d, ", msg[i]);
printf("\n \n done \n \n ");
}
fclose(f);
return 0;
}
</code>
I have been struggling to find what I'm doing wrong and I can't seem to find the issue. When I compile the code below, I get an I/O error.
e.g: /usr/bin/sort: read failed: -: Input/output error
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv, char **envp)
{
int fd[2];
pid_t pid;
pipe(fd);
pid = fork();
if (pid == -1) {
exit(EXIT_FAILURE);
}
if (pid == 0) { /* child */
char *exe[]= { "/usr/bin/sort", NULL };
close(fd[0]);
execve("/usr/bin/sort", exe, envp);
}
else {
char *a[] = { "zilda", "andrew", "bartholomeu", NULL };
int i;
close(fd[1]);
for (i = 0; a[i]; i++)
printf("%s\n", a[i]);
}
return 0;
}
dup2(fd[0], 0) in the child.
dup2(fd[1], 1) in the parent.
close the other fd.
I am getting the same error multiple times when compiling the following pthreads program in linux using:
gcc -c -lpthread proj2_part1.c -lrt
#include <unistd.h>
#include <sys/types.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#define BUFFER_SIZE 10
#define TRUE 1
struct cQueue{
int *buffer;
int front, rear;
}*queue;
int count;
pthread_mutex_t mutex;
sem_t full, empty;
........
/*MAIN*/
int main(int argc,char* argv[])
{
int a=0, b=0, count =0, buff[BUFFER_SIZE];
int p = atoi(argv[1]), c = atoi(argv[2]);
unsigned int s = atoi(argv[0]);
pthread_t prothread[p], conthread[c];
/*Initialize Semaphores*/
if (sem_init(&full,0,0) == -1)
printf("%s\n",strerror(errno));
if (sem_init(&empty,0,BUFFER_SIZE) == -1)
printf("%s\n",strerror(errno));
pthread_mutex_init(&mutex, NULL);
/*Initialize Circular Queue*/
queue->buffer=buff;
queue->front = queue->buffer[0];
queue->rear = queue->buffer[0];
if(argc!=3)
{
fprintf(stderr,"Syntax: ./a.out <int> <int> <int>");
return -1;
}
if(s<0)
{
fprintf(stderr,"Argument %d must be positive value\n",s);
return -1;
}
else
{
/*Create producer threads*/
int i;
for (i=0; i<p; i++)
{
b = pthread_create(&prothread[i], NULL, producerThread, (void*)argv[1]);
if (b<0)
{
printf("Error: unable to create thread, %d\n",b);
return -1;
}
}
/*Create consumer threads*/
int j;
for (j=0; j<c; j++)
(
a = pthread_create(&conthread[j], NULL, consumerThread, (void*)argv[2]);
if (a<0)
{
printf("Error: unable to create thread, %d\n",a);
return -1;
}
}
sleep(atoi(argv[0]));
}
return 0;
}
I am receiving the following error. I think it has something to do with my semaphore declaration.
proj2_part1.c:147:81: error: expected â)â before â;â token
a = pthread_create(&conthread[j], NULL, consumerThread, (void*)argv[2]);
^
proj2_part1.c:153:6: error: expected â;â before â}â token}
^
proj2_part1.c: At top level:
proj2_part1.c:156:6: error: expected identifier or â(â before âreturnâ
return 0;
^
proj2_part1.c:157:1: error: expected identifier or â(â before â}â token
}
You've used a ( where you meant {:
for (j=0; j<c; j++)
(
I run the program on Ubuntu 12.04,
The counters' value is awalys 0.It seems that my counters didn't work for me.
When I run the program,the ouput is :
Get the number of CPU:8
Create counters for each CPU finished!
run_perf_stat()!
Cache miss in cpu1:0
Cache miss in cpu2:0
Cache miss in cpu3:0
Cache miss in cpu4:0
Cache miss in cpu5:0
Cache miss in cpu6:0
Cache miss in cpu7:0
Cache miss in cpu8:0
I can't make sense of the values'meaning.What I want to get is every cpu's cache reference and it's cache miss.But obviously the result seems not correct!
I have read the doc about the perf method at:
http://www.man7.org/linux/man-pages/man2/perf_event_open.2.html
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <asm-generic/unistd.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
#include "perf_event.h"
#define MAX_COUNTERS 256
static int fd[MAX_COUNTERS];
static unsigned int counter;
static unsigned int nr_cpus = 0; // amount of cpus
//open counter
long sys_perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
{
int ret;
ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
group_fd, flags);
return ret;
}
void run_perf_stat()
{
long long eventContents=0;
for (counter = 0; counter < nr_cpus; counter++){
if(fd[counter]!=-1){
read(fd[counter],&eventContents,sizeof(long long));
printf("Cache miss in cpu%d:%lld\n",counter+1,eventContents);
}
else{
fprintf(stderr, "Fail to read counter %d\n", counter);
}
}
}
int main(int argc, const char **argv){
DIR *dir; //access to dir
struct dirent *drp;
int run_count, p, pid;
struct timespec tim, tim2;
tim.tv_sec = 1; tim.tv_nsec = 0;
nr_cpus = sysconf(_SC_NPROCESSORS_ONLN);// the number of CPU
printf("Get the number of CPU:%d\n",nr_cpus);
//create counters for each CPU (system-wide)
struct perf_event_attr attr; //cache miss
memset(&attr, 0, sizeof(struct perf_event_attr));
attr.type = PERF_TYPE_HARDWARE;
attr.config = PERF_COUNT_HW_CACHE_MISSES;
attr.size = sizeof(struct perf_event_attr);
attr.disabled = 0;
attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
PERF_FORMAT_TOTAL_TIME_RUNNING;
unsigned int cpu = 0;
for(cpu = 0; cpu < nr_cpus; cpu++)
fd[cpu] = sys_perf_event_open(&attr, -1, cpu, -1, 0);
printf("Create counters for each CPU finished!\n");
//get perf report
while (1) {
nanosleep(&tim , &tim2);
printf("run_perf_stat()!\n");
run_perf_stat();
}
return 1;
}
And I also run the example given at http://www.man7.org/linux/man-pages/man2/perf_event_open.2.html
But,unfortunaely,The result is always 0,too.Here comes the example in the man-page.
The following is a short example that measures the total instruction count of a call to printf(3).
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/ioctl.h>
#include <linux/perf_event.h>
#include <asm/unistd.h>
long
perf_event_open(struct perf_event_attr *hw_event, pid_t pid,
int cpu, int group_fd, unsigned long flags)
{
int ret;
ret = syscall(__NR_perf_event_open, hw_event, pid, cpu,
group_fd, flags);
return ret;
}
int
main(int argc, char **argv)
{
struct perf_event_attr pe;
long long count;
int fd;
memset(&pe, 0, sizeof(struct perf_event_attr));
pe.type = PERF_TYPE_HARDWARE;
pe.size = sizeof(struct perf_event_attr);
pe.config = PERF_COUNT_HW_INSTRUCTIONS;
pe.disabled = 1;
pe.exclude_kernel = 1;
pe.exclude_hv = 1;
fd = perf_event_open(&pe, 0, -1, -1, 0);
if (fd == -1) {
fprintf(stderr, "Error opening leader %llx\n", pe.config);
exit(EXIT_FAILURE);
}
ioctl(fd, PERF_EVENT_IOC_RESET, 0);
ioctl(fd, PERF_EVENT_IOC_ENABLE, 0);
printf("Measuring instruction count for this printf\n");
ioctl(fd, PERF_EVENT_IOC_DISABLE, 0);
read(fd, &count, sizeof(long long));
printf("Used %lld instructions\n", count);
close(fd);
}
I just tried your code and removing following lines (line no 75,76) makes the code work for me.
attr.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED |
PERF_FORMAT_TOTAL_TIME_RUNNING;