add exercise lab0_ex4
This commit is contained in:
parent
9fe50a3377
commit
d41b9e7f4f
68
related_info/lab0/defs.h
Normal file
68
related_info/lab0/defs.h
Normal file
@ -0,0 +1,68 @@
|
||||
#ifndef __LIBS_DEFS_H__
|
||||
#define __LIBS_DEFS_H__
|
||||
|
||||
#ifndef NULL
|
||||
#define NULL ((void *)0)
|
||||
#endif
|
||||
|
||||
//#define __always_inline inline __attribute__((always_inline))
|
||||
#define __noinline __attribute__((noinline))
|
||||
#define __noreturn __attribute__((noreturn))
|
||||
|
||||
/* Represents true-or-false values */
|
||||
typedef int bool;
|
||||
|
||||
/* Explicitly-sized versions of integer types */
|
||||
//typedef char int8_t;
|
||||
typedef unsigned char uint8_t;
|
||||
typedef short int16_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef int int32_t;
|
||||
typedef unsigned int uint32_t;
|
||||
typedef long long int64_t;
|
||||
typedef unsigned long long uint64_t;
|
||||
|
||||
/* *
|
||||
* Pointers and addresses are 32 bits long.
|
||||
* We use pointer types to represent addresses,
|
||||
* uintptr_t to represent the numerical values of addresses.
|
||||
* */
|
||||
typedef int32_t intptr_t;
|
||||
typedef uint32_t uintptr_t;
|
||||
|
||||
/* size_t is used for memory object sizes */
|
||||
typedef uintptr_t size_t;
|
||||
|
||||
/* used for page numbers */
|
||||
typedef size_t ppn_t;
|
||||
|
||||
/* *
|
||||
* Rounding operations (efficient when n is a power of 2)
|
||||
* Round down to the nearest multiple of n
|
||||
* */
|
||||
#define ROUNDDOWN(a, n) ({ \
|
||||
size_t __a = (size_t)(a); \
|
||||
(typeof(a))(__a - __a % (n)); \
|
||||
})
|
||||
|
||||
/* Round up to the nearest multiple of n */
|
||||
#define ROUNDUP(a, n) ({ \
|
||||
size_t __n = (size_t)(n); \
|
||||
(typeof(a))(ROUNDDOWN((size_t)(a) + __n - 1, __n)); \
|
||||
})
|
||||
|
||||
/* Return the offset of 'member' relative to the beginning of a struct type */
|
||||
#define offsetof(type, member) \
|
||||
((size_t)(&((type *)0)->member))
|
||||
|
||||
/* *
|
||||
* to_struct - get the struct from a ptr
|
||||
* @ptr: a struct pointer of member
|
||||
* @type: the type of the struct this is embedded in
|
||||
* @member: the name of the member within the struct
|
||||
* */
|
||||
#define to_struct(ptr, type, member) \
|
||||
((type *)((char *)(ptr) - offsetof(type, member)))
|
||||
|
||||
#endif /* !__LIBS_DEFS_H__ */
|
||||
|
27
related_info/lab0/lab0_ex4.c
Normal file
27
related_info/lab0/lab0_ex4.c
Normal file
@ -0,0 +1,27 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "list.h"
|
||||
|
||||
struct entry {
|
||||
|
||||
list_entry_t node;
|
||||
int num;
|
||||
};
|
||||
|
||||
int main() {
|
||||
struct entry head;
|
||||
list_entry_t* p = &head.node;
|
||||
list_init(p);
|
||||
head.num = 0;
|
||||
int i;
|
||||
for (i = 1; i != 10; i ++) {
|
||||
struct entry * e = (struct entry *)malloc(sizeof(struct entry));
|
||||
e->num = i;
|
||||
list_add(p, &(e->node));
|
||||
p = list_next(p);
|
||||
}
|
||||
//reverse list all node
|
||||
while ((p = list_prev(p)) != &head.node)
|
||||
printf("%d\n", ((struct entry *)p)->num);
|
||||
return 0;
|
||||
}
|
12
related_info/lab0/lab0_ex4.md
Normal file
12
related_info/lab0/lab0_ex4.md
Normal file
@ -0,0 +1,12 @@
|
||||
#README
|
||||
Try below command
|
||||
```
|
||||
gcc -g -m32 -I. lab0_ex4.c 2>&1|tee make.log
|
||||
```
|
||||
If you get gcc's error, try to read make.log and fix the bugs.
|
||||
|
||||
If gcc successed, then you will get a.out.
|
||||
|
||||
Try to answer below question.
|
||||
|
||||
|
163
related_info/lab0/list.h
Normal file
163
related_info/lab0/list.h
Normal file
@ -0,0 +1,163 @@
|
||||
#ifndef __LIBS_LIST_H__
|
||||
#define __LIBS_LIST_H__
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
|
||||
#include <defs.h>
|
||||
|
||||
/* *
|
||||
* Simple doubly linked list implementation.
|
||||
*
|
||||
* Some of the internal functions ("__xxx") are useful when manipulating
|
||||
* whole lists rather than single entries, as sometimes we already know
|
||||
* the next/prev entries and we can generate better code by using them
|
||||
* directly rather than using the generic single-entry routines.
|
||||
* */
|
||||
|
||||
struct list_entry {
|
||||
struct list_entry *prev, *next;
|
||||
};
|
||||
|
||||
typedef struct list_entry list_entry_t;
|
||||
|
||||
static inline void list_init(list_entry_t *elm) __attribute__((always_inline));
|
||||
static inline void list_add(list_entry_t *listelm, list_entry_t *elm) __attribute__((always_inline));
|
||||
static inline void list_add_before(list_entry_t *listelm, list_entry_t *elm) __attribute__((always_inline));
|
||||
static inline void list_add_after(list_entry_t *listelm, list_entry_t *elm) __attribute__((always_inline));
|
||||
static inline void list_del(list_entry_t *listelm) __attribute__((always_inline));
|
||||
static inline void list_del_init(list_entry_t *listelm) __attribute__((always_inline));
|
||||
static inline bool list_empty(list_entry_t *list) __attribute__((always_inline));
|
||||
static inline list_entry_t *list_next(list_entry_t *listelm) __attribute__((always_inline));
|
||||
static inline list_entry_t *list_prev(list_entry_t *listelm) __attribute__((always_inline));
|
||||
|
||||
static inline void __list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) __attribute__((always_inline));
|
||||
static inline void __list_del(list_entry_t *prev, list_entry_t *next) __attribute__((always_inline));
|
||||
|
||||
/* *
|
||||
* list_init - initialize a new entry
|
||||
* @elm: new entry to be initialized
|
||||
* */
|
||||
static inline void
|
||||
list_init(list_entry_t *elm) {
|
||||
elm->prev = elm->next = elm;
|
||||
}
|
||||
|
||||
/* *
|
||||
* list_add - add a new entry
|
||||
* @listelm: list head to add after
|
||||
* @elm: new entry to be added
|
||||
*
|
||||
* Insert the new element @elm *after* the element @listelm which
|
||||
* is already in the list.
|
||||
* */
|
||||
static inline void
|
||||
list_add(list_entry_t *listelm, list_entry_t *elm) {
|
||||
list_add_after(listelm, elm);
|
||||
}
|
||||
|
||||
/* *
|
||||
* list_add_before - add a new entry
|
||||
* @listelm: list head to add before
|
||||
* @elm: new entry to be added
|
||||
*
|
||||
* Insert the new element @elm *before* the element @listelm which
|
||||
* is already in the list.
|
||||
* */
|
||||
static inline void
|
||||
list_add_before(list_entry_t *listelm, list_entry_t *elm) {
|
||||
__list_add(elm, listelm->prev, listelm);
|
||||
}
|
||||
|
||||
/* *
|
||||
* list_add_after - add a new entry
|
||||
* @listelm: list head to add after
|
||||
* @elm: new entry to be added
|
||||
*
|
||||
* Insert the new element @elm *after* the element @listelm which
|
||||
* is already in the list.
|
||||
* */
|
||||
static inline void
|
||||
list_add_after(list_entry_t *listelm, list_entry_t *elm) {
|
||||
__list_add(elm, listelm, listelm->next);
|
||||
}
|
||||
|
||||
/* *
|
||||
* list_del - deletes entry from list
|
||||
* @listelm: the element to delete from the list
|
||||
*
|
||||
* Note: list_empty() on @listelm does not return true after this, the entry is
|
||||
* in an undefined state.
|
||||
* */
|
||||
static inline void
|
||||
list_del(list_entry_t *listelm) {
|
||||
__list_del(listelm->prev, listelm->next);
|
||||
}
|
||||
|
||||
/* *
|
||||
* list_del_init - deletes entry from list and reinitialize it.
|
||||
* @listelm: the element to delete from the list.
|
||||
*
|
||||
* Note: list_empty() on @listelm returns true after this.
|
||||
* */
|
||||
static inline void
|
||||
list_del_init(list_entry_t *listelm) {
|
||||
list_del(listelm);
|
||||
list_init(listelm);
|
||||
}
|
||||
|
||||
/* *
|
||||
* list_empty - tests whether a list is empty
|
||||
* @list: the list to test.
|
||||
* */
|
||||
static inline bool
|
||||
list_empty(list_entry_t *list) {
|
||||
return list->next == list;
|
||||
}
|
||||
|
||||
/* *
|
||||
* list_next - get the next entry
|
||||
* @listelm: the list head
|
||||
**/
|
||||
static inline list_entry_t *
|
||||
list_next(list_entry_t *listelm) {
|
||||
return listelm->next;
|
||||
}
|
||||
|
||||
/* *
|
||||
* list_prev - get the previous entry
|
||||
* @listelm: the list head
|
||||
**/
|
||||
static inline list_entry_t *
|
||||
list_prev(list_entry_t *listelm) {
|
||||
return listelm->prev;
|
||||
}
|
||||
|
||||
/* *
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
* */
|
||||
static inline void
|
||||
__list_add(list_entry_t *elm, list_entry_t *prev, list_entry_t *next) {
|
||||
prev->next = next->prev = elm;
|
||||
elm->next = next;
|
||||
elm->prev = prev;
|
||||
}
|
||||
|
||||
/* *
|
||||
* Delete a list entry by making the prev/next entries point to each other.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
* */
|
||||
static inline void
|
||||
__list_del(list_entry_t *prev, list_entry_t *next) {
|
||||
prev->next = next;
|
||||
next->prev = prev;
|
||||
}
|
||||
|
||||
#endif /* !__ASSEMBLER__ */
|
||||
|
||||
#endif /* !__LIBS_LIST_H__ */
|
||||
|
Loading…
Reference in New Issue
Block a user